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