]> git.gir.st - tmk_keyboard.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/stm32f4xx_hal_usart.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[tmk_keyboard.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_STM / TARGET_STM32F4 / stm32f4xx_hal_usart.c
1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_usart.c
4 * @author MCD Application Team
5 * @version V1.1.0
6 * @date 19-June-2014
7 * @brief USART HAL module driver.
8 * This file provides firmware functions to manage the following
9 * functionalities of the Universal Synchronous Asynchronous Receiver Transmitter (USART) peripheral:
10 * + Initialization and de-initialization functions
11 * + IO operation functions
12 * + Peripheral Control functions
13 @verbatim
14 ==============================================================================
15 ##### How to use this driver #####
16 ==============================================================================
17 [..]
18 The USART HAL driver can be used as follows:
19
20 (#) Declare a USART_HandleTypeDef handle structure.
21 (#) Initialize the USART low level resources by implementing the HAL_USART_MspInit () API:
22 (##) Enable the USARTx interface clock.
23 (##) USART pins configuration:
24 (+++) Enable the clock for the USART GPIOs.
25 (+++) Configure these USART pins as alternate function pull-up.
26 (##) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
27 HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
28 (+++) Configure the USARTx interrupt priority.
29 (+++) Enable the NVIC USART IRQ handle.
30 (##) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA()
31 HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
32 (+++) Declare a DMA handle structure for the Tx/Rx stream.
33 (+++) Enable the DMAx interface clock.
34 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
35 (+++) Configure the DMA Tx/Rx Stream.
36 (+++) Associate the initilalized DMA handle to the USART DMA Tx/Rx handle.
37 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx Stream.
38
39 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
40 flow control and Mode(Receiver/Transmitter) in the husart Init structure.
41
42 (#) Initialize the USART registers by calling the HAL_USART_Init() API:
43 (++) These APIs configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
44 by calling the customed HAL_USART_MspInit(&husart) API.
45
46 -@@- The specific USART interrupts (Transmission complete interrupt,
47 RXNE interrupt and Error Interrupts) will be managed using the macros
48 __USART_ENABLE_IT() and __USART_DISABLE_IT() inside the transmit and receive process.
49
50 (#) Three operation modes are available within this driver :
51
52 *** Polling mode IO operation ***
53 =================================
54 [..]
55 (+) Send an amount of data in blocking mode using HAL_USART_Transmit()
56 (+) Receive an amount of data in blocking mode using HAL_USART_Receive()
57
58 *** Interrupt mode IO operation ***
59 ===================================
60 [..]
61 (+) Send an amount of data in non blocking mode using HAL_USART_Transmit_IT()
62 (+) At transmission end of half transfer HAL_USART_TxHalfCpltCallback is executed and user can
63 add his own code by customization of function pointer HAL_USART_TxHalfCpltCallback
64 (+) At transmission end of transfer HAL_USART_TxCpltCallback is executed and user can
65 add his own code by customization of function pointer HAL_USART_TxCpltCallback
66 (+) Receive an amount of data in non blocking mode using HAL_USART_Receive_IT()
67 (+) At reception end of half transfer HAL_USART_RxHalfCpltCallback is executed and user can
68 add his own code by customization of function pointer HAL_USART_RxHalfCpltCallback
69 (+) At reception end of transfer HAL_USART_RxCpltCallback is executed and user can
70 add his own code by customization of function pointer HAL_USART_RxCpltCallback
71 (+) In case of transfer Error, HAL_USART_ErrorCallback() function is executed and user can
72 add his own code by customization of function pointer HAL_USART_ErrorCallback
73
74 *** DMA mode IO operation ***
75 ==============================
76 [..]
77 (+) Send an amount of data in non blocking mode (DMA) using HAL_USART_Transmit_DMA()
78 (+) At transmission end of half transfer HAL_USART_TxHalfCpltCallback is executed and user can
79 add his own code by customization of function pointer HAL_USART_TxHalfCpltCallback
80 (+) At transmission end of transfer HAL_USART_TxCpltCallback is executed and user can
81 add his own code by customization of function pointer HAL_USART_TxCpltCallback
82 (+) Receive an amount of data in non blocking mode (DMA) using HAL_USART_Receive_DMA()
83 (+) At reception end of half transfer HAL_USART_RxHalfCpltCallback is executed and user can
84 add his own code by customization of function pointer HAL_USART_RxHalfCpltCallback
85 (+) At reception end of transfer HAL_USART_RxCpltCallback is executed and user can
86 add his own code by customization of function pointer HAL_USART_RxCpltCallback
87 (+) In case of transfer Error, HAL_USART_ErrorCallback() function is executed and user can
88 add his own code by customization of function pointer HAL_USART_ErrorCallback
89 (+) Pause the DMA Transfer using HAL_USART_DMAPause()
90 (+) Resume the DMA Transfer using HAL_USART_DMAResume()
91 (+) Stop the DMA Transfer using HAL_USART_DMAStop()
92
93 *** USART HAL driver macros list ***
94 =============================================
95 [..]
96 Below the list of most used macros in USART HAL driver.
97
98 (+) __HAL_USART_ENABLE: Enable the USART peripheral
99 (+) __HAL_USART_DISABLE: Disable the USART peripheral
100 (+) __HAL_USART_GET_FLAG : Check whether the specified USART flag is set or not
101 (+) __HAL_USART_CLEAR_FLAG : Clear the specified USART pending flag
102 (+) __HAL_USART_ENABLE_IT: Enable the specified USART interrupt
103 (+) __HAL_USART_DISABLE_IT: Disable the specified USART interrupt
104
105 [..]
106 (@) You can refer to the USART HAL driver header file for more useful macros
107
108 @endverbatim
109 ******************************************************************************
110 * @attention
111 *
112 * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
113 *
114 * Redistribution and use in source and binary forms, with or without modification,
115 * are permitted provided that the following conditions are met:
116 * 1. Redistributions of source code must retain the above copyright notice,
117 * this list of conditions and the following disclaimer.
118 * 2. Redistributions in binary form must reproduce the above copyright notice,
119 * this list of conditions and the following disclaimer in the documentation
120 * and/or other materials provided with the distribution.
121 * 3. Neither the name of STMicroelectronics nor the names of its contributors
122 * may be used to endorse or promote products derived from this software
123 * without specific prior written permission.
124 *
125 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
126 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
127 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
129 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
130 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
131 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
132 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
133 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
134 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
135 *
136 ******************************************************************************
137 */
138
139 /* Includes ------------------------------------------------------------------*/
140 #include "stm32f4xx_hal.h"
141
142 /** @addtogroup STM32F4xx_HAL_Driver
143 * @{
144 */
145
146 /** @defgroup USART
147 * @brief HAL USART Synchronous module driver
148 * @{
149 */
150 #ifdef HAL_USART_MODULE_ENABLED
151 /* Private typedef -----------------------------------------------------------*/
152 /* Private define ------------------------------------------------------------*/
153 #define DUMMY_DATA 0xFFFF
154 #define USART_TIMEOUT_VALUE 22000
155 /* Private macro -------------------------------------------------------------*/
156 /* Private variables ---------------------------------------------------------*/
157 /* Private function prototypes -----------------------------------------------*/
158 static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart);
159 static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart);
160 static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart);
161 static void USART_SetConfig (USART_HandleTypeDef *husart);
162 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
163 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
164 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
165 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
166 static void USART_DMAError(DMA_HandleTypeDef *hdma);
167 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
168 /* Private functions ---------------------------------------------------------*/
169
170
171 /** @defgroup USART_Private_Functions
172 * @{
173 */
174
175 /** @defgroup USART_Group1 USART Initialization and de-initialization functions
176 * @brief Initialization and Configuration functions
177 *
178 @verbatim
179 ==============================================================================
180 ##### Initialization and Configuration functions #####
181 ==============================================================================
182 [..]
183 This subsection provides a set of functions allowing to initialize the USART
184 in asynchronous and in synchronous modes.
185 (+) For the asynchronous mode only these parameters can be configured:
186 (++) Baud Rate
187 (++) Word Length
188 (++) Stop Bit
189 (++) Parity: If the parity is enabled, then the MSB bit of the data written
190 in the data register is transmitted but is changed by the parity bit.
191 Depending on the frame length defined by the M bit (8-bits or 9-bits),
192 please refer to Reference manual for possible USART frame formats.
193 (++) USART polarity
194 (++) USART phase
195 (++) USART LastBit
196 (++) Receiver/transmitter modes
197
198 [..]
199 The HAL_USART_Init() function follows the USART synchronous configuration
200 procedure (details for the procedure are available in reference manual (RM0329)).
201
202 @endverbatim
203 * @{
204 */
205
206 /**
207 * @brief Initializes the USART mode according to the specified
208 * parameters in the USART_InitTypeDef and create the associated handle.
209 * @param husart: pointer to a USART_HandleTypeDef structure that contains
210 * the configuration information for the specified USART module.
211 * @retval HAL status
212 */
213 HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
214 {
215 /* Check the USART handle allocation */
216 if(husart == HAL_NULL)
217 {
218 return HAL_ERROR;
219 }
220
221 /* Check the parameters */
222 assert_param(IS_USART_INSTANCE(husart->Instance));
223
224 if(husart->State == HAL_USART_STATE_RESET)
225 {
226 /* Init the low level hardware */
227 HAL_USART_MspInit(husart);
228 }
229
230 husart->State = HAL_USART_STATE_BUSY;
231
232 /* Set the USART Communication parameters */
233 USART_SetConfig(husart);
234
235 /* In USART mode, the following bits must be kept cleared:
236 - LINEN bit in the USART_CR2 register
237 - HDSEL, SCEN and IREN bits in the USART_CR3 register */
238 husart->Instance->CR2 &= ~USART_CR2_LINEN;
239 husart->Instance->CR3 &= ~(USART_CR3_IREN | USART_CR3_SCEN | USART_CR3_HDSEL);
240
241 /* Enable the Peripheral */
242 __USART_ENABLE(husart);
243
244 /* Initialize the USART state */
245 husart->ErrorCode = HAL_USART_ERROR_NONE;
246 husart->State= HAL_USART_STATE_READY;
247
248 return HAL_OK;
249 }
250
251 /**
252 * @brief DeInitializes the USART peripheral.
253 * @param husart: pointer to a USART_HandleTypeDef structure that contains
254 * the configuration information for the specified USART module.
255 * @retval HAL status
256 */
257 HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart)
258 {
259 /* Check the USART handle allocation */
260 if(husart == HAL_NULL)
261 {
262 return HAL_ERROR;
263 }
264
265 /* Check the parameters */
266 assert_param(IS_USART_INSTANCE(husart->Instance));
267
268 husart->State = HAL_USART_STATE_BUSY;
269
270 /* DeInit the low level hardware */
271 HAL_USART_MspDeInit(husart);
272
273 husart->ErrorCode = HAL_USART_ERROR_NONE;
274 husart->State = HAL_USART_STATE_RESET;
275
276 /* Release Lock */
277 __HAL_UNLOCK(husart);
278
279 return HAL_OK;
280 }
281
282 /**
283 * @brief USART MSP Init.
284 * @param husart: pointer to a USART_HandleTypeDef structure that contains
285 * the configuration information for the specified USART module.
286 * @retval None
287 */
288 __weak void HAL_USART_MspInit(USART_HandleTypeDef *husart)
289 {
290 /* NOTE: This function Should not be modified, when the callback is needed,
291 the HAL_USART_MspInit could be implenetd in the user file
292 */
293 }
294
295 /**
296 * @brief USART MSP DeInit.
297 * @param husart: pointer to a USART_HandleTypeDef structure that contains
298 * the configuration information for the specified USART module.
299 * @retval None
300 */
301 __weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart)
302 {
303 /* NOTE: This function Should not be modified, when the callback is needed,
304 the HAL_USART_MspDeInit could be implenetd in the user file
305 */
306 }
307
308 /**
309 * @}
310 */
311
312 /** @defgroup USART_Group2 IO operation functions
313 * @brief USART Transmit and Receive functions
314 *
315 @verbatim
316 ==============================================================================
317 ##### IO operation functions #####
318 ==============================================================================
319 [..]
320 This subsection provides a set of functions allowing to manage the USART synchronous
321 data transfers.
322
323 [..]
324 The USART supports master mode only: it cannot receive or send data related to an input
325 clock (SCLK is always an output).
326
327 (#) There are two modes of transfer:
328 (++) Blocking mode: The communication is performed in polling mode.
329 The HAL status of all data processing is returned by the same function
330 after finishing transfer.
331 (++) No-Blocking mode: The communication is performed using Interrupts
332 or DMA, These API's return the HAL status.
333 The end of the data processing will be indicated through the
334 dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
335 using DMA mode.
336 The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback()
337 user callbacks
338 will be executed respectivelly at the end of the transmit or Receive process
339 The HAL_USART_ErrorCallback() user callback will be executed when a communication
340 error is detected
341
342 (#) Blocking mode APIs are :
343 (++) HAL_USART_Transmit() in simplex mode
344 (++) HAL_USART_Receive() in full duplex receive only
345 (++) HAL_USART_TransmitReceive() in full duplex mode
346
347 (#) Non Blocking mode APIs with Interrupt are :
348 (++) HAL_USART_Transmit_IT()in simplex mode
349 (++) HAL_USART_Receive_IT() in full duplex receive only
350 (++) HAL_USART_TransmitReceive_IT() in full duplex mode
351 (++) HAL_USART_IRQHandler()
352
353 (#) Non Blocking mode functions with DMA are :
354 (++) HAL_USART_Transmit_DMA()in simplex mode
355 (++) HAL_USART_Receive_DMA() in full duplex receive only
356 (++) HAL_USART_TransmitReceie_DMA() in full duplex mode
357
358 (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
359 (++) HAL_USART_TxCpltCallback()
360 (++) HAL_USART_RxCpltCallback()
361 (++) HAL_USART_ErrorCallback()
362 (++) HAL_USART_TxRxCpltCallback()
363
364 @endverbatim
365 * @{
366 */
367
368 /**
369 * @brief Simplex Send an amount of data in blocking mode.
370 * @param husart: pointer to a USART_HandleTypeDef structure that contains
371 * the configuration information for the specified USART module.
372 * @param pTxData: Pointer to data buffer
373 * @param Size: Amount of data to be sent
374 * @param Timeout: Timeout duration
375 * @retval HAL status
376 */
377 HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout)
378 {
379 uint16_t* tmp;
380
381 if(husart->State == HAL_USART_STATE_READY)
382 {
383 if((pTxData == HAL_NULL) || (Size == 0))
384 {
385 return HAL_ERROR;
386 }
387
388 /* Process Locked */
389 __HAL_LOCK(husart);
390
391 husart->ErrorCode = HAL_USART_ERROR_NONE;
392 husart->State = HAL_USART_STATE_BUSY_TX;
393
394 husart->TxXferSize = Size;
395 husart->TxXferCount = Size;
396 while(husart->TxXferCount > 0)
397 {
398 husart->TxXferCount--;
399 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
400 {
401 /* Wait for TC flag in order to write data in DR */
402 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK)
403 {
404 return HAL_TIMEOUT;
405 }
406 tmp = (uint16_t*) pTxData;
407 husart->Instance->DR = (*tmp & (uint16_t)0x01FF);
408 if(husart->Init.Parity == USART_PARITY_NONE)
409 {
410 pTxData += 2;
411 }
412 else
413 {
414 pTxData += 1;
415 }
416 }
417 else
418 {
419 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK)
420 {
421 return HAL_TIMEOUT;
422 }
423 husart->Instance->DR = (*pTxData++ & (uint8_t)0xFF);
424 }
425 }
426
427 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK)
428 {
429 return HAL_TIMEOUT;
430 }
431
432 husart->State = HAL_USART_STATE_READY;
433
434 /* Process Unlocked */
435 __HAL_UNLOCK(husart);
436
437 return HAL_OK;
438 }
439 else
440 {
441 return HAL_BUSY;
442 }
443 }
444
445 /**
446 * @brief Full-Duplex Receive an amount of data in blocking mode.
447 * @param husart: pointer to a USART_HandleTypeDef structure that contains
448 * the configuration information for the specified USART module.
449 * @param pRxData: Pointer to data buffer
450 * @param Size: Amount of data to be received
451 * @param Timeout: Timeout duration
452 * @retval HAL status
453 */
454 HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
455 {
456 uint16_t* tmp;
457
458 if(husart->State == HAL_USART_STATE_READY)
459 {
460 if((pRxData == HAL_NULL) || (Size == 0))
461 {
462 return HAL_ERROR;
463 }
464 /* Process Locked */
465 __HAL_LOCK(husart);
466
467 husart->ErrorCode = HAL_USART_ERROR_NONE;
468 husart->State = HAL_USART_STATE_BUSY_RX;
469
470 husart->RxXferSize = Size;
471 husart->RxXferCount = Size;
472 /* Check the remain data to be received */
473 while(husart->RxXferCount > 0)
474 {
475 husart->RxXferCount--;
476 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
477 {
478 /* Wait until TXE flag is set to send dummy byte in order to generate the clock for the slave to send data */
479 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK)
480 {
481 return HAL_TIMEOUT;
482 }
483 /* Send dummy byte in order to generate clock */
484 husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x01FF);
485
486 /* Wait for RXNE Flag */
487 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
488 {
489 return HAL_TIMEOUT;
490 }
491 tmp = (uint16_t*) pRxData ;
492 if(husart->Init.Parity == USART_PARITY_NONE)
493 {
494 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
495 pRxData +=2;
496 }
497 else
498 {
499 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
500 pRxData +=1;
501 }
502 }
503 else
504 {
505 /* Wait until TXE flag is set to send dummy byte in order to generate the clock for the slave to send data */
506 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK)
507 {
508 return HAL_TIMEOUT;
509 }
510
511 /* Send Dummy Byte in order to generate clock */
512 husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x00FF);
513
514 /* Wait until RXNE flag is set to receive the byte */
515 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
516 {
517 return HAL_TIMEOUT;
518 }
519 if(husart->Init.Parity == USART_PARITY_NONE)
520 {
521 /* Receive data */
522 *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
523 }
524 else
525 {
526 /* Receive data */
527 *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
528 }
529
530 }
531 }
532
533 husart->State = HAL_USART_STATE_READY;
534
535 /* Process Unlocked */
536 __HAL_UNLOCK(husart);
537
538 return HAL_OK;
539 }
540 else
541 {
542 return HAL_BUSY;
543 }
544 }
545
546 /**
547 * @brief Full-Duplex Send receive an amount of data in full-duplex mode (blocking mode).
548 * @param husart: pointer to a USART_HandleTypeDef structure that contains
549 * the configuration information for the specified USART module.
550 * @param pTxData: Pointer to data transmitted buffer
551 * @param pRxData: Pointer to data received buffer
552 * @param Size: Amount of data to be sent
553 * @param Timeout: Timeout duration
554 * @retval HAL status
555 */
556 HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
557 {
558 uint16_t* tmp;
559
560 if(husart->State == HAL_USART_STATE_READY)
561 {
562 if((pTxData == HAL_NULL) || (pRxData == HAL_NULL) || (Size == 0))
563 {
564 return HAL_ERROR;
565 }
566 /* Process Locked */
567 __HAL_LOCK(husart);
568
569 husart->ErrorCode = HAL_USART_ERROR_NONE;
570 husart->State = HAL_USART_STATE_BUSY_RX;
571
572 husart->RxXferSize = Size;
573 husart->TxXferSize = Size;
574 husart->TxXferCount = Size;
575 husart->RxXferCount = Size;
576
577 /* Check the remain data to be received */
578 while(husart->TxXferCount > 0)
579 {
580 husart->TxXferCount--;
581 husart->RxXferCount--;
582 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
583 {
584 /* Wait for TC flag in order to write data in DR */
585 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK)
586 {
587 return HAL_TIMEOUT;
588 }
589 tmp = (uint16_t*) pTxData;
590 husart->Instance->DR = (*tmp & (uint16_t)0x01FF);
591 if(husart->Init.Parity == USART_PARITY_NONE)
592 {
593 pTxData += 2;
594 }
595 else
596 {
597 pTxData += 1;
598 }
599
600 /* Wait for RXNE Flag */
601 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
602 {
603 return HAL_TIMEOUT;
604 }
605 tmp = (uint16_t*) pRxData ;
606 if(husart->Init.Parity == USART_PARITY_NONE)
607 {
608 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
609 pRxData += 2;
610 }
611 else
612 {
613 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
614 pRxData += 1;
615 }
616 }
617 else
618 {
619 /* Wait for TC flag in order to write data in DR */
620 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK)
621 {
622 return HAL_TIMEOUT;
623 }
624 husart->Instance->DR = (*pTxData++ & (uint8_t)0x00FF);
625
626 /* Wait for RXNE Flag */
627 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
628 {
629 return HAL_TIMEOUT;
630 }
631 if(husart->Init.Parity == USART_PARITY_NONE)
632 {
633 /* Receive data */
634 *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
635 }
636 else
637 {
638 /* Receive data */
639 *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
640 }
641 }
642 }
643
644 husart->State = HAL_USART_STATE_READY;
645
646 /* Process Unlocked */
647 __HAL_UNLOCK(husart);
648
649 return HAL_OK;
650 }
651 else
652 {
653 return HAL_BUSY;
654 }
655 }
656
657 /**
658 * @brief Simplex Send an amount of data in non-blocking mode.
659 * @param husart: pointer to a USART_HandleTypeDef structure that contains
660 * the configuration information for the specified USART module.
661 * @param pTxData: Pointer to data buffer
662 * @param Size: Amount of data to be sent
663 * @retval HAL status
664 * @note The USART errors are not managed to avoid the overrun error.
665 */
666 HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
667 {
668 if(husart->State == HAL_USART_STATE_READY)
669 {
670 if((pTxData == HAL_NULL) || (Size == 0))
671 {
672 return HAL_ERROR;
673 }
674
675 /* Process Locked */
676 __HAL_LOCK(husart);
677
678 husart->pTxBuffPtr = pTxData;
679 husart->TxXferSize = Size;
680 husart->TxXferCount = Size;
681
682 husart->ErrorCode = HAL_USART_ERROR_NONE;
683 husart->State = HAL_USART_STATE_BUSY_TX;
684
685 /* The USART Error Interrupts: (Frame error, Noise error, Overrun error)
686 are not managed by the USART transmit process to avoid the overrun interrupt
687 when the USART mode is configured for transmit and receive "USART_MODE_TX_RX"
688 to benefit for the frame error and noise interrupts the USART mode should be
689 configured only for transmit "USART_MODE_TX"
690 The __USART_ENABLE_IT(husart, USART_IT_ERR) can be used to enable the Frame error,
691 Noise error interrupt */
692
693 /* Process Unlocked */
694 __HAL_UNLOCK(husart);
695
696 /* Enable the USART Transmit Data Register Empty Interrupt */
697 __USART_ENABLE_IT(husart, USART_IT_TXE);
698
699 return HAL_OK;
700 }
701 else
702 {
703 return HAL_BUSY;
704 }
705 }
706
707 /**
708 * @brief Simplex Receive an amount of data in non-blocking mode.
709 * @param husart: pointer to a USART_HandleTypeDef structure that contains
710 * the configuration information for the specified USART module.
711 * @param pRxData: Pointer to data buffer
712 * @param Size: Amount of data to be received
713 * @retval HAL status
714 */
715 HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
716 {
717 if(husart->State == HAL_USART_STATE_READY)
718 {
719 if((pRxData == HAL_NULL) || (Size == 0))
720 {
721 return HAL_ERROR;
722 }
723 /* Process Locked */
724 __HAL_LOCK(husart);
725
726 husart->pRxBuffPtr = pRxData;
727 husart->RxXferSize = Size;
728 husart->RxXferCount = Size;
729
730 husart->ErrorCode = HAL_USART_ERROR_NONE;
731 husart->State = HAL_USART_STATE_BUSY_RX;
732
733 /* Enable the USART Data Register not empty Interrupt */
734 __USART_ENABLE_IT(husart, USART_IT_RXNE);
735
736 /* Enable the USART Parity Error Interrupt */
737 __USART_ENABLE_IT(husart, USART_IT_PE);
738
739 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
740 __USART_ENABLE_IT(husart, USART_IT_ERR);
741
742 /* Process Unlocked */
743 __HAL_UNLOCK(husart);
744
745 /* Send dummy byte in order to generate the clock for the slave to send data */
746 husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x01FF);
747
748 return HAL_OK;
749 }
750 else
751 {
752 return HAL_BUSY;
753 }
754 }
755
756 /**
757 * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking).
758 * @param husart: pointer to a USART_HandleTypeDef structure that contains
759 * the configuration information for the specified USART module.
760 * @param pTxData: Pointer to data transmitted buffer
761 * @param pRxData: Pointer to data received buffer
762 * @param Size: Amount of data to be received
763 * @retval HAL status
764 */
765 HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
766 {
767 if(husart->State == HAL_USART_STATE_READY)
768 {
769 if((pTxData == HAL_NULL) || (pRxData == HAL_NULL) || (Size == 0))
770 {
771 return HAL_ERROR;
772 }
773 /* Process Locked */
774 __HAL_LOCK(husart);
775
776 husart->pRxBuffPtr = pRxData;
777 husart->RxXferSize = Size;
778 husart->RxXferCount = Size;
779 husart->pTxBuffPtr = pTxData;
780 husart->TxXferSize = Size;
781 husart->TxXferCount = Size;
782
783 husart->ErrorCode = HAL_USART_ERROR_NONE;
784 husart->State = HAL_USART_STATE_BUSY_TX_RX;
785
786 /* Enable the USART Data Register not empty Interrupt */
787 __USART_ENABLE_IT(husart, USART_IT_RXNE);
788
789 /* Enable the USART Parity Error Interrupt */
790 __USART_ENABLE_IT(husart, USART_IT_PE);
791
792 /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
793 __USART_ENABLE_IT(husart, USART_IT_ERR);
794
795 /* Process Unlocked */
796 __HAL_UNLOCK(husart);
797
798 /* Enable the USART Transmit Data Register Empty Interrupt */
799 __USART_ENABLE_IT(husart, USART_IT_TXE);
800
801 return HAL_OK;
802 }
803 else
804 {
805 return HAL_BUSY;
806 }
807 }
808
809 /**
810 * @brief Simplex Send an amount of data in non-blocking mode.
811 * @param husart: pointer to a USART_HandleTypeDef structure that contains
812 * the configuration information for the specified USART module.
813 * @param pTxData: Pointer to data buffer
814 * @param Size: Amount of data to be sent
815 * @retval HAL status
816 */
817 HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
818 {
819 uint32_t *tmp;
820
821 if(husart->State == HAL_USART_STATE_READY)
822 {
823 if((pTxData == HAL_NULL) || (Size == 0))
824 {
825 return HAL_ERROR;
826 }
827 /* Process Locked */
828 __HAL_LOCK(husart);
829
830 husart->pTxBuffPtr = pTxData;
831 husart->TxXferSize = Size;
832 husart->TxXferCount = Size;
833
834 husart->ErrorCode = HAL_USART_ERROR_NONE;
835 husart->State = HAL_USART_STATE_BUSY_TX;
836
837 /* Set the USART DMA transfer complete callback */
838 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
839
840 /* Set the USART DMA Half transfer complete callback */
841 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
842
843 /* Set the DMA error callback */
844 husart->hdmatx->XferErrorCallback = USART_DMAError;
845
846 /* Enable the USART transmit DMA Stream */
847 tmp = (uint32_t*)&pTxData;
848 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->DR, Size);
849
850 /* Enable the DMA transfer for transmit request by setting the DMAT bit
851 in the USART CR3 register */
852 husart->Instance->CR3 |= USART_CR3_DMAT;
853
854 /* Process Unlocked */
855 __HAL_UNLOCK(husart);
856
857 return HAL_OK;
858 }
859 else
860 {
861 return HAL_BUSY;
862 }
863 }
864
865 /**
866 * @brief Full-Duplex Receive an amount of data in non-blocking mode.
867 * @param husart: pointer to a USART_HandleTypeDef structure that contains
868 * the configuration information for the specified USART module.
869 * @param pRxData: Pointer to data buffer
870 * @param Size: Amount of data to be received
871 * @retval HAL status
872 * @note The USART DMA transmit stream must be configured in order to generate the clock for the slave.
873 * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
874 */
875 HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
876 {
877 uint32_t *tmp;
878
879 if(husart->State == HAL_USART_STATE_READY)
880 {
881 if((pRxData == HAL_NULL) || (Size == 0))
882 {
883 return HAL_ERROR;
884 }
885
886 /* Process Locked */
887 __HAL_LOCK(husart);
888
889 husart->pRxBuffPtr = pRxData;
890 husart->RxXferSize = Size;
891 husart->pTxBuffPtr = pRxData;
892 husart->TxXferSize = Size;
893
894 husart->ErrorCode = HAL_USART_ERROR_NONE;
895 husart->State = HAL_USART_STATE_BUSY_RX;
896
897 /* Set the USART DMA Rx transfer complete callback */
898 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
899
900 /* Set the USART DMA Half transfer complete callback */
901 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
902
903 /* Set the USART DMA Rx transfer error callback */
904 husart->hdmarx->XferErrorCallback = USART_DMAError;
905
906 /* Enable the USART receive DMA Stream */
907 tmp = (uint32_t*)&pRxData;
908 HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->DR, *(uint32_t*)tmp, Size);
909
910 /* Enable the USART transmit DMA Stream: the transmit stream is used in order
911 to generate in the non-blocking mode the clock to the slave device,
912 this mode isn't a simplex receive mode but a full-duplex receive one */
913 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->DR, Size);
914
915 /* Clear the Overrun flag just before enabling the DMA Rx request: mandatory for the second transfer
916 when using the USART in circular mode */
917 __HAL_USART_CLEAR_OREFLAG(husart);
918
919 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
920 in the USART CR3 register */
921 husart->Instance->CR3 |= USART_CR3_DMAR;
922
923 /* Enable the DMA transfer for transmit request by setting the DMAT bit
924 in the USART CR3 register */
925 husart->Instance->CR3 |= USART_CR3_DMAT;
926
927 /* Process Unlocked */
928 __HAL_UNLOCK(husart);
929
930 return HAL_OK;
931 }
932 else
933 {
934 return HAL_BUSY;
935 }
936 }
937
938 /**
939 * @brief Full-Duplex Transmit Receive an amount of data in non-blocking mode.
940 * @param husart: pointer to a USART_HandleTypeDef structure that contains
941 * the configuration information for the specified USART module.
942 * @param pTxData: Pointer to data transmitted buffer
943 * @param pRxData: Pointer to data received buffer
944 * @param Size: Amount of data to be received
945 * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
946 * @retval HAL status
947 */
948 HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
949 {
950 uint32_t *tmp;
951
952 if(husart->State == HAL_USART_STATE_READY)
953 {
954 if((pTxData == HAL_NULL) || (pRxData == HAL_NULL) || (Size == 0))
955 {
956 return HAL_ERROR;
957 }
958 /* Process Locked */
959 __HAL_LOCK(husart);
960
961 husart->pRxBuffPtr = pRxData;
962 husart->RxXferSize = Size;
963 husart->pTxBuffPtr = pTxData;
964 husart->TxXferSize = Size;
965
966 husart->ErrorCode = HAL_USART_ERROR_NONE;
967 husart->State = HAL_USART_STATE_BUSY_TX_RX;
968
969 /* Set the USART DMA Rx transfer complete callback */
970 husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
971
972 /* Set the USART DMA Half transfer complete callback */
973 husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
974
975 /* Set the USART DMA Tx transfer complete callback */
976 husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
977
978 /* Set the USART DMA Half transfer complete callback */
979 husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
980
981 /* Set the USART DMA Tx transfer error callback */
982 husart->hdmatx->XferErrorCallback = USART_DMAError;
983
984 /* Set the USART DMA Rx transfer error callback */
985 husart->hdmarx->XferErrorCallback = USART_DMAError;
986
987 /* Enable the USART receive DMA Stream */
988 tmp = (uint32_t*)&pRxData;
989 HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->DR, *(uint32_t*)tmp, Size);
990
991 /* Enable the USART transmit DMA Stream */
992 tmp = (uint32_t*)&pTxData;
993 HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->DR, Size);
994
995 /* Clear the Overrun flag: mandatory for the second transfer in circular mode */
996 __HAL_USART_CLEAR_OREFLAG(husart);
997
998 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
999 in the USART CR3 register */
1000 husart->Instance->CR3 |= USART_CR3_DMAR;
1001
1002 /* Enable the DMA transfer for transmit request by setting the DMAT bit
1003 in the USART CR3 register */
1004 husart->Instance->CR3 |= USART_CR3_DMAT;
1005
1006 /* Process Unlocked */
1007 __HAL_UNLOCK(husart);
1008
1009 return HAL_OK;
1010 }
1011 else
1012 {
1013 return HAL_BUSY;
1014 }
1015 }
1016
1017 /**
1018 * @brief Pauses the DMA Transfer.
1019 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1020 * the configuration information for the specified USART module.
1021 * @retval HAL status
1022 */
1023 HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart)
1024 {
1025 /* Process Locked */
1026 __HAL_LOCK(husart);
1027
1028 /* Disable the USART DMA Tx request */
1029 husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT);
1030
1031 /* Process Unlocked */
1032 __HAL_UNLOCK(husart);
1033
1034 return HAL_OK;
1035 }
1036
1037 /**
1038 * @brief Resumes the DMA Transfer.
1039 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1040 * the configuration information for the specified USART module.
1041 * @retval HAL status
1042 */
1043 HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart)
1044 {
1045 /* Process Locked */
1046 __HAL_LOCK(husart);
1047
1048 /* Enable the USART DMA Tx request */
1049 husart->Instance->CR3 |= USART_CR3_DMAT;
1050
1051 /* Process Unlocked */
1052 __HAL_UNLOCK(husart);
1053
1054 return HAL_OK;
1055 }
1056
1057 /**
1058 * @brief Stops the DMA Transfer.
1059 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1060 * the configuration information for the specified USART module.
1061 * @retval HAL status
1062 */
1063 HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart)
1064 {
1065 /* The Lock is not implemented on this API to allow the user application
1066 to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback():
1067 when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
1068 and the correspond call back is executed HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback()
1069 */
1070
1071 /* Abort the USART DMA Tx Stream */
1072 if(husart->hdmatx != HAL_NULL)
1073 {
1074 HAL_DMA_Abort(husart->hdmatx);
1075 }
1076 /* Abort the USART DMA Rx Stream */
1077 if(husart->hdmarx != HAL_NULL)
1078 {
1079 HAL_DMA_Abort(husart->hdmarx);
1080 }
1081
1082 /* Disable the USART Tx/Rx DMA requests */
1083 husart->Instance->CR3 &= ~USART_CR3_DMAT;
1084 husart->Instance->CR3 &= ~USART_CR3_DMAR;
1085
1086 husart->State = HAL_USART_STATE_READY;
1087
1088 return HAL_OK;
1089 }
1090
1091 /**
1092 * @brief This function handles USART interrupt request.
1093 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1094 * the configuration information for the specified USART module.
1095 * @retval None
1096 */
1097 void HAL_USART_IRQHandler(USART_HandleTypeDef *husart)
1098 {
1099 uint32_t tmp1 = 0, tmp2 = 0;
1100
1101 tmp1 = __HAL_USART_GET_FLAG(husart, USART_FLAG_PE);
1102 tmp2 = __HAL_USART_GET_IT_SOURCE(husart, USART_IT_PE);
1103 /* USART parity error interrupt occurred -----------------------------------*/
1104 if((tmp1 != RESET) && (tmp2 != RESET))
1105 {
1106 __HAL_USART_CLEAR_PEFLAG(husart);
1107 husart->ErrorCode |= HAL_USART_ERROR_PE;
1108 }
1109
1110 tmp1 = __HAL_USART_GET_FLAG(husart, USART_FLAG_FE);
1111 tmp2 = __HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR);
1112 /* USART frame error interrupt occurred ------------------------------------*/
1113 if((tmp1 != RESET) && (tmp2 != RESET))
1114 {
1115 __HAL_USART_CLEAR_FEFLAG(husart);
1116 husart->ErrorCode |= HAL_USART_ERROR_FE;
1117 }
1118
1119 tmp1 = __HAL_USART_GET_FLAG(husart, USART_FLAG_NE);
1120 tmp2 = __HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR);
1121 /* USART noise error interrupt occurred ------------------------------------*/
1122 if((tmp1 != RESET) && (tmp2 != RESET))
1123 {
1124 __HAL_USART_CLEAR_NEFLAG(husart);
1125 husart->ErrorCode |= HAL_USART_ERROR_NE;
1126 }
1127
1128 tmp1 = __HAL_USART_GET_FLAG(husart, USART_FLAG_ORE);
1129 tmp2 = __HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR);
1130 /* USART Over-Run interrupt occurred ---------------------------------------*/
1131 if((tmp1 != RESET) && (tmp2 != RESET))
1132 {
1133 __HAL_USART_CLEAR_OREFLAG(husart);
1134 husart->ErrorCode |= HAL_USART_ERROR_ORE;
1135 }
1136
1137 if(husart->ErrorCode != HAL_USART_ERROR_NONE)
1138 {
1139 /* Set the USART state ready to be able to start again the process */
1140 husart->State = HAL_USART_STATE_READY;
1141
1142 HAL_USART_ErrorCallback(husart);
1143 }
1144
1145 tmp1 = __HAL_USART_GET_FLAG(husart, USART_FLAG_RXNE);
1146 tmp2 = __HAL_USART_GET_IT_SOURCE(husart, USART_IT_RXNE);
1147 /* USART in mode Receiver --------------------------------------------------*/
1148 if((tmp1 != RESET) && (tmp2 != RESET))
1149 {
1150 if(husart->State == HAL_USART_STATE_BUSY_RX)
1151 {
1152 USART_Receive_IT(husart);
1153 }
1154 else
1155 {
1156 USART_TransmitReceive_IT(husart);
1157 }
1158 }
1159
1160 tmp1 = __HAL_USART_GET_FLAG(husart, USART_FLAG_TXE);
1161 tmp2 = __HAL_USART_GET_IT_SOURCE(husart, USART_IT_TXE);
1162 /* USART in mode Transmitter -----------------------------------------------*/
1163 if((tmp1 != RESET) && (tmp2 != RESET))
1164 {
1165 if(husart->State == HAL_USART_STATE_BUSY_TX)
1166 {
1167 USART_Transmit_IT(husart);
1168 }
1169 else
1170 {
1171 USART_TransmitReceive_IT(husart);
1172 }
1173 }
1174 }
1175
1176 /**
1177 * @brief Tx Transfer completed callbacks.
1178 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1179 * the configuration information for the specified USART module.
1180 * @retval None
1181 */
1182 __weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart)
1183 {
1184 /* NOTE: This function Should not be modified, when the callback is needed,
1185 the HAL_USART_TxCpltCallback could be implemented in the user file
1186 */
1187 }
1188
1189 /**
1190 * @brief Tx Half Transfer completed callbacks.
1191 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1192 * the configuration information for the specified USART module.
1193 * @retval None
1194 */
1195 __weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart)
1196 {
1197 /* NOTE: This function Should not be modified, when the callback is needed,
1198 the HAL_USART_TxCpltCallback could be implemented in the user file
1199 */
1200 }
1201
1202 /**
1203 * @brief Rx Transfer completed callbacks.
1204 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1205 * the configuration information for the specified USART module.
1206 * @retval None
1207 */
1208 __weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart)
1209 {
1210 /* NOTE: This function Should not be modified, when the callback is needed,
1211 the HAL_USART_TxCpltCallback could be implemented in the user file
1212 */
1213 }
1214
1215 /**
1216 * @brief Rx Half Transfer completed callbacks.
1217 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1218 * the configuration information for the specified USART module.
1219 * @retval None
1220 */
1221 __weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart)
1222 {
1223 /* NOTE: This function Should not be modified, when the callback is needed,
1224 the HAL_USART_TxCpltCallback could be implemented in the user file
1225 */
1226 }
1227
1228 /**
1229 * @brief Tx/Rx Transfers completed callback for the non-blocking process.
1230 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1231 * the configuration information for the specified USART module.
1232 * @retval None
1233 */
1234 __weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart)
1235 {
1236 /* NOTE: This function Should not be modified, when the callback is needed,
1237 the HAL_USART_TxCpltCallback could be implemented in the user file
1238 */
1239 }
1240
1241 /**
1242 * @brief USART error callbacks.
1243 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1244 * the configuration information for the specified USART module.
1245 * @retval None
1246 */
1247 __weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart)
1248 {
1249 /* NOTE: This function Should not be modified, when the callback is needed,
1250 the HAL_USART_ErrorCallback could be implemented in the user file
1251 */
1252 }
1253
1254 /**
1255 * @}
1256 */
1257
1258 /** @defgroup USART_Group3 Peripheral State and Errors functions
1259 * @brief USART State and Errors functions
1260 *
1261 @verbatim
1262 ==============================================================================
1263 ##### Peripheral State and Errors functions #####
1264 ==============================================================================
1265 [..]
1266 This subsection provides a set of functions allowing to return the State of
1267 USART communication
1268 process, return Peripheral Errors occurred during communication process
1269 (+) HAL_USART_GetState() API can be helpful to check in run-time the state
1270 of the USART peripheral.
1271 (+) HAL_USART_GetError() check in run-time errors that could be occurred during
1272 communication.
1273 @endverbatim
1274 * @{
1275 */
1276
1277 /**
1278 * @brief Returns the USART state.
1279 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1280 * the configuration information for the specified USART module.
1281 * @retval HAL state
1282 */
1283 HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart)
1284 {
1285 return husart->State;
1286 }
1287
1288 /**
1289 * @brief Return the USART error code
1290 * @param husart : pointer to a USART_HandleTypeDef structure that contains
1291 * the configuration information for the specified USART.
1292 * @retval USART Error Code
1293 */
1294 uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart)
1295 {
1296 return husart->ErrorCode;
1297 }
1298
1299 /**
1300 * @}
1301 */
1302
1303
1304 /**
1305 * @brief DMA USART transmit process complete callback.
1306 * @param hdma: DMA handle
1307 * @retval None
1308 */
1309 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1310 {
1311 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1312 /* DMA Normal mode */
1313 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
1314 {
1315 husart->TxXferCount = 0;
1316 if(husart->State == HAL_USART_STATE_BUSY_TX)
1317 {
1318 /* Wait for USART TC Flag */
1319 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, USART_TIMEOUT_VALUE) != HAL_OK)
1320 {
1321 /* Timeout occurred */
1322 husart->State = HAL_USART_STATE_TIMEOUT;
1323 HAL_USART_ErrorCallback(husart);
1324 }
1325 else
1326 {
1327 /* No Timeout */
1328 /* Disable the DMA transfer for transmit request by setting the DMAT bit
1329 in the USART CR3 register */
1330 husart->Instance->CR3 &= ~(USART_CR3_DMAT);
1331 husart->State= HAL_USART_STATE_READY;
1332 HAL_USART_TxCpltCallback(husart);
1333 }
1334 }
1335 }
1336 /* DMA Circular mode */
1337 else
1338 {
1339 if(husart->State == HAL_USART_STATE_BUSY_TX)
1340 {
1341 HAL_USART_TxCpltCallback(husart);
1342 }
1343 }
1344 }
1345
1346 /**
1347 * @brief DMA USART transmit process half complete callback
1348 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
1349 * the configuration information for the specified DMA module.
1350 * @retval None
1351 */
1352 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1353 {
1354 USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1355
1356 HAL_USART_TxHalfCpltCallback(husart);
1357 }
1358
1359 /**
1360 * @brief DMA USART receive process complete callback.
1361 * @param hdma: DMA handle
1362 * @retval None
1363 */
1364 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1365 {
1366 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1367 /* DMA Normal mode */
1368 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
1369 {
1370 husart->RxXferCount = 0;
1371 husart->State= HAL_USART_STATE_READY;
1372 if(husart->State == HAL_USART_STATE_BUSY_RX)
1373 {
1374 /* Disable the DMA transfer for the Transmit/receiver requests by setting the DMAT/DMAR bit
1375 in the USART CR3 register */
1376 husart->Instance->CR3 &= ~(USART_CR3_DMAR);
1377
1378 HAL_USART_RxCpltCallback(husart);
1379 }
1380 /* the usart state is HAL_USART_STATE_BUSY_TX_RX*/
1381 else
1382 {
1383 /* Disable the DMA transfer for the Transmit/receiver requests by setting the DMAT/DMAR bit
1384 in the USART CR3 register */
1385 husart->Instance->CR3 &= ~(USART_CR3_DMAR);
1386 husart->Instance->CR3 &= ~(USART_CR3_DMAT);
1387
1388 HAL_USART_TxRxCpltCallback(husart);
1389 }
1390 }
1391 /* DMA circular mode */
1392 else
1393 {
1394 if(husart->State == HAL_USART_STATE_BUSY_RX)
1395 {
1396 HAL_USART_RxCpltCallback(husart);
1397 }
1398 /* the usart state is HAL_USART_STATE_BUSY_TX_RX*/
1399 else
1400 {
1401 HAL_USART_TxRxCpltCallback(husart);
1402 }
1403 }
1404 }
1405
1406 /**
1407 * @brief DMA USART receive process half complete callback
1408 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
1409 * the configuration information for the specified DMA module.
1410 * @retval None
1411 */
1412 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1413 {
1414 USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1415
1416 HAL_USART_RxHalfCpltCallback(husart);
1417 }
1418
1419 /**
1420 * @brief DMA USART communication error callback.
1421 * @param hdma: DMA handle
1422 * @retval None
1423 */
1424 static void USART_DMAError(DMA_HandleTypeDef *hdma)
1425 {
1426 USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1427
1428 husart->RxXferCount = 0;
1429 husart->TxXferCount = 0;
1430 husart->ErrorCode |= HAL_USART_ERROR_DMA;
1431 husart->State= HAL_USART_STATE_READY;
1432
1433 HAL_USART_ErrorCallback(husart);
1434 }
1435
1436 /**
1437 * @brief This function handles USART Communication Timeout.
1438 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1439 * the configuration information for the specified USART module.
1440 * @param Flag: specifies the USART flag to check.
1441 * @param Status: The new Flag status (SET or RESET).
1442 * @param Timeout: Timeout duration
1443 * @retval HAL status
1444 */
1445 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
1446 {
1447 uint32_t tickstart = 0;
1448
1449 /* Get tick */
1450 tickstart = HAL_GetTick();
1451
1452 /* Wait until flag is set */
1453 if(Status == RESET)
1454 {
1455 while(__HAL_USART_GET_FLAG(husart, Flag) == RESET)
1456 {
1457 /* Check for the Timeout */
1458 if(Timeout != HAL_MAX_DELAY)
1459 {
1460 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1461 {
1462 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1463 __USART_DISABLE_IT(husart, USART_IT_TXE);
1464 __USART_DISABLE_IT(husart, USART_IT_RXNE);
1465 __USART_DISABLE_IT(husart, USART_IT_PE);
1466 __USART_DISABLE_IT(husart, USART_IT_ERR);
1467
1468 husart->State= HAL_USART_STATE_READY;
1469
1470 /* Process Unlocked */
1471 __HAL_UNLOCK(husart);
1472
1473 return HAL_TIMEOUT;
1474 }
1475 }
1476 }
1477 }
1478 else
1479 {
1480 while(__HAL_USART_GET_FLAG(husart, Flag) != RESET)
1481 {
1482 /* Check for the Timeout */
1483 if(Timeout != HAL_MAX_DELAY)
1484 {
1485 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1486 {
1487 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1488 __USART_DISABLE_IT(husart, USART_IT_TXE);
1489 __USART_DISABLE_IT(husart, USART_IT_RXNE);
1490 __USART_DISABLE_IT(husart, USART_IT_PE);
1491 __USART_DISABLE_IT(husart, USART_IT_ERR);
1492
1493 husart->State= HAL_USART_STATE_READY;
1494
1495 /* Process Unlocked */
1496 __HAL_UNLOCK(husart);
1497
1498 return HAL_TIMEOUT;
1499 }
1500 }
1501 }
1502 }
1503 return HAL_OK;
1504 }
1505
1506
1507 /**
1508 * @brief Simplex Send an amount of data in non-blocking mode.
1509 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1510 * the configuration information for the specified USART module.
1511 * @retval HAL status
1512 * @note The USART errors are not managed to avoid the overrun error.
1513 */
1514 static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart)
1515 {
1516 uint16_t* tmp;
1517
1518 if(husart->State == HAL_USART_STATE_BUSY_TX)
1519 {
1520 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
1521 {
1522 tmp = (uint16_t*) husart->pTxBuffPtr;
1523 husart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
1524 if(husart->Init.Parity == USART_PARITY_NONE)
1525 {
1526 husart->pTxBuffPtr += 2;
1527 }
1528 else
1529 {
1530 husart->pTxBuffPtr += 1;
1531 }
1532 }
1533 else
1534 {
1535 husart->Instance->DR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0x00FF);
1536 }
1537
1538 if(--husart->TxXferCount == 0)
1539 {
1540 /* Disable the USART Transmit data register empty Interrupt */
1541 __USART_DISABLE_IT(husart, USART_IT_TXE);
1542
1543 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1544 __USART_DISABLE_IT(husart, USART_IT_ERR);
1545
1546
1547 if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, USART_TIMEOUT_VALUE) != HAL_OK)
1548 {
1549 return HAL_TIMEOUT;
1550 }
1551 husart->State = HAL_USART_STATE_READY;
1552
1553 HAL_USART_TxCpltCallback(husart);
1554
1555 return HAL_OK;
1556 }
1557 return HAL_OK;
1558 }
1559 else
1560 {
1561 return HAL_BUSY;
1562 }
1563 }
1564
1565 /**
1566 * @brief Simplex Receive an amount of data in non-blocking mode.
1567 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1568 * the configuration information for the specified USART module.
1569 * @retval HAL status
1570 */
1571 static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart)
1572 {
1573 uint16_t* tmp;
1574 if(husart->State == HAL_USART_STATE_BUSY_RX)
1575 {
1576 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
1577 {
1578 tmp = (uint16_t*) husart->pRxBuffPtr;
1579 if(husart->Init.Parity == USART_PARITY_NONE)
1580 {
1581 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
1582 husart->pRxBuffPtr += 2;
1583 }
1584 else
1585 {
1586 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
1587 husart->pRxBuffPtr += 1;
1588 }
1589 if(--husart->RxXferCount != 0x00)
1590 {
1591 /* Send dummy byte in order to generate the clock for the slave to send the next data */
1592 husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x01FF);
1593 }
1594 }
1595 else
1596 {
1597 if(husart->Init.Parity == USART_PARITY_NONE)
1598 {
1599 *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
1600 }
1601 else
1602 {
1603 *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
1604 }
1605
1606 if(--husart->RxXferCount != 0x00)
1607 {
1608 /* Send dummy byte in order to generate the clock for the slave to send the next data */
1609 husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x00FF);
1610 }
1611 }
1612
1613 if(husart->RxXferCount == 0)
1614 {
1615 /* Disable the USART RXNE Interrupt */
1616 __USART_DISABLE_IT(husart, USART_IT_RXNE);
1617
1618 /* Disable the USART Parity Error Interrupt */
1619 __USART_DISABLE_IT(husart, USART_IT_PE);
1620
1621 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1622 __USART_DISABLE_IT(husart, USART_IT_ERR);
1623
1624 husart->State = HAL_USART_STATE_READY;
1625 HAL_USART_RxCpltCallback(husart);
1626
1627 return HAL_OK;
1628 }
1629 return HAL_OK;
1630 }
1631 else
1632 {
1633 return HAL_BUSY;
1634 }
1635 }
1636
1637 /**
1638 * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking).
1639 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1640 * the configuration information for the specified USART module.
1641 * @retval HAL status
1642 */
1643 static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart)
1644 {
1645 uint16_t* tmp;
1646
1647 if(husart->State == HAL_USART_STATE_BUSY_TX_RX)
1648 {
1649 if(husart->TxXferCount != 0x00)
1650 {
1651 if(__HAL_USART_GET_FLAG(husart, USART_FLAG_TXE) != RESET)
1652 {
1653 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
1654 {
1655 tmp = (uint16_t*) husart->pTxBuffPtr;
1656 husart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
1657 if(husart->Init.Parity == USART_PARITY_NONE)
1658 {
1659 husart->pTxBuffPtr += 2;
1660 }
1661 else
1662 {
1663 husart->pTxBuffPtr += 1;
1664 }
1665 }
1666 else
1667 {
1668 husart->Instance->DR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0x00FF);
1669 }
1670 husart->TxXferCount--;
1671
1672 /* Check the latest data transmitted */
1673 if(husart->TxXferCount == 0)
1674 {
1675 __USART_DISABLE_IT(husart, USART_IT_TXE);
1676 }
1677 }
1678 }
1679
1680 if(husart->RxXferCount != 0x00)
1681 {
1682 if(__HAL_USART_GET_FLAG(husart, USART_FLAG_RXNE) != RESET)
1683 {
1684 if(husart->Init.WordLength == USART_WORDLENGTH_9B)
1685 {
1686 tmp = (uint16_t*) husart->pRxBuffPtr;
1687 if(husart->Init.Parity == USART_PARITY_NONE)
1688 {
1689 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
1690 husart->pRxBuffPtr += 2;
1691 }
1692 else
1693 {
1694 *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
1695 husart->pRxBuffPtr += 1;
1696 }
1697 }
1698 else
1699 {
1700 if(husart->Init.Parity == USART_PARITY_NONE)
1701 {
1702 *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
1703 }
1704 else
1705 {
1706 *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
1707 }
1708 }
1709 husart->RxXferCount--;
1710 }
1711 }
1712
1713 /* Check the latest data received */
1714 if(husart->RxXferCount == 0)
1715 {
1716 __USART_DISABLE_IT(husart, USART_IT_RXNE);
1717
1718 /* Disable the USART Parity Error Interrupt */
1719 __USART_DISABLE_IT(husart, USART_IT_PE);
1720
1721 /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1722 __USART_DISABLE_IT(husart, USART_IT_ERR);
1723
1724 husart->State = HAL_USART_STATE_READY;
1725
1726 HAL_USART_TxRxCpltCallback(husart);
1727
1728 return HAL_OK;
1729 }
1730
1731 return HAL_OK;
1732 }
1733 else
1734 {
1735 return HAL_BUSY;
1736 }
1737 }
1738
1739 /**
1740 * @brief Configures the USART peripheral.
1741 * @param husart: pointer to a USART_HandleTypeDef structure that contains
1742 * the configuration information for the specified USART module.
1743 * @retval None
1744 */
1745 static void USART_SetConfig(USART_HandleTypeDef *husart)
1746 {
1747 uint32_t tmpreg = 0x00;
1748
1749 /* Check the parameters */
1750 assert_param(IS_USART_INSTANCE(husart->Instance));
1751 assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity));
1752 assert_param(IS_USART_PHASE(husart->Init.CLKPhase));
1753 assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit));
1754 assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate));
1755 assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength));
1756 assert_param(IS_USART_STOPBITS(husart->Init.StopBits));
1757 assert_param(IS_USART_PARITY(husart->Init.Parity));
1758 assert_param(IS_USART_MODE(husart->Init.Mode));
1759
1760 /* The LBCL, CPOL and CPHA bits have to be selected when both the transmitter and the
1761 receiver are disabled (TE=RE=0) to ensure that the clock pulses function correctly. */
1762 husart->Instance->CR1 &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE));
1763
1764 /*---------------------------- USART CR2 Configuration ---------------------*/
1765 tmpreg = husart->Instance->CR2;
1766 /* Clear CLKEN, CPOL, CPHA and LBCL bits */
1767 tmpreg &= (uint32_t)~((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP));
1768 /* Configure the USART Clock, CPOL, CPHA and LastBit -----------------------*/
1769 /* Set CPOL bit according to husart->Init.CLKPolarity value */
1770 /* Set CPHA bit according to husart->Init.CLKPhase value */
1771 /* Set LBCL bit according to husart->Init.CLKLastBit value */
1772 /* Set Stop Bits: Set STOP[13:12] bits according to husart->Init.StopBits value */
1773 tmpreg |= (uint32_t)(USART_CLOCK_ENABLED| husart->Init.CLKPolarity |
1774 husart->Init.CLKPhase| husart->Init.CLKLastBit | husart->Init.StopBits);
1775 /* Write to USART CR2 */
1776 husart->Instance->CR2 = (uint32_t)tmpreg;
1777
1778 /*-------------------------- USART CR1 Configuration -----------------------*/
1779 tmpreg = husart->Instance->CR1;
1780
1781 /* Clear M, PCE, PS, TE and RE bits */
1782 tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | \
1783 USART_CR1_RE));
1784
1785 /* Configure the USART Word Length, Parity and mode:
1786 Set the M bits according to husart->Init.WordLength value
1787 Set PCE and PS bits according to husart->Init.Parity value
1788 Set TE and RE bits according to husart->Init.Mode value */
1789 tmpreg |= (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode;
1790
1791 /* Write to USART CR1 */
1792 husart->Instance->CR1 = (uint32_t)tmpreg;
1793
1794 /*-------------------------- USART CR3 Configuration -----------------------*/
1795 /* Clear CTSE and RTSE bits */
1796 husart->Instance->CR3 &= (uint32_t)~((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE));
1797
1798 /*-------------------------- USART BRR Configuration -----------------------*/
1799 if((husart->Instance == USART1) || (husart->Instance == USART6))
1800 {
1801 husart->Instance->BRR = __USART_BRR(HAL_RCC_GetPCLK2Freq(), husart->Init.BaudRate);
1802 }
1803 else
1804 {
1805 husart->Instance->BRR = __USART_BRR(HAL_RCC_GetPCLK1Freq(), husart->Init.BaudRate);
1806 }
1807 }
1808
1809 /**
1810 * @}
1811 */
1812
1813 #endif /* HAL_USART_MODULE_ENABLED */
1814 /**
1815 * @}
1816 */
1817
1818 /**
1819 * @}
1820 */
1821
1822 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Imprint / Impressum