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