Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
stm32l4xx_hal_usart.c
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_hal_usart.c 00004 * @author MCD Application Team 00005 * @version V1.5.1 00006 * @date 31-May-2016 00007 * @brief USART HAL module driver. 00008 * This file provides firmware functions to manage the following 00009 * functionalities of the Universal Synchronous/Asynchronous Receiver Transmitter 00010 * Peripheral (USART). 00011 * + Initialization and de-initialization functions 00012 * + IO operation functions 00013 * + Peripheral Control functions 00014 * + Peripheral State and Error functions 00015 * 00016 @verbatim 00017 =============================================================================== 00018 ##### How to use this driver ##### 00019 =============================================================================== 00020 [..] 00021 The USART HAL driver can be used as follows: 00022 00023 (#) Declare a USART_HandleTypeDef handle structure (eg. USART_HandleTypeDef husart). 00024 (#) Initialize the USART low level resources by implementing the HAL_USART_MspInit() API: 00025 (++) Enable the USARTx interface clock. 00026 (++) USART pins configuration: 00027 (+++) Enable the clock for the USART GPIOs. 00028 (+++) Configure these USART pins as alternate function pull-up. 00029 (++) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(), 00030 HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs): 00031 (+++) Configure the USARTx interrupt priority. 00032 (+++) Enable the NVIC USART IRQ handle. 00033 (++) USART interrupts handling: 00034 -@@- The specific USART interrupts (Transmission complete interrupt, 00035 RXNE interrupt and Error Interrupts) will be managed using the macros 00036 __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process. 00037 (++) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA() 00038 HAL_USART_Receive_DMA() and HAL_USART_TransmitReceive_DMA() APIs): 00039 (+++) Declare a DMA handle structure for the Tx/Rx channel. 00040 (+++) Enable the DMAx interface clock. 00041 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. 00042 (+++) Configure the DMA Tx/Rx channel. 00043 (+++) Associate the initialized DMA handle to the USART DMA Tx/Rx handle. 00044 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel. 00045 00046 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware 00047 flow control and Mode (Receiver/Transmitter) in the husart handle Init structure. 00048 00049 (#) Initialize the USART registers by calling the HAL_USART_Init() API: 00050 (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) 00051 by calling the customized HAL_USART_MspInit(&husart) API. 00052 00053 [..] 00054 (@) To configure and enable/disable the USART to wake up the MCU from stop mode, resort to UART API's 00055 HAL_UARTEx_StopModeWakeUpSourceConfig(), HAL_UARTEx_EnableStopMode() and 00056 HAL_UARTEx_DisableStopMode() in casting the USART handle to UART type UART_HandleTypeDef. 00057 00058 @endverbatim 00059 ****************************************************************************** 00060 * @attention 00061 * 00062 * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2> 00063 * 00064 * Redistribution and use in source and binary forms, with or without modification, 00065 * are permitted provided that the following conditions are met: 00066 * 1. Redistributions of source code must retain the above copyright notice, 00067 * this list of conditions and the following disclaimer. 00068 * 2. Redistributions in binary form must reproduce the above copyright notice, 00069 * this list of conditions and the following disclaimer in the documentation 00070 * and/or other materials provided with the distribution. 00071 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00072 * may be used to endorse or promote products derived from this software 00073 * without specific prior written permission. 00074 * 00075 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00076 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00077 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00078 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00079 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00080 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00081 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00082 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00083 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00084 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00085 * 00086 ****************************************************************************** 00087 */ 00088 00089 /* Includes ------------------------------------------------------------------*/ 00090 #include "stm32l4xx_hal.h" 00091 00092 /** @addtogroup STM32L4xx_HAL_Driver 00093 * @{ 00094 */ 00095 00096 /** @defgroup USART USART 00097 * @brief HAL USART Synchronous module driver 00098 * @{ 00099 */ 00100 00101 #ifdef HAL_USART_MODULE_ENABLED 00102 00103 /* Private typedef -----------------------------------------------------------*/ 00104 /* Private define ------------------------------------------------------------*/ 00105 /** @defgroup USART_Private_Constants USART Private Constants 00106 * @{ 00107 */ 00108 #define USART_DUMMY_DATA ((uint16_t) 0xFFFF) /*!< USART transmitted dummy data */ 00109 #define USART_TEACK_REACK_TIMEOUT ((uint32_t) 1000) /*!< USART TX or RX enable acknowledge time-out value */ 00110 #define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \ 00111 USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8)) /*!< USART CR1 fields of parameters set by USART_SetConfig API */ 00112 #define USART_CR2_FIELDS ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | \ 00113 USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP)) /*!< USART CR2 fields of parameters set by USART_SetConfig API */ 00114 /** 00115 * @} 00116 */ 00117 00118 /* Private macros ------------------------------------------------------------*/ 00119 /* Private variables ---------------------------------------------------------*/ 00120 /* Private function prototypes -----------------------------------------------*/ 00121 /** @addtogroup USART_Private_Functions 00122 * @{ 00123 */ 00124 static void USART_EndTransfer(USART_HandleTypeDef *husart); 00125 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma); 00126 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma); 00127 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma); 00128 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma); 00129 static void USART_DMAError(DMA_HandleTypeDef *hdma); 00130 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout); 00131 static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart); 00132 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart); 00133 static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma); 00134 static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart); 00135 static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart); 00136 static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart); 00137 static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart); 00138 /** 00139 * @} 00140 */ 00141 00142 /* Exported functions --------------------------------------------------------*/ 00143 00144 /** @defgroup USART_Exported_Functions USART Exported Functions 00145 * @{ 00146 */ 00147 00148 /** @defgroup USART_Exported_Functions_Group1 Initialization and de-initialization functions 00149 * @brief Initialization and Configuration functions 00150 * 00151 @verbatim 00152 =============================================================================== 00153 ##### Initialization and Configuration functions ##### 00154 =============================================================================== 00155 [..] 00156 This subsection provides a set of functions allowing to initialize the USART 00157 in asynchronous and in synchronous modes. 00158 (+) For the asynchronous mode only these parameters can be configured: 00159 (++) Baud Rate 00160 (++) Word Length 00161 (++) Stop Bit 00162 (++) Parity: If the parity is enabled, then the MSB bit of the data written 00163 in the data register is transmitted but is changed by the parity bit. 00164 (++) USART polarity 00165 (++) USART phase 00166 (++) USART LastBit 00167 (++) Receiver/transmitter modes 00168 00169 [..] 00170 The HAL_USART_Init() function follows the USART synchronous configuration 00171 procedure (details for the procedure are available in reference manual). 00172 00173 @endverbatim 00174 00175 Depending on the frame length defined by the M1 and M0 bits (7-bit, 00176 8-bit or 9-bit), the possible USART formats are listed in the 00177 following table. 00178 00179 Table 1. USART frame format. 00180 +-----------------------------------------------------------------------+ 00181 | M1 bit | M0 bit | PCE bit | USART frame | 00182 |---------|---------|-----------|---------------------------------------| 00183 | 0 | 0 | 0 | | SB | 8 bit data | STB | | 00184 |---------|---------|-----------|---------------------------------------| 00185 | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | 00186 |---------|---------|-----------|---------------------------------------| 00187 | 0 | 1 | 0 | | SB | 9 bit data | STB | | 00188 |---------|---------|-----------|---------------------------------------| 00189 | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | 00190 |---------|---------|-----------|---------------------------------------| 00191 | 1 | 0 | 0 | | SB | 7 bit data | STB | | 00192 |---------|---------|-----------|---------------------------------------| 00193 | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | 00194 +-----------------------------------------------------------------------+ 00195 00196 * @{ 00197 */ 00198 00199 /** 00200 * @brief Initializes the USART mode according to the specified 00201 * parameters in the USART_InitTypeDef and initialize the associated handle. 00202 * @param husart: USART handle. 00203 * @retval HAL status 00204 */ 00205 HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart) 00206 { 00207 /* Check the USART handle allocation */ 00208 if(husart == NULL) 00209 { 00210 return HAL_ERROR; 00211 } 00212 00213 /* Check the parameters */ 00214 assert_param(IS_USART_INSTANCE(husart->Instance)); 00215 00216 if(husart->State == HAL_USART_STATE_RESET) 00217 { 00218 /* Allocate lock resource and initialize it */ 00219 husart->Lock = HAL_UNLOCKED; 00220 00221 /* Init the low level hardware : GPIO, CLOCK */ 00222 HAL_USART_MspInit(husart); 00223 } 00224 00225 husart->State = HAL_USART_STATE_BUSY; 00226 00227 /* Disable the Peripheral */ 00228 __HAL_USART_DISABLE(husart); 00229 00230 /* Set the Usart Communication parameters */ 00231 if (USART_SetConfig(husart) == HAL_ERROR) 00232 { 00233 return HAL_ERROR; 00234 } 00235 00236 /* In Synchronous mode, the following bits must be kept cleared: 00237 - LINEN bit in the USART_CR2 register 00238 - HDSEL, SCEN and IREN bits in the USART_CR3 register.*/ 00239 husart->Instance->CR2 &= ~USART_CR2_LINEN; 00240 husart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN); 00241 00242 /* Enable the Peripheral */ 00243 __HAL_USART_ENABLE(husart); 00244 00245 /* TEACK and/or REACK to check before moving husart->State to Ready */ 00246 return (USART_CheckIdleState(husart)); 00247 } 00248 00249 /** 00250 * @brief DeInitialize the USART peripheral. 00251 * @param husart: USART handle. 00252 * @retval HAL status 00253 */ 00254 HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart) 00255 { 00256 /* Check the USART handle allocation */ 00257 if(husart == NULL) 00258 { 00259 return HAL_ERROR; 00260 } 00261 00262 /* Check the parameters */ 00263 assert_param(IS_USART_INSTANCE(husart->Instance)); 00264 00265 husart->State = HAL_USART_STATE_BUSY; 00266 00267 husart->Instance->CR1 = 0x0; 00268 husart->Instance->CR2 = 0x0; 00269 husart->Instance->CR3 = 0x0; 00270 00271 /* DeInit the low level hardware */ 00272 HAL_USART_MspDeInit(husart); 00273 00274 husart->ErrorCode = HAL_USART_ERROR_NONE; 00275 husart->State = HAL_USART_STATE_RESET; 00276 00277 /* Process Unlock */ 00278 __HAL_UNLOCK(husart); 00279 00280 return HAL_OK; 00281 } 00282 00283 /** 00284 * @brief Initialize the USART MSP. 00285 * @param husart: USART handle. 00286 * @retval None 00287 */ 00288 __weak void HAL_USART_MspInit(USART_HandleTypeDef *husart) 00289 { 00290 /* Prevent unused argument(s) compilation warning */ 00291 UNUSED(husart); 00292 00293 /* NOTE : This function should not be modified, when the callback is needed, 00294 the HAL_USART_MspInit can be implemented in the user file 00295 */ 00296 } 00297 00298 /** 00299 * @brief DeInitialize the USART MSP. 00300 * @param husart: USART handle. 00301 * @retval None 00302 */ 00303 __weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart) 00304 { 00305 /* Prevent unused argument(s) compilation warning */ 00306 UNUSED(husart); 00307 00308 /* NOTE : This function should not be modified, when the callback is needed, 00309 the HAL_USART_MspDeInit can be implemented in the user file 00310 */ 00311 } 00312 00313 /** 00314 * @} 00315 */ 00316 00317 /** @defgroup USART_Exported_Functions_Group2 IO operation functions 00318 * @brief USART Transmit and Receive functions 00319 * 00320 @verbatim 00321 =============================================================================== 00322 ##### IO operation functions ##### 00323 =============================================================================== 00324 [..] This subsection provides a set of functions allowing to manage the USART synchronous 00325 data transfers. 00326 00327 [..] The USART supports master mode only: it cannot receive or send data related to an input 00328 clock (SCLK is always an output). 00329 00330 (#) There are two modes of transfer: 00331 (++) Blocking mode: The communication is performed in polling mode. 00332 The HAL status of all data processing is returned by the same function 00333 after finishing transfer. 00334 (++) No-Blocking mode: The communication is performed using Interrupts 00335 or DMA, These API's return the HAL status. 00336 The end of the data processing will be indicated through the 00337 dedicated USART IRQ when using Interrupt mode or the DMA IRQ when 00338 using DMA mode. 00339 The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() user callbacks 00340 will be executed respectively at the end of the transmit or Receive process 00341 The HAL_USART_ErrorCallback()user callback will be executed when a communication error is detected 00342 00343 (#) Blocking mode API's are : 00344 (++) HAL_USART_Transmit()in simplex mode 00345 (++) HAL_USART_Receive() in full duplex receive only 00346 (++) HAL_USART_TransmitReceive() in full duplex mode 00347 00348 (#) Non-Blocking mode API's with Interrupt are : 00349 (++) HAL_USART_Transmit_IT()in simplex mode 00350 (++) HAL_USART_Receive_IT() in full duplex receive only 00351 (++) HAL_USART_TransmitReceive_IT()in full duplex mode 00352 (++) HAL_USART_IRQHandler() 00353 00354 (#) No-Blocking mode API's with DMA are : 00355 (++) HAL_USART_Transmit_DMA()in simplex mode 00356 (++) HAL_USART_Receive_DMA() in full duplex receive only 00357 (++) HAL_USART_TransmitReceive_DMA() in full duplex mode 00358 (++) HAL_USART_DMAPause() 00359 (++) HAL_USART_DMAResume() 00360 (++) HAL_USART_DMAStop() 00361 00362 (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode: 00363 (++) HAL_USART_TxCpltCallback() 00364 (++) HAL_USART_RxCpltCallback() 00365 (++) HAL_USART_TxHalfCpltCallback() 00366 (++) HAL_USART_RxHalfCpltCallback() 00367 (++) HAL_USART_ErrorCallback() 00368 (++) HAL_USART_TxRxCpltCallback() 00369 00370 (#) In Non-Blocking mode transfers, possible errors are split into 2 categories. 00371 Errors are handled as follows : 00372 (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is 00373 to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception . 00374 Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type, 00375 and HAL_USART_ErrorCallback() user callback is executed. Transfer is kept ongoing on USART side. 00376 (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted. 00377 This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode. 00378 Error code is set to allow user to identify error type, and HAL_USART_ErrorCallback() user callback is executed. 00379 00380 @endverbatim 00381 * @{ 00382 */ 00383 00384 /** 00385 * @brief Simplex send an amount of data in blocking mode. 00386 * @param husart USART handle. 00387 * @param pTxData Pointer to data buffer. 00388 * @param Size Amount of data to be sent. 00389 * @param Timeout Timeout duration. 00390 * @retval HAL status 00391 */ 00392 HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout) 00393 { 00394 uint16_t* tmp; 00395 uint32_t tickstart = 0; 00396 00397 if(husart->State == HAL_USART_STATE_READY) 00398 { 00399 if((pTxData == NULL) || (Size == 0)) 00400 { 00401 return HAL_ERROR; 00402 } 00403 00404 /* Process Locked */ 00405 __HAL_LOCK(husart); 00406 00407 husart->ErrorCode = HAL_USART_ERROR_NONE; 00408 husart->State = HAL_USART_STATE_BUSY_TX; 00409 00410 /* Init tickstart for timeout managment*/ 00411 tickstart = HAL_GetTick(); 00412 00413 husart->TxXferSize = Size; 00414 husart->TxXferCount = Size; 00415 00416 /* Check the remaining data to be sent */ 00417 while(husart->TxXferCount > 0) 00418 { 00419 husart->TxXferCount--; 00420 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) 00421 { 00422 return HAL_TIMEOUT; 00423 } 00424 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) 00425 { 00426 tmp = (uint16_t*) pTxData; 00427 husart->Instance->TDR = (*tmp & (uint16_t)0x01FF); 00428 pTxData += 2; 00429 } 00430 else 00431 { 00432 husart->Instance->TDR = (*pTxData++ & (uint8_t)0xFF); 00433 } 00434 } 00435 00436 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) 00437 { 00438 return HAL_TIMEOUT; 00439 } 00440 00441 /* At end of Tx process, restore husart->State to Ready */ 00442 husart->State = HAL_USART_STATE_READY; 00443 00444 /* Process Unlocked */ 00445 __HAL_UNLOCK(husart); 00446 00447 return HAL_OK; 00448 } 00449 else 00450 { 00451 return HAL_BUSY; 00452 } 00453 } 00454 00455 /** 00456 * @brief Receive an amount of data in blocking mode. 00457 * @note To receive synchronous data, dummy data are simultaneously transmitted. 00458 * @param husart USART handle. 00459 * @param pRxData Pointer to data buffer. 00460 * @param Size Amount of data to be received. 00461 * @param Timeout Timeout duration. 00462 * @retval HAL status 00463 */ 00464 HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout) 00465 { 00466 uint16_t* tmp; 00467 uint16_t uhMask; 00468 uint32_t tickstart = 0; 00469 00470 if(husart->State == HAL_USART_STATE_READY) 00471 { 00472 if((pRxData == NULL) || (Size == 0)) 00473 { 00474 return HAL_ERROR; 00475 } 00476 00477 /* Process Locked */ 00478 __HAL_LOCK(husart); 00479 00480 husart->ErrorCode = HAL_USART_ERROR_NONE; 00481 husart->State = HAL_USART_STATE_BUSY_RX; 00482 00483 /* Init tickstart for timeout managment*/ 00484 tickstart = HAL_GetTick(); 00485 00486 husart->RxXferSize = Size; 00487 husart->RxXferCount = Size; 00488 00489 /* Computation of USART mask to apply to RDR register */ 00490 USART_MASK_COMPUTATION(husart); 00491 uhMask = husart->Mask; 00492 00493 /* as long as data have to be received */ 00494 while(husart->RxXferCount > 0) 00495 { 00496 husart->RxXferCount--; 00497 00498 /* Wait until TC flag is set to send dummy byte in order to generate the 00499 * clock for the slave to send data. 00500 * Whatever the frame length (7, 8 or 9-bit long), the same dummy value 00501 * can be written for all the cases. */ 00502 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) 00503 { 00504 return HAL_TIMEOUT; 00505 } 00506 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x0FF); 00507 00508 /* Wait for RXNE Flag */ 00509 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) 00510 { 00511 return HAL_TIMEOUT; 00512 } 00513 00514 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) 00515 { 00516 tmp = (uint16_t*) pRxData ; 00517 *tmp = (uint16_t)(husart->Instance->RDR & uhMask); 00518 pRxData +=2; 00519 } 00520 else 00521 { 00522 *pRxData++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask); 00523 } 00524 } 00525 00526 /* At end of Rx process, restore husart->State to Ready */ 00527 husart->State = HAL_USART_STATE_READY; 00528 00529 /* Process Unlocked */ 00530 __HAL_UNLOCK(husart); 00531 00532 return HAL_OK; 00533 } 00534 else 00535 { 00536 return HAL_BUSY; 00537 } 00538 } 00539 00540 /** 00541 * @brief Full-Duplex Send and Receive an amount of data in blocking mode. 00542 * @param husart USART handle. 00543 * @param pTxData pointer to TX data buffer. 00544 * @param pRxData pointer to RX data buffer. 00545 * @param Size amount of data to be sent (same amount to be received). 00546 * @param Timeout Timeout duration. 00547 * @retval HAL status 00548 */ 00549 HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout) 00550 { 00551 uint16_t* tmp; 00552 uint16_t uhMask; 00553 uint32_t tickstart = 0; 00554 00555 if(husart->State == HAL_USART_STATE_READY) 00556 { 00557 if((pTxData == NULL) || (pRxData == NULL) || (Size == 0)) 00558 { 00559 return HAL_ERROR; 00560 } 00561 /* Process Locked */ 00562 __HAL_LOCK(husart); 00563 00564 husart->ErrorCode = HAL_USART_ERROR_NONE; 00565 husart->State = HAL_USART_STATE_BUSY_RX; 00566 00567 /* Init tickstart for timeout managment*/ 00568 tickstart = HAL_GetTick(); 00569 00570 husart->RxXferSize = Size; 00571 husart->TxXferSize = Size; 00572 husart->TxXferCount = Size; 00573 husart->RxXferCount = Size; 00574 00575 /* Computation of USART mask to apply to RDR register */ 00576 USART_MASK_COMPUTATION(husart); 00577 uhMask = husart->Mask; 00578 00579 /* Check the remain data to be sent */ 00580 while(husart->TxXferCount > 0) 00581 { 00582 husart->TxXferCount--; 00583 husart->RxXferCount--; 00584 00585 /* Wait until TC flag is set to send data */ 00586 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) 00587 { 00588 return HAL_TIMEOUT; 00589 } 00590 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) 00591 { 00592 tmp = (uint16_t*) pTxData; 00593 husart->Instance->TDR = (*tmp & uhMask); 00594 pTxData += 2; 00595 } 00596 else 00597 { 00598 husart->Instance->TDR = (*pTxData++ & (uint8_t)uhMask); 00599 } 00600 00601 /* Wait for RXNE Flag */ 00602 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) 00603 { 00604 return HAL_TIMEOUT; 00605 } 00606 00607 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) 00608 { 00609 tmp = (uint16_t*) pRxData ; 00610 *tmp = (uint16_t)(husart->Instance->RDR & uhMask); 00611 pRxData +=2; 00612 } 00613 else 00614 { 00615 *pRxData++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask); 00616 } 00617 } 00618 00619 /* At end of TxRx process, restore husart->State to Ready */ 00620 husart->State = HAL_USART_STATE_READY; 00621 00622 /* Process Unlocked */ 00623 __HAL_UNLOCK(husart); 00624 00625 return HAL_OK; 00626 } 00627 else 00628 { 00629 return HAL_BUSY; 00630 } 00631 } 00632 00633 /** 00634 * @brief Send an amount of data in interrupt mode. 00635 * @param husart USART handle. 00636 * @param pTxData pointer to data buffer. 00637 * @param Size amount of data to be sent. 00638 * @retval HAL status 00639 */ 00640 HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size) 00641 { 00642 if(husart->State == HAL_USART_STATE_READY) 00643 { 00644 if((pTxData == NULL ) || (Size == 0)) 00645 { 00646 return HAL_ERROR; 00647 } 00648 00649 /* Process Locked */ 00650 __HAL_LOCK(husart); 00651 00652 husart->pTxBuffPtr = pTxData; 00653 husart->TxXferSize = Size; 00654 husart->TxXferCount = Size; 00655 00656 husart->ErrorCode = HAL_USART_ERROR_NONE; 00657 husart->State = HAL_USART_STATE_BUSY_TX; 00658 00659 /* The USART Error Interrupts: (Frame error, noise error, overrun error) 00660 are not managed by the USART Transmit Process to avoid the overrun interrupt 00661 when the usart mode is configured for transmit and receive "USART_MODE_TX_RX" 00662 to benefit for the frame error and noise interrupts the usart mode should be 00663 configured only for transmit "USART_MODE_TX" */ 00664 00665 /* Process Unlocked */ 00666 __HAL_UNLOCK(husart); 00667 00668 /* Enable the USART Transmit Data Register Empty Interrupt */ 00669 __HAL_USART_ENABLE_IT(husart, USART_IT_TXE); 00670 00671 return HAL_OK; 00672 } 00673 else 00674 { 00675 return HAL_BUSY; 00676 } 00677 } 00678 00679 /** 00680 * @brief Receive an amount of data in blocking mode. 00681 * @note To receive synchronous data, dummy data are simultaneously transmitted. 00682 * @param husart USART handle. 00683 * @param pRxData pointer to data buffer. 00684 * @param Size amount of data to be received. 00685 * @retval HAL status 00686 */ 00687 HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size) 00688 { 00689 if(husart->State == HAL_USART_STATE_READY) 00690 { 00691 if((pRxData == NULL ) || (Size == 0)) 00692 { 00693 return HAL_ERROR; 00694 } 00695 00696 /* Process Locked */ 00697 __HAL_LOCK(husart); 00698 00699 husart->pRxBuffPtr = pRxData; 00700 husart->RxXferSize = Size; 00701 husart->RxXferCount = Size; 00702 00703 USART_MASK_COMPUTATION(husart); 00704 00705 husart->ErrorCode = HAL_USART_ERROR_NONE; 00706 husart->State = HAL_USART_STATE_BUSY_RX; 00707 00708 /* Process Unlocked */ 00709 __HAL_UNLOCK(husart); 00710 00711 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */ 00712 SET_BIT(husart->Instance->CR3, USART_CR3_EIE); 00713 00714 /* Enable the USART Parity Error and USART Data Register not empty Interrupts */ 00715 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE); 00716 00717 /* Send dummy byte in order to generate the clock for the Slave to send the next data */ 00718 if(husart->Init.WordLength == USART_WORDLENGTH_9B) 00719 { 00720 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x01FF); 00721 } 00722 else 00723 { 00724 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF); 00725 } 00726 00727 return HAL_OK; 00728 } 00729 else 00730 { 00731 return HAL_BUSY; 00732 } 00733 } 00734 00735 /** 00736 * @brief Full-Duplex Send and Receive an amount of data in interrupt mode. 00737 * @param husart USART handle. 00738 * @param pTxData pointer to TX data buffer. 00739 * @param pRxData pointer to RX data buffer. 00740 * @param Size amount of data to be sent (same amount to be received). 00741 * @retval HAL status 00742 */ 00743 HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size) 00744 { 00745 00746 if(husart->State == HAL_USART_STATE_READY) 00747 { 00748 if((pTxData == NULL) || (pRxData == NULL) || (Size == 0)) 00749 { 00750 return HAL_ERROR; 00751 } 00752 /* Process Locked */ 00753 __HAL_LOCK(husart); 00754 00755 husart->pRxBuffPtr = pRxData; 00756 husart->RxXferSize = Size; 00757 husart->RxXferCount = Size; 00758 husart->pTxBuffPtr = pTxData; 00759 husart->TxXferSize = Size; 00760 husart->TxXferCount = Size; 00761 00762 /* Computation of USART mask to apply to RDR register */ 00763 USART_MASK_COMPUTATION(husart); 00764 00765 husart->ErrorCode = HAL_USART_ERROR_NONE; 00766 husart->State = HAL_USART_STATE_BUSY_TX_RX; 00767 00768 /* Process Unlocked */ 00769 __HAL_UNLOCK(husart); 00770 00771 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */ 00772 SET_BIT(husart->Instance->CR3, USART_CR3_EIE); 00773 00774 /* Enable the USART Parity Error and USART Data Register not empty Interrupts */ 00775 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE); 00776 00777 /* Enable the USART Transmit Data Register Empty Interrupt */ 00778 SET_BIT(husart->Instance->CR1, USART_CR1_TXEIE); 00779 00780 return HAL_OK; 00781 } 00782 else 00783 { 00784 return HAL_BUSY; 00785 } 00786 } 00787 00788 /** 00789 * @brief Send an amount of data in DMA mode. 00790 * @param husart USART handle. 00791 * @param pTxData pointer to data buffer. 00792 * @param Size amount of data to be sent. 00793 * @retval HAL status 00794 */ 00795 HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size) 00796 { 00797 uint32_t *tmp; 00798 00799 if(husart->State == HAL_USART_STATE_READY) 00800 { 00801 if((pTxData == NULL ) || (Size == 0)) 00802 { 00803 return HAL_ERROR; 00804 } 00805 /* Process Locked */ 00806 __HAL_LOCK(husart); 00807 00808 husart->pTxBuffPtr = pTxData; 00809 husart->TxXferSize = Size; 00810 husart->TxXferCount = Size; 00811 00812 husart->ErrorCode = HAL_USART_ERROR_NONE; 00813 husart->State = HAL_USART_STATE_BUSY_TX; 00814 00815 /* Set the USART DMA transfer complete callback */ 00816 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt; 00817 00818 /* Set the USART DMA Half transfer complete callback */ 00819 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt; 00820 00821 /* Set the DMA error callback */ 00822 husart->hdmatx->XferErrorCallback = USART_DMAError; 00823 00824 /* Enable the USART transmit DMA channel */ 00825 tmp = (uint32_t*)&pTxData; 00826 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size); 00827 00828 /* Clear the TC flag in the ICR register */ 00829 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF); 00830 00831 /* Process Unlocked */ 00832 __HAL_UNLOCK(husart); 00833 00834 /* Enable the DMA transfer for transmit request by setting the DMAT bit 00835 in the USART CR3 register */ 00836 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT); 00837 00838 return HAL_OK; 00839 } 00840 else 00841 { 00842 return HAL_BUSY; 00843 } 00844 } 00845 00846 /** 00847 * @brief Receive an amount of data in DMA mode. 00848 * @param husart USART handle. 00849 * @param pRxData pointer to data buffer. 00850 * @param Size amount of data to be received. 00851 * @note When the USART parity is enabled (PCE = 1), the received data contain 00852 * the parity bit (MSB position). 00853 * @note The USART DMA transmit channel must be configured in order to generate the clock for the slave. 00854 * @retval HAL status 00855 */ 00856 HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size) 00857 { 00858 uint32_t *tmp; 00859 00860 /* Check that a Rx process is not already ongoing */ 00861 if(husart->State == HAL_USART_STATE_READY) 00862 { 00863 if((pRxData == NULL ) || (Size == 0)) 00864 { 00865 return HAL_ERROR; 00866 } 00867 00868 /* Process Locked */ 00869 __HAL_LOCK(husart); 00870 00871 husart->pRxBuffPtr = pRxData; 00872 husart->RxXferSize = Size; 00873 husart->pTxBuffPtr = pRxData; 00874 husart->TxXferSize = Size; 00875 00876 husart->ErrorCode = HAL_USART_ERROR_NONE; 00877 husart->State = HAL_USART_STATE_BUSY_RX; 00878 00879 /* Set the USART DMA Rx transfer complete callback */ 00880 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt; 00881 00882 /* Set the USART DMA Half transfer complete callback */ 00883 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt; 00884 00885 /* Set the USART DMA Rx transfer error callback */ 00886 husart->hdmarx->XferErrorCallback = USART_DMAError; 00887 00888 /* Enable the USART receive DMA channel */ 00889 tmp = (uint32_t*)&pRxData; 00890 HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t*)tmp, Size); 00891 00892 /* Enable the USART transmit DMA channel: the transmit channel is used in order 00893 to generate in the non-blocking mode the clock to the slave device, 00894 this mode isn't a simplex receive mode but a full-duplex receive mode */ 00895 tmp = (uint32_t*)&pRxData; 00896 /* Set the USART DMA Tx Complete and Error callback to Null */ 00897 husart->hdmatx->XferErrorCallback = NULL; 00898 husart->hdmatx->XferHalfCpltCallback = NULL; 00899 husart->hdmatx->XferCpltCallback = NULL; 00900 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size); 00901 00902 /* Process Unlocked */ 00903 __HAL_UNLOCK(husart); 00904 00905 /* Enable the USART Parity Error Interrupt */ 00906 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE); 00907 00908 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */ 00909 SET_BIT(husart->Instance->CR3, USART_CR3_EIE); 00910 00911 /* Enable the DMA transfer for the receiver request by setting the DMAR bit 00912 in the USART CR3 register */ 00913 SET_BIT(husart->Instance->CR3, USART_CR3_DMAR); 00914 00915 /* Enable the DMA transfer for transmit request by setting the DMAT bit 00916 in the USART CR3 register */ 00917 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT); 00918 00919 return HAL_OK; 00920 } 00921 else 00922 { 00923 return HAL_BUSY; 00924 } 00925 } 00926 00927 /** 00928 * @brief Full-Duplex Transmit Receive an amount of data in non-blocking mode. 00929 * @param husart USART handle. 00930 * @param pTxData pointer to TX data buffer. 00931 * @param pRxData pointer to RX data buffer. 00932 * @param Size amount of data to be received/sent. 00933 * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit. 00934 * @retval HAL status 00935 */ 00936 HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size) 00937 { 00938 uint32_t *tmp; 00939 00940 if(husart->State == HAL_USART_STATE_READY) 00941 { 00942 if((pTxData == NULL) || (pRxData == NULL) || (Size == 0)) 00943 { 00944 return HAL_ERROR; 00945 } 00946 /* Process Locked */ 00947 __HAL_LOCK(husart); 00948 00949 husart->pRxBuffPtr = pRxData; 00950 husart->RxXferSize = Size; 00951 husart->pTxBuffPtr = pTxData; 00952 husart->TxXferSize = Size; 00953 00954 husart->ErrorCode = HAL_USART_ERROR_NONE; 00955 husart->State = HAL_USART_STATE_BUSY_TX_RX; 00956 00957 /* Set the USART DMA Rx transfer complete callback */ 00958 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt; 00959 00960 /* Set the USART DMA Half transfer complete callback */ 00961 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt; 00962 00963 /* Set the USART DMA Tx transfer complete callback */ 00964 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt; 00965 00966 /* Set the USART DMA Half transfer complete callback */ 00967 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt; 00968 00969 /* Set the USART DMA Tx transfer error callback */ 00970 husart->hdmatx->XferErrorCallback = USART_DMAError; 00971 00972 /* Set the USART DMA Rx transfer error callback */ 00973 husart->hdmarx->XferErrorCallback = USART_DMAError; 00974 00975 /* Enable the USART receive DMA channel */ 00976 tmp = (uint32_t*)&pRxData; 00977 HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t*)tmp, Size); 00978 00979 /* Enable the USART transmit DMA channel */ 00980 tmp = (uint32_t*)&pTxData; 00981 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size); 00982 00983 /* Process Unlocked */ 00984 __HAL_UNLOCK(husart); 00985 00986 /* Enable the USART Parity Error Interrupt */ 00987 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE); 00988 00989 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */ 00990 SET_BIT(husart->Instance->CR3, USART_CR3_EIE); 00991 00992 /* Clear the TC flag in the ICR register */ 00993 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF); 00994 00995 /* Enable the DMA transfer for the receiver request by setting the DMAR bit 00996 in the USART CR3 register */ 00997 SET_BIT(husart->Instance->CR3, USART_CR3_DMAR); 00998 00999 /* Enable the DMA transfer for transmit request by setting the DMAT bit 01000 in the USART CR3 register */ 01001 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT); 01002 01003 return HAL_OK; 01004 } 01005 else 01006 { 01007 return HAL_BUSY; 01008 } 01009 } 01010 01011 /** 01012 * @brief Pause the DMA Transfer. 01013 * @param husart USART handle. 01014 * @retval HAL status 01015 */ 01016 HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart) 01017 { 01018 /* Process Locked */ 01019 __HAL_LOCK(husart); 01020 01021 if( (husart->State == HAL_USART_STATE_BUSY_TX) && 01022 (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))) 01023 { 01024 /* Disable the USART DMA Tx request */ 01025 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT); 01026 } 01027 else if( (husart->State == HAL_USART_STATE_BUSY_RX) || 01028 (husart->State == HAL_USART_STATE_BUSY_TX_RX) ) 01029 { 01030 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)) 01031 { 01032 /* Disable the USART DMA Tx request */ 01033 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT); 01034 } 01035 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) 01036 { 01037 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ 01038 CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE); 01039 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE); 01040 01041 /* Disable the USART DMA Rx request */ 01042 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR); 01043 } 01044 } 01045 01046 /* Process Unlocked */ 01047 __HAL_UNLOCK(husart); 01048 01049 return HAL_OK; 01050 } 01051 01052 /** 01053 * @brief Resume the DMA Transfer. 01054 * @param husart USART handle. 01055 * @retval HAL status 01056 */ 01057 HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart) 01058 { 01059 /* Process Locked */ 01060 __HAL_LOCK(husart); 01061 01062 if(husart->State == HAL_USART_STATE_BUSY_TX) 01063 { 01064 /* Enable the USART DMA Tx request */ 01065 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT); 01066 } 01067 else if( (husart->State == HAL_USART_STATE_BUSY_RX) || 01068 (husart->State == HAL_USART_STATE_BUSY_TX_RX) ) 01069 { 01070 /* Clear the Overrun flag before resuming the Rx transfer*/ 01071 __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF); 01072 01073 /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */ 01074 SET_BIT(husart->Instance->CR1, USART_CR1_PEIE); 01075 SET_BIT(husart->Instance->CR3, USART_CR3_EIE); 01076 01077 /* Enable the USART DMA Rx request before the DMA Tx request */ 01078 SET_BIT(husart->Instance->CR3, USART_CR3_DMAR); 01079 01080 /* Enable the USART DMA Tx request */ 01081 SET_BIT(husart->Instance->CR3, USART_CR3_DMAT); 01082 } 01083 01084 /* Process Unlocked */ 01085 __HAL_UNLOCK(husart); 01086 01087 return HAL_OK; 01088 } 01089 01090 /** 01091 * @brief Stop the DMA Transfer. 01092 * @param husart USART handle. 01093 * @retval HAL status 01094 */ 01095 HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart) 01096 { 01097 /* The Lock is not implemented on this API to allow the user application 01098 to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback() / 01099 HAL_USART_TxHalfCpltCallback / HAL_USART_RxHalfCpltCallback: 01100 indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete 01101 interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of 01102 the stream and the corresponding call back is executed. */ 01103 01104 /* Disable the USART Tx/Rx DMA requests */ 01105 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT); 01106 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR); 01107 01108 /* Abort the USART DMA tx channel */ 01109 if(husart->hdmatx != NULL) 01110 { 01111 HAL_DMA_Abort(husart->hdmatx); 01112 } 01113 /* Abort the USART DMA rx channel */ 01114 if(husart->hdmarx != NULL) 01115 { 01116 HAL_DMA_Abort(husart->hdmarx); 01117 } 01118 01119 USART_EndTransfer(husart); 01120 husart->State = HAL_USART_STATE_READY; 01121 01122 return HAL_OK; 01123 } 01124 01125 /** 01126 * @brief Handle USART interrupt request. 01127 * @param husart USART handle. 01128 * @retval None 01129 */ 01130 void HAL_USART_IRQHandler(USART_HandleTypeDef *husart) 01131 { 01132 uint32_t isrflags = READ_REG(husart->Instance->ISR); 01133 uint32_t cr1its = READ_REG(husart->Instance->CR1); 01134 uint32_t cr3its; 01135 uint32_t errorflags; 01136 01137 /* If no error occurs */ 01138 errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE)); 01139 if (errorflags == RESET) 01140 { 01141 /* USART in mode Receiver ---------------------------------------------------*/ 01142 if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) 01143 { 01144 if(husart->State == HAL_USART_STATE_BUSY_RX) 01145 { 01146 USART_Receive_IT(husart); 01147 } 01148 else 01149 { 01150 USART_TransmitReceive_IT(husart); 01151 } 01152 return; 01153 } 01154 } 01155 01156 /* If some errors occur */ 01157 cr3its = READ_REG(husart->Instance->CR3); 01158 if((errorflags != RESET) && ((cr3its & (USART_CR3_EIE | USART_CR1_PEIE)) != RESET)) 01159 { 01160 /* USART parity error interrupt occurred -------------------------------------*/ 01161 if(((isrflags & USART_ISR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET)) 01162 { 01163 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_PEF); 01164 01165 husart->ErrorCode |= HAL_USART_ERROR_PE; 01166 } 01167 01168 /* USART frame error interrupt occurred --------------------------------------*/ 01169 if(((isrflags & USART_ISR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) 01170 { 01171 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_FEF); 01172 01173 husart->ErrorCode |= HAL_USART_ERROR_FE; 01174 } 01175 01176 /* USART noise error interrupt occurred --------------------------------------*/ 01177 if(((isrflags & USART_ISR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) 01178 { 01179 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_NEF); 01180 01181 husart->ErrorCode |= HAL_USART_ERROR_NE; 01182 } 01183 01184 /* USART Over-Run interrupt occurred -----------------------------------------*/ 01185 if(((isrflags & USART_ISR_ORE) != RESET) && 01186 (((cr1its & USART_CR1_RXNEIE) != RESET) || ((cr3its & USART_CR3_EIE) != RESET))) 01187 { 01188 __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF); 01189 01190 husart->ErrorCode |= HAL_USART_ERROR_ORE; 01191 } 01192 01193 /* Call USART Error Call back function if need be --------------------------*/ 01194 if(husart->ErrorCode != HAL_USART_ERROR_NONE) 01195 { 01196 /* USART in mode Receiver ---------------------------------------------------*/ 01197 if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) 01198 { 01199 if(husart->State == HAL_USART_STATE_BUSY_RX) 01200 { 01201 USART_Receive_IT(husart); 01202 } 01203 else 01204 { 01205 USART_TransmitReceive_IT(husart); 01206 } 01207 } 01208 01209 /* If Overrun error occurs, or if any error occurs in DMA mode reception, 01210 consider error as blocking */ 01211 if (((husart->ErrorCode & HAL_USART_ERROR_ORE) != RESET) || 01212 (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))) 01213 { 01214 /* Blocking error : transfer is aborted 01215 Set the USART state ready to be able to start again the process, 01216 Disable Interrupts, and disable DMA requests, if ongoing */ 01217 USART_EndTransfer(husart); 01218 01219 /* Disable the USART DMA Rx request if enabled */ 01220 if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) 01221 { 01222 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR | USART_CR3_DMAR); 01223 01224 /* Abort the USART DMA Tx channel */ 01225 if(husart->hdmatx != NULL) 01226 { 01227 /* Set the USART Tx DMA Abort callback to NULL : no callback 01228 executed at end of DMA abort procedure */ 01229 husart->hdmatx->XferAbortCallback = NULL; 01230 01231 /* Abort DMA TX */ 01232 HAL_DMA_Abort_IT(husart->hdmatx); 01233 } 01234 01235 /* Abort the USART DMA Rx channel */ 01236 if(husart->hdmarx != NULL) 01237 { 01238 /* Set the USART Rx DMA Abort callback : 01239 will lead to call HAL_USART_ErrorCallback() at end of DMA abort procedure */ 01240 husart->hdmarx->XferAbortCallback = USART_DMAAbortOnError; 01241 01242 /* Abort DMA RX */ 01243 if(HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK) 01244 { 01245 /* Call Directly husart->hdmarx->XferAbortCallback function in case of error */ 01246 husart->hdmarx->XferAbortCallback(husart->hdmarx); 01247 } 01248 } 01249 else 01250 { 01251 /* Call user error callback */ 01252 HAL_USART_ErrorCallback(husart); 01253 } 01254 } 01255 else 01256 { 01257 /* Call user error callback */ 01258 HAL_USART_ErrorCallback(husart); 01259 } 01260 } 01261 else 01262 { 01263 /* Non Blocking error : transfer could go on. 01264 Error is notified to user through user error callback */ 01265 HAL_USART_ErrorCallback(husart); 01266 husart->ErrorCode = HAL_USART_ERROR_NONE; 01267 } 01268 } 01269 return; 01270 01271 } /* End if some error occurs */ 01272 01273 01274 /* USART in mode Transmitter ------------------------------------------------*/ 01275 if(((isrflags & USART_ISR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET)) 01276 { 01277 if(husart->State == HAL_USART_STATE_BUSY_TX) 01278 { 01279 USART_Transmit_IT(husart); 01280 } 01281 else 01282 { 01283 USART_TransmitReceive_IT(husart); 01284 } 01285 return; 01286 } 01287 01288 /* USART in mode Transmitter (transmission end) -----------------------------*/ 01289 if(((isrflags & USART_ISR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET)) 01290 { 01291 USART_EndTransmit_IT(husart); 01292 return; 01293 } 01294 01295 } 01296 01297 /** 01298 * @brief Tx Transfer completed callback. 01299 * @param husart: USART handle. 01300 * @retval None 01301 */ 01302 __weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart) 01303 { 01304 /* Prevent unused argument(s) compilation warning */ 01305 UNUSED(husart); 01306 01307 /* NOTE : This function should not be modified, when the callback is needed, 01308 the HAL_USART_TxCpltCallback can be implemented in the user file. 01309 */ 01310 } 01311 01312 /** 01313 * @brief Tx Half Transfer completed callback. 01314 * @param husart: USART handle. 01315 * @retval None 01316 */ 01317 __weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart) 01318 { 01319 /* Prevent unused argument(s) compilation warning */ 01320 UNUSED(husart); 01321 01322 /* NOTE: This function should not be modified, when the callback is needed, 01323 the HAL_USART_TxHalfCpltCallback can be implemented in the user file. 01324 */ 01325 } 01326 01327 /** 01328 * @brief Rx Transfer completed callback. 01329 * @param husart: USART handle. 01330 * @retval None 01331 */ 01332 __weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart) 01333 { 01334 /* Prevent unused argument(s) compilation warning */ 01335 UNUSED(husart); 01336 01337 /* NOTE: This function should not be modified, when the callback is needed, 01338 the HAL_USART_RxCpltCallback can be implemented in the user file. 01339 */ 01340 } 01341 01342 /** 01343 * @brief Rx Half Transfer completed callback. 01344 * @param husart: USART handle. 01345 * @retval None 01346 */ 01347 __weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart) 01348 { 01349 /* Prevent unused argument(s) compilation warning */ 01350 UNUSED(husart); 01351 01352 /* NOTE : This function should not be modified, when the callback is needed, 01353 the HAL_USART_RxHalfCpltCallback can be implemented in the user file 01354 */ 01355 } 01356 01357 /** 01358 * @brief Tx/Rx Transfers completed callback for the non-blocking process. 01359 * @param husart: USART handle. 01360 * @retval None 01361 */ 01362 __weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart) 01363 { 01364 /* Prevent unused argument(s) compilation warning */ 01365 UNUSED(husart); 01366 01367 /* NOTE : This function should not be modified, when the callback is needed, 01368 the HAL_USART_TxRxCpltCallback can be implemented in the user file 01369 */ 01370 } 01371 01372 /** 01373 * @brief USART error callback. 01374 * @param husart: USART handle. 01375 * @retval None 01376 */ 01377 __weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart) 01378 { 01379 /* Prevent unused argument(s) compilation warning */ 01380 UNUSED(husart); 01381 01382 /* NOTE : This function should not be modified, when the callback is needed, 01383 the HAL_USART_ErrorCallback can be implemented in the user file. 01384 */ 01385 } 01386 01387 /** 01388 * @} 01389 */ 01390 01391 /** @defgroup USART_Exported_Functions_Group4 Peripheral State and Error functions 01392 * @brief USART Peripheral State and Error functions 01393 * 01394 @verbatim 01395 ============================================================================== 01396 ##### Peripheral State and Error functions ##### 01397 ============================================================================== 01398 [..] 01399 This subsection provides functions allowing to : 01400 (+) Return the USART handle state 01401 (+) Return the USART handle error code 01402 01403 @endverbatim 01404 * @{ 01405 */ 01406 01407 01408 /** 01409 * @brief Return the USART handle state. 01410 * @param husart : pointer to a USART_HandleTypeDef structure that contains 01411 * the configuration information for the specified USART. 01412 * @retval USART handle state 01413 */ 01414 HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart) 01415 { 01416 return husart->State; 01417 } 01418 01419 /** 01420 * @brief Return the USART error code. 01421 * @param husart : pointer to a USART_HandleTypeDef structure that contains 01422 * the configuration information for the specified USART. 01423 * @retval USART handle Error Code 01424 */ 01425 uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart) 01426 { 01427 return husart->ErrorCode; 01428 } 01429 01430 /** 01431 * @} 01432 */ 01433 01434 /** 01435 * @} 01436 */ 01437 01438 /** @defgroup USART_Private_Functions USART Private Functions 01439 * @{ 01440 */ 01441 01442 /** 01443 * @brief End ongoing transfer on USART peripheral (following error detection or Transfer completion). 01444 * @param husart USART handle. 01445 * @retval None 01446 */ 01447 static void USART_EndTransfer(USART_HandleTypeDef *husart) 01448 { 01449 /* Disable TXEIE and TCIE interrupts */ 01450 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ 01451 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE | USART_CR1_RXNEIE | USART_CR1_PEIE)); 01452 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE); 01453 01454 /* At end of process, restore husart->State to Ready */ 01455 husart->State = HAL_USART_STATE_READY; 01456 } 01457 01458 /** 01459 * @brief DMA USART transmit process complete callback. 01460 * @param hdma DMA handle. 01461 * @retval None 01462 */ 01463 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma) 01464 { 01465 USART_HandleTypeDef* husart = (USART_HandleTypeDef*)(hdma->Parent); 01466 01467 /* DMA Normal mode */ 01468 if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) 01469 { 01470 husart->TxXferCount = 0; 01471 01472 if(husart->State == HAL_USART_STATE_BUSY_TX) 01473 { 01474 /* Disable the DMA transfer for transmit request by resetting the DMAT bit 01475 in the USART CR3 register */ 01476 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT); 01477 01478 /* Enable the USART Transmit Complete Interrupt */ 01479 __HAL_USART_ENABLE_IT(husart, USART_IT_TC); 01480 } 01481 } 01482 /* DMA Circular mode */ 01483 else 01484 { 01485 if(husart->State == HAL_USART_STATE_BUSY_TX) 01486 { 01487 HAL_USART_TxCpltCallback(husart); 01488 } 01489 } 01490 } 01491 01492 /** 01493 * @brief DMA USART transmit process half complete callback. 01494 * @param hdma DMA handle. 01495 * @retval None 01496 */ 01497 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma) 01498 { 01499 USART_HandleTypeDef* husart = (USART_HandleTypeDef*)(hdma->Parent); 01500 01501 HAL_USART_TxHalfCpltCallback(husart); 01502 } 01503 01504 /** 01505 * @brief DMA USART receive process complete callback. 01506 * @param hdma DMA handle. 01507 * @retval None 01508 */ 01509 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) 01510 { 01511 USART_HandleTypeDef* husart = (USART_HandleTypeDef*)(hdma->Parent); 01512 01513 /* DMA Normal mode */ 01514 if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) 01515 { 01516 husart->RxXferCount = 0; 01517 01518 /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ 01519 CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE); 01520 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE); 01521 01522 /* Disable the DMA RX transfer for the receiver request by resetting the DMAR bit 01523 in USART CR3 register */ 01524 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR); 01525 /* similarly, disable the DMA TX transfer that was started to provide the 01526 clock to the slave device */ 01527 CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT); 01528 01529 if(husart->State == HAL_USART_STATE_BUSY_RX) 01530 { 01531 HAL_USART_RxCpltCallback(husart); 01532 } 01533 /* The USART state is HAL_USART_STATE_BUSY_TX_RX */ 01534 else 01535 { 01536 HAL_USART_TxRxCpltCallback(husart); 01537 } 01538 husart->State= HAL_USART_STATE_READY; 01539 } 01540 /* DMA circular mode */ 01541 else 01542 { 01543 if(husart->State == HAL_USART_STATE_BUSY_RX) 01544 { 01545 HAL_USART_RxCpltCallback(husart); 01546 } 01547 /* The USART state is HAL_USART_STATE_BUSY_TX_RX */ 01548 else 01549 { 01550 HAL_USART_TxRxCpltCallback(husart); 01551 } 01552 } 01553 01554 } 01555 01556 /** 01557 * @brief DMA USART receive process half complete callback. 01558 * @param hdma DMA handle. 01559 * @retval None 01560 */ 01561 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma) 01562 { 01563 USART_HandleTypeDef* husart = (USART_HandleTypeDef*)(hdma->Parent); 01564 01565 HAL_USART_RxHalfCpltCallback(husart); 01566 } 01567 01568 /** 01569 * @brief DMA USART communication error callback. 01570 * @param hdma: DMA handle. 01571 * @retval None 01572 */ 01573 static void USART_DMAError(DMA_HandleTypeDef *hdma) 01574 { 01575 USART_HandleTypeDef* husart = (USART_HandleTypeDef*)(hdma->Parent); 01576 01577 husart->RxXferCount = 0; 01578 husart->TxXferCount = 0; 01579 USART_EndTransfer(husart); 01580 01581 husart->ErrorCode |= HAL_USART_ERROR_DMA; 01582 husart->State= HAL_USART_STATE_READY; 01583 01584 HAL_USART_ErrorCallback(husart); 01585 } 01586 01587 /** 01588 * @brief DMA USART communication abort callback, when initiated by HAL services on Error 01589 * (To be called at end of DMA Abort procedure following error occurrence). 01590 * @param hdma DMA handle. 01591 * @retval None 01592 */ 01593 static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma) 01594 { 01595 USART_HandleTypeDef* husart = (USART_HandleTypeDef*)(hdma->Parent); 01596 husart->RxXferCount = 0; 01597 husart->TxXferCount = 0; 01598 01599 HAL_USART_ErrorCallback(husart); 01600 } 01601 01602 /** 01603 * @brief Handle USART Communication Timeout. 01604 * @param husart USART handle. 01605 * @param Flag Specifies the USART flag to check. 01606 * @param Status the Flag status (SET or RESET). 01607 * @param Tickstart Tick start value 01608 * @param Timeout timeout duration. 01609 * @retval HAL status 01610 */ 01611 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout) 01612 { 01613 /* Wait until flag is set */ 01614 while((__HAL_USART_GET_FLAG(husart, Flag) ? SET : RESET) == Status) 01615 { 01616 /* Check for the Timeout */ 01617 if(Timeout != HAL_MAX_DELAY) 01618 { 01619 if((Timeout == 0) || ((HAL_GetTick()-Tickstart) > Timeout)) 01620 { 01621 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ 01622 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE)); 01623 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE); 01624 01625 husart->State= HAL_USART_STATE_READY; 01626 01627 /* Process Unlocked */ 01628 __HAL_UNLOCK(husart); 01629 01630 return HAL_TIMEOUT; 01631 } 01632 } 01633 } 01634 return HAL_OK; 01635 } 01636 01637 /** 01638 * @brief Configure the USART peripheral. 01639 * @param husart: USART handle. 01640 * @retval HAL status 01641 */ 01642 static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart) 01643 { 01644 uint32_t tmpreg = 0x0; 01645 USART_ClockSourceTypeDef clocksource = USART_CLOCKSOURCE_UNDEFINED; 01646 HAL_StatusTypeDef ret = HAL_OK; 01647 uint16_t brrtemp = 0x0000; 01648 uint16_t usartdiv = 0x0000; 01649 01650 /* Check the parameters */ 01651 assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity)); 01652 assert_param(IS_USART_PHASE(husart->Init.CLKPhase)); 01653 assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit)); 01654 assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate)); 01655 assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength)); 01656 assert_param(IS_USART_STOPBITS(husart->Init.StopBits)); 01657 assert_param(IS_USART_PARITY(husart->Init.Parity)); 01658 assert_param(IS_USART_MODE(husart->Init.Mode)); 01659 01660 01661 /*-------------------------- USART CR1 Configuration -----------------------*/ 01662 /* Clear M, PCE, PS, TE and RE bits and configure 01663 * the USART Word Length, Parity and Mode: 01664 * set the M bits according to husart->Init.WordLength value 01665 * set PCE and PS bits according to husart->Init.Parity value 01666 * set TE and RE bits according to husart->Init.Mode value 01667 * force OVER8 to 1 to allow to reach the maximum speed (Fclock/8) */ 01668 tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8; 01669 MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg); 01670 01671 /*---------------------------- USART CR2 Configuration ---------------------*/ 01672 /* Clear and configure the USART Clock, CPOL, CPHA, LBCL and STOP bits: 01673 * set CPOL bit according to husart->Init.CLKPolarity value 01674 * set CPHA bit according to husart->Init.CLKPhase value 01675 * set LBCL bit according to husart->Init.CLKLastBit value 01676 * set STOP[13:12] bits according to husart->Init.StopBits value */ 01677 tmpreg = (uint32_t)(USART_CLOCK_ENABLE); 01678 tmpreg |= ((uint32_t)husart->Init.CLKPolarity | (uint32_t)husart->Init.CLKPhase); 01679 tmpreg |= ((uint32_t)husart->Init.CLKLastBit | (uint32_t)husart->Init.StopBits); 01680 MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg); 01681 01682 /*-------------------------- USART CR3 Configuration -----------------------*/ 01683 /* no CR3 register configuration */ 01684 01685 /*-------------------------- USART BRR Configuration -----------------------*/ 01686 /* BRR is filled-up according to OVER8 bit setting which is forced to 1 */ 01687 USART_GETCLOCKSOURCE(husart, clocksource); 01688 switch (clocksource) 01689 { 01690 case USART_CLOCKSOURCE_PCLK1: 01691 usartdiv = (uint16_t)(((2*HAL_RCC_GetPCLK1Freq()) + (husart->Init.BaudRate/2)) / husart->Init.BaudRate); 01692 break; 01693 case USART_CLOCKSOURCE_PCLK2: 01694 usartdiv = (uint16_t)(((2*HAL_RCC_GetPCLK2Freq()) + (husart->Init.BaudRate/2)) / husart->Init.BaudRate); 01695 break; 01696 case USART_CLOCKSOURCE_HSI: 01697 usartdiv = (uint16_t)(((2*HSI_VALUE) + (husart->Init.BaudRate/2)) / husart->Init.BaudRate); 01698 break; 01699 case USART_CLOCKSOURCE_SYSCLK: 01700 usartdiv = (uint16_t)(((2*HAL_RCC_GetSysClockFreq()) + (husart->Init.BaudRate/2)) / husart->Init.BaudRate); 01701 break; 01702 case USART_CLOCKSOURCE_LSE: 01703 usartdiv = (uint16_t)(((2*LSE_VALUE) + (husart->Init.BaudRate/2)) / husart->Init.BaudRate); 01704 break; 01705 case USART_CLOCKSOURCE_UNDEFINED: 01706 default: 01707 ret = HAL_ERROR; 01708 break; 01709 } 01710 01711 brrtemp = usartdiv & 0xFFF0; 01712 brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000F) >> 1U); 01713 husart->Instance->BRR = brrtemp; 01714 01715 return ret; 01716 } 01717 01718 /** 01719 * @brief Check the USART Idle State. 01720 * @param husart: USART handle. 01721 * @retval HAL status 01722 */ 01723 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart) 01724 { 01725 uint32_t tickstart = 0; 01726 01727 /* Initialize the USART ErrorCode */ 01728 husart->ErrorCode = HAL_USART_ERROR_NONE; 01729 01730 /* Init tickstart for timeout managment*/ 01731 tickstart = HAL_GetTick(); 01732 01733 /* Check if the Transmitter is enabled */ 01734 if((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) 01735 { 01736 /* Wait until TEACK flag is set */ 01737 if(USART_WaitOnFlagUntilTimeout(husart, USART_ISR_TEACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK) 01738 { 01739 /* Timeout occurred */ 01740 return HAL_TIMEOUT; 01741 } 01742 } 01743 /* Check if the Receiver is enabled */ 01744 if((husart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) 01745 { 01746 /* Wait until REACK flag is set */ 01747 if(USART_WaitOnFlagUntilTimeout(husart, USART_ISR_REACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK) 01748 { 01749 /* Timeout occurred */ 01750 return HAL_TIMEOUT; 01751 } 01752 } 01753 01754 /* Initialize the USART state*/ 01755 husart->State= HAL_USART_STATE_READY; 01756 01757 /* Process Unlocked */ 01758 __HAL_UNLOCK(husart); 01759 01760 return HAL_OK; 01761 } 01762 01763 /** 01764 * @brief Simplex send an amount of data in non-blocking mode. 01765 * @note Function called under interruption only, once 01766 * interruptions have been enabled by HAL_USART_Transmit_IT(). 01767 * @note The USART errors are not managed to avoid the overrun error. 01768 * @param husart USART handle. 01769 * @retval HAL status 01770 */ 01771 static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart) 01772 { 01773 uint16_t* tmp; 01774 01775 /* Check that a Tx process is ongoing */ 01776 if(husart->State == HAL_USART_STATE_BUSY_TX) 01777 { 01778 01779 if(husart->TxXferCount == 0) 01780 { 01781 /* Disable the USART Transmit data register empty interrupt */ 01782 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE); 01783 01784 /* Enable the USART Transmit Complete Interrupt */ 01785 __HAL_USART_ENABLE_IT(husart, USART_IT_TC); 01786 01787 return HAL_OK; 01788 } 01789 else 01790 { 01791 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) 01792 { 01793 tmp = (uint16_t*) husart->pTxBuffPtr; 01794 husart->Instance->TDR = (*tmp & (uint16_t)0x01FF); 01795 husart->pTxBuffPtr += 2; 01796 } 01797 else 01798 { 01799 husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0xFF); 01800 } 01801 01802 husart->TxXferCount--; 01803 01804 return HAL_OK; 01805 } 01806 } 01807 else 01808 { 01809 return HAL_BUSY; 01810 } 01811 } 01812 01813 01814 /** 01815 * @brief Wraps up transmission in non-blocking mode. 01816 * @param husart Pointer to a USART_HandleTypeDef structure that contains 01817 * the configuration information for the specified USART module. 01818 * @retval HAL status 01819 */ 01820 static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart) 01821 { 01822 /* Disable the USART Transmit Complete Interrupt */ 01823 __HAL_USART_DISABLE_IT(husart, USART_IT_TC); 01824 01825 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */ 01826 __HAL_USART_DISABLE_IT(husart, USART_IT_ERR); 01827 01828 /* Tx process is ended, restore husart->State to Ready */ 01829 husart->State = HAL_USART_STATE_READY; 01830 01831 HAL_USART_TxCpltCallback(husart); 01832 01833 return HAL_OK; 01834 } 01835 01836 01837 /** 01838 * @brief Simplex receive an amount of data in non-blocking mode. 01839 * @note Function called under interruption only, once 01840 * interruptions have been enabled by HAL_USART_Receive_IT(). 01841 * @param husart USART handle 01842 * @retval HAL status 01843 */ 01844 static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart) 01845 { 01846 uint16_t* tmp; 01847 uint16_t uhMask = husart->Mask; 01848 01849 if(husart->State == HAL_USART_STATE_BUSY_RX) 01850 { 01851 01852 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) 01853 { 01854 tmp = (uint16_t*) husart->pRxBuffPtr; 01855 *tmp = (uint16_t)(husart->Instance->RDR & uhMask); 01856 husart->pRxBuffPtr += 2; 01857 } 01858 else 01859 { 01860 *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask); 01861 } 01862 /* Send dummy byte in order to generate the clock for the Slave to Send the next data */ 01863 husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF); 01864 01865 if(--husart->RxXferCount == 0) 01866 { 01867 /* Disable the USART Parity Error Interrupt and RXNE interrupt*/ 01868 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); 01869 01870 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */ 01871 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE); 01872 01873 /* Rx process is completed, restore husart->State to Ready */ 01874 husart->State = HAL_USART_STATE_READY; 01875 01876 HAL_USART_RxCpltCallback(husart); 01877 01878 return HAL_OK; 01879 } 01880 01881 return HAL_OK; 01882 } 01883 else 01884 { 01885 return HAL_BUSY; 01886 } 01887 } 01888 01889 /** 01890 * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking). 01891 * @note Function called under interruption only, once 01892 * interruptions have been enabled by HAL_USART_TransmitReceive_IT(). 01893 * @param husart: USART handle. 01894 * @retval HAL status 01895 */ 01896 static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart) 01897 { 01898 uint16_t* tmp; 01899 uint16_t uhMask = husart->Mask; 01900 01901 if(husart->State == HAL_USART_STATE_BUSY_TX_RX) 01902 { 01903 01904 if(husart->TxXferCount != 0x00) 01905 { 01906 if(__HAL_USART_GET_FLAG(husart, USART_FLAG_TXE) != RESET) 01907 { 01908 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) 01909 { 01910 tmp = (uint16_t*) husart->pTxBuffPtr; 01911 husart->Instance->TDR = (uint16_t)(*tmp & uhMask); 01912 husart->pTxBuffPtr += 2; 01913 } 01914 else 01915 { 01916 husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)uhMask); 01917 } 01918 husart->TxXferCount--; 01919 01920 /* Check the latest data transmitted */ 01921 if(husart->TxXferCount == 0) 01922 { 01923 __HAL_USART_DISABLE_IT(husart, USART_IT_TXE); 01924 } 01925 } 01926 } 01927 01928 if(husart->RxXferCount != 0x00) 01929 { 01930 if(__HAL_USART_GET_FLAG(husart, USART_FLAG_RXNE) != RESET) 01931 { 01932 if((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) 01933 { 01934 tmp = (uint16_t*) husart->pRxBuffPtr; 01935 *tmp = (uint16_t)(husart->Instance->RDR & uhMask); 01936 husart->pRxBuffPtr += 2; 01937 } 01938 else 01939 { 01940 *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask); 01941 } 01942 husart->RxXferCount--; 01943 } 01944 } 01945 01946 /* Check the latest data received */ 01947 if(husart->RxXferCount == 0) 01948 { 01949 /* Disable the USART Parity Error Interrupt and RXNE interrupt*/ 01950 CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); 01951 01952 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */ 01953 CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE); 01954 01955 /* Rx process is completed, restore husart->State to Ready */ 01956 husart->State = HAL_USART_STATE_READY; 01957 01958 HAL_USART_TxRxCpltCallback(husart); 01959 01960 return HAL_OK; 01961 } 01962 01963 return HAL_OK; 01964 } 01965 else 01966 { 01967 return HAL_BUSY; 01968 } 01969 } 01970 01971 /** 01972 * @} 01973 */ 01974 01975 #endif /* HAL_USART_MODULE_ENABLED */ 01976 /** 01977 * @} 01978 */ 01979 01980 /** 01981 * @} 01982 */ 01983 01984 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Tue Jul 12 2022 10:59:59 by
