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