Mercurial > public > ostc4
comparison Common/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c @ 128:c78bcbd5deda FlipDisplay
Added current STM32 standandard libraries in version independend folder structure
author | Ideenmodellierer |
---|---|
date | Sun, 17 Feb 2019 21:12:22 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
127:1369f8660eaa | 128:c78bcbd5deda |
---|---|
1 /** | |
2 ****************************************************************************** | |
3 * @file stm32f4xx_hal_uart.c | |
4 * @author MCD Application Team | |
5 * @brief UART HAL module driver. | |
6 * This file provides firmware functions to manage the following | |
7 * functionalities of the Universal Asynchronous Receiver Transmitter (UART) peripheral: | |
8 * + Initialization and de-initialization functions | |
9 * + IO operation functions | |
10 * + Peripheral Control functions | |
11 * + Peripheral State and Errors functions | |
12 * | |
13 @verbatim | |
14 ============================================================================== | |
15 ##### How to use this driver ##### | |
16 ============================================================================== | |
17 [..] | |
18 The UART HAL driver can be used as follows: | |
19 | |
20 (#) Declare a UART_HandleTypeDef handle structure. | |
21 | |
22 (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API: | |
23 (##) Enable the USARTx interface clock. | |
24 (##) UART pins configuration: | |
25 (+++) Enable the clock for the UART GPIOs. | |
26 (+++) Configure these UART pins as alternate function pull-up. | |
27 (##) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT() | |
28 and HAL_UART_Receive_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_UART_Transmit_DMA() | |
32 and HAL_UART_Receive_DMA() APIs): | |
33 (+++) Declare a DMA handle structure for the Tx/Rx stream. | |
34 (+++) Enable the DMAx interface clock. | |
35 (+++) Configure the declared DMA handle structure with the required | |
36 Tx/Rx parameters. | |
37 (+++) Configure the DMA Tx/Rx Stream. | |
38 (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle. | |
39 (+++) Configure the priority and enable the NVIC for the transfer complete | |
40 interrupt on the DMA Tx/Rx Stream. | |
41 | |
42 (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware | |
43 flow control and Mode(Receiver/Transmitter) in the Init structure. | |
44 | |
45 (#) For the UART asynchronous mode, initialize the UART registers by calling | |
46 the HAL_UART_Init() API. | |
47 | |
48 (#) For the UART Half duplex mode, initialize the UART registers by calling | |
49 the HAL_HalfDuplex_Init() API. | |
50 | |
51 (#) For the LIN mode, initialize the UART registers by calling the HAL_LIN_Init() API. | |
52 | |
53 (#) For the Multi-Processor mode, initialize the UART registers by calling | |
54 the HAL_MultiProcessor_Init() API. | |
55 | |
56 [..] | |
57 (@) The specific UART interrupts (Transmission complete interrupt, | |
58 RXNE interrupt and Error Interrupts) will be managed using the macros | |
59 __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the transmit | |
60 and receive process. | |
61 | |
62 [..] | |
63 (@) These APIs (HAL_UART_Init() and HAL_HalfDuplex_Init()) configure also the | |
64 low level Hardware GPIO, CLOCK, CORTEX...etc) by calling the customized | |
65 HAL_UART_MspInit() API. | |
66 | |
67 [..] | |
68 Three operation modes are available within this driver : | |
69 | |
70 *** Polling mode IO operation *** | |
71 ================================= | |
72 [..] | |
73 (+) Send an amount of data in blocking mode using HAL_UART_Transmit() | |
74 (+) Receive an amount of data in blocking mode using HAL_UART_Receive() | |
75 | |
76 *** Interrupt mode IO operation *** | |
77 =================================== | |
78 [..] | |
79 (+) Send an amount of data in non blocking mode using HAL_UART_Transmit_IT() | |
80 (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can | |
81 add his own code by customization of function pointer HAL_UART_TxCpltCallback | |
82 (+) Receive an amount of data in non blocking mode using HAL_UART_Receive_IT() | |
83 (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can | |
84 add his own code by customization of function pointer HAL_UART_RxCpltCallback | |
85 (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can | |
86 add his own code by customization of function pointer HAL_UART_ErrorCallback | |
87 | |
88 *** DMA mode IO operation *** | |
89 ============================== | |
90 [..] | |
91 (+) Send an amount of data in non blocking mode (DMA) using HAL_UART_Transmit_DMA() | |
92 (+) At transmission end of half transfer HAL_UART_TxHalfCpltCallback is executed and user can | |
93 add his own code by customization of function pointer HAL_UART_TxHalfCpltCallback | |
94 (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can | |
95 add his own code by customization of function pointer HAL_UART_TxCpltCallback | |
96 (+) Receive an amount of data in non blocking mode (DMA) using HAL_UART_Receive_DMA() | |
97 (+) At reception end of half transfer HAL_UART_RxHalfCpltCallback is executed and user can | |
98 add his own code by customization of function pointer HAL_UART_RxHalfCpltCallback | |
99 (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can | |
100 add his own code by customization of function pointer HAL_UART_RxCpltCallback | |
101 (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can | |
102 add his own code by customization of function pointer HAL_UART_ErrorCallback | |
103 (+) Pause the DMA Transfer using HAL_UART_DMAPause() | |
104 (+) Resume the DMA Transfer using HAL_UART_DMAResume() | |
105 (+) Stop the DMA Transfer using HAL_UART_DMAStop() | |
106 | |
107 *** UART HAL driver macros list *** | |
108 ============================================= | |
109 [..] | |
110 Below the list of most used macros in UART HAL driver. | |
111 | |
112 (+) __HAL_UART_ENABLE: Enable the UART peripheral | |
113 (+) __HAL_UART_DISABLE: Disable the UART peripheral | |
114 (+) __HAL_UART_GET_FLAG : Check whether the specified UART flag is set or not | |
115 (+) __HAL_UART_CLEAR_FLAG : Clear the specified UART pending flag | |
116 (+) __HAL_UART_ENABLE_IT: Enable the specified UART interrupt | |
117 (+) __HAL_UART_DISABLE_IT: Disable the specified UART interrupt | |
118 (+) __HAL_UART_GET_IT_SOURCE: Check whether the specified UART interrupt has occurred or not | |
119 | |
120 [..] | |
121 (@) You can refer to the UART HAL driver header file for more useful macros | |
122 | |
123 @endverbatim | |
124 ****************************************************************************** | |
125 * @attention | |
126 * | |
127 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> | |
128 * | |
129 * Redistribution and use in source and binary forms, with or without modification, | |
130 * are permitted provided that the following conditions are met: | |
131 * 1. Redistributions of source code must retain the above copyright notice, | |
132 * this list of conditions and the following disclaimer. | |
133 * 2. Redistributions in binary form must reproduce the above copyright notice, | |
134 * this list of conditions and the following disclaimer in the documentation | |
135 * and/or other materials provided with the distribution. | |
136 * 3. Neither the name of STMicroelectronics nor the names of its contributors | |
137 * may be used to endorse or promote products derived from this software | |
138 * without specific prior written permission. | |
139 * | |
140 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
141 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
142 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
143 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
144 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
145 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
146 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
147 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
148 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
149 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
150 * | |
151 ****************************************************************************** | |
152 */ | |
153 | |
154 /* Includes ------------------------------------------------------------------*/ | |
155 #include "stm32f4xx_hal.h" | |
156 | |
157 /** @addtogroup STM32F4xx_HAL_Driver | |
158 * @{ | |
159 */ | |
160 | |
161 /** @defgroup UART UART | |
162 * @brief HAL UART module driver | |
163 * @{ | |
164 */ | |
165 #ifdef HAL_UART_MODULE_ENABLED | |
166 | |
167 /* Private typedef -----------------------------------------------------------*/ | |
168 /* Private define ------------------------------------------------------------*/ | |
169 /** @addtogroup UART_Private_Constants | |
170 * @{ | |
171 */ | |
172 /** | |
173 * @} | |
174 */ | |
175 /* Private macro -------------------------------------------------------------*/ | |
176 /* Private variables ---------------------------------------------------------*/ | |
177 /* Private function prototypes -----------------------------------------------*/ | |
178 /** @addtogroup UART_Private_Functions UART Private Functions | |
179 * @{ | |
180 */ | |
181 static void UART_EndTxTransfer(UART_HandleTypeDef *huart); | |
182 static void UART_EndRxTransfer(UART_HandleTypeDef *huart); | |
183 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma); | |
184 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma); | |
185 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma); | |
186 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma); | |
187 static void UART_DMAError(DMA_HandleTypeDef *hdma); | |
188 static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma); | |
189 static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma); | |
190 static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma); | |
191 static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma); | |
192 static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma); | |
193 static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart); | |
194 static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart); | |
195 static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart); | |
196 static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout); | |
197 static void UART_SetConfig (UART_HandleTypeDef *huart); | |
198 /** | |
199 * @} | |
200 */ | |
201 | |
202 /* Exported functions ---------------------------------------------------------*/ | |
203 /** @defgroup UART_Exported_Functions UART Exported Functions | |
204 * @{ | |
205 */ | |
206 | |
207 /** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions | |
208 * @brief Initialization and Configuration functions | |
209 * | |
210 @verbatim | |
211 =============================================================================== | |
212 ##### Initialization and Configuration functions ##### | |
213 =============================================================================== | |
214 [..] | |
215 This subsection provides a set of functions allowing to initialize the USARTx or the UARTy | |
216 in asynchronous mode. | |
217 (+) For the asynchronous mode only these parameters can be configured: | |
218 (++) Baud Rate | |
219 (++) Word Length | |
220 (++) Stop Bit | |
221 (++) Parity: If the parity is enabled, then the MSB bit of the data written | |
222 in the data register is transmitted but is changed by the parity bit. | |
223 Depending on the frame length defined by the M bit (8-bits or 9-bits), | |
224 please refer to Reference manual for possible UART frame formats. | |
225 (++) Hardware flow control | |
226 (++) Receiver/transmitter modes | |
227 (++) Over Sampling Method | |
228 [..] | |
229 The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init() and HAL_MultiProcessor_Init() APIs | |
230 follow respectively the UART asynchronous, UART Half duplex, LIN and Multi-Processor | |
231 configuration procedures (details for the procedures are available in reference manual (RM0329)). | |
232 | |
233 @endverbatim | |
234 * @{ | |
235 */ | |
236 | |
237 /** | |
238 * @brief Initializes the UART mode according to the specified parameters in | |
239 * the UART_InitTypeDef and create the associated handle. | |
240 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
241 * the configuration information for the specified UART module. | |
242 * @retval HAL status | |
243 */ | |
244 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart) | |
245 { | |
246 /* Check the UART handle allocation */ | |
247 if(huart == NULL) | |
248 { | |
249 return HAL_ERROR; | |
250 } | |
251 | |
252 /* Check the parameters */ | |
253 if(huart->Init.HwFlowCtl != UART_HWCONTROL_NONE) | |
254 { | |
255 /* The hardware flow control is available only for USART1, USART2, USART3 and USART6 */ | |
256 assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance)); | |
257 assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl)); | |
258 } | |
259 else | |
260 { | |
261 assert_param(IS_UART_INSTANCE(huart->Instance)); | |
262 } | |
263 assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); | |
264 assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling)); | |
265 | |
266 if(huart->gState == HAL_UART_STATE_RESET) | |
267 { | |
268 /* Allocate lock resource and initialize it */ | |
269 huart->Lock = HAL_UNLOCKED; | |
270 /* Init the low level hardware */ | |
271 HAL_UART_MspInit(huart); | |
272 } | |
273 | |
274 huart->gState = HAL_UART_STATE_BUSY; | |
275 | |
276 /* Disable the peripheral */ | |
277 __HAL_UART_DISABLE(huart); | |
278 | |
279 /* Set the UART Communication parameters */ | |
280 UART_SetConfig(huart); | |
281 | |
282 /* In asynchronous mode, the following bits must be kept cleared: | |
283 - LINEN and CLKEN bits in the USART_CR2 register, | |
284 - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/ | |
285 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); | |
286 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN)); | |
287 | |
288 /* Enable the peripheral */ | |
289 __HAL_UART_ENABLE(huart); | |
290 | |
291 /* Initialize the UART state */ | |
292 huart->ErrorCode = HAL_UART_ERROR_NONE; | |
293 huart->gState= HAL_UART_STATE_READY; | |
294 huart->RxState= HAL_UART_STATE_READY; | |
295 | |
296 return HAL_OK; | |
297 } | |
298 | |
299 /** | |
300 * @brief Initializes the half-duplex mode according to the specified | |
301 * parameters in the UART_InitTypeDef and create the associated handle. | |
302 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
303 * the configuration information for the specified UART module. | |
304 * @retval HAL status | |
305 */ | |
306 HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart) | |
307 { | |
308 /* Check the UART handle allocation */ | |
309 if(huart == NULL) | |
310 { | |
311 return HAL_ERROR; | |
312 } | |
313 | |
314 /* Check the parameters */ | |
315 assert_param(IS_UART_INSTANCE(huart->Instance)); | |
316 assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); | |
317 assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling)); | |
318 | |
319 if(huart->gState == HAL_UART_STATE_RESET) | |
320 { | |
321 /* Allocate lock resource and initialize it */ | |
322 huart->Lock = HAL_UNLOCKED; | |
323 /* Init the low level hardware */ | |
324 HAL_UART_MspInit(huart); | |
325 } | |
326 | |
327 huart->gState = HAL_UART_STATE_BUSY; | |
328 | |
329 /* Disable the peripheral */ | |
330 __HAL_UART_DISABLE(huart); | |
331 | |
332 /* Set the UART Communication parameters */ | |
333 UART_SetConfig(huart); | |
334 | |
335 /* In half-duplex mode, the following bits must be kept cleared: | |
336 - LINEN and CLKEN bits in the USART_CR2 register, | |
337 - SCEN and IREN bits in the USART_CR3 register.*/ | |
338 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); | |
339 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN)); | |
340 | |
341 /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */ | |
342 SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL); | |
343 | |
344 /* Enable the peripheral */ | |
345 __HAL_UART_ENABLE(huart); | |
346 | |
347 /* Initialize the UART state*/ | |
348 huart->ErrorCode = HAL_UART_ERROR_NONE; | |
349 huart->gState= HAL_UART_STATE_READY; | |
350 huart->RxState= HAL_UART_STATE_READY; | |
351 | |
352 return HAL_OK; | |
353 } | |
354 | |
355 /** | |
356 * @brief Initializes the LIN mode according to the specified | |
357 * parameters in the UART_InitTypeDef and create the associated handle. | |
358 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
359 * the configuration information for the specified UART module. | |
360 * @param BreakDetectLength Specifies the LIN break detection length. | |
361 * This parameter can be one of the following values: | |
362 * @arg UART_LINBREAKDETECTLENGTH_10B: 10-bit break detection | |
363 * @arg UART_LINBREAKDETECTLENGTH_11B: 11-bit break detection | |
364 * @retval HAL status | |
365 */ | |
366 HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength) | |
367 { | |
368 /* Check the UART handle allocation */ | |
369 if(huart == NULL) | |
370 { | |
371 return HAL_ERROR; | |
372 } | |
373 | |
374 /* Check the parameters */ | |
375 assert_param(IS_UART_INSTANCE(huart->Instance)); | |
376 assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength)); | |
377 assert_param(IS_UART_LIN_WORD_LENGTH(huart->Init.WordLength)); | |
378 assert_param(IS_UART_LIN_OVERSAMPLING(huart->Init.OverSampling)); | |
379 | |
380 if(huart->gState == HAL_UART_STATE_RESET) | |
381 { | |
382 /* Allocate lock resource and initialize it */ | |
383 huart->Lock = HAL_UNLOCKED; | |
384 /* Init the low level hardware */ | |
385 HAL_UART_MspInit(huart); | |
386 } | |
387 | |
388 huart->gState = HAL_UART_STATE_BUSY; | |
389 | |
390 /* Disable the peripheral */ | |
391 __HAL_UART_DISABLE(huart); | |
392 | |
393 /* Set the UART Communication parameters */ | |
394 UART_SetConfig(huart); | |
395 | |
396 /* In LIN mode, the following bits must be kept cleared: | |
397 - LINEN and CLKEN bits in the USART_CR2 register, | |
398 - SCEN and IREN bits in the USART_CR3 register.*/ | |
399 CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN); | |
400 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN)); | |
401 | |
402 /* Enable the LIN mode by setting the LINEN bit in the CR2 register */ | |
403 SET_BIT(huart->Instance->CR2, USART_CR2_LINEN); | |
404 | |
405 /* Set the USART LIN Break detection length. */ | |
406 CLEAR_BIT(huart->Instance->CR2, USART_CR2_LBDL); | |
407 SET_BIT(huart->Instance->CR2, BreakDetectLength); | |
408 | |
409 /* Enable the peripheral */ | |
410 __HAL_UART_ENABLE(huart); | |
411 | |
412 /* Initialize the UART state*/ | |
413 huart->ErrorCode = HAL_UART_ERROR_NONE; | |
414 huart->gState= HAL_UART_STATE_READY; | |
415 huart->RxState= HAL_UART_STATE_READY; | |
416 | |
417 return HAL_OK; | |
418 } | |
419 | |
420 /** | |
421 * @brief Initializes the Multi-Processor mode according to the specified | |
422 * parameters in the UART_InitTypeDef and create the associated handle. | |
423 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
424 * the configuration information for the specified UART module. | |
425 * @param Address USART address | |
426 * @param WakeUpMethod specifies the USART wake-up method. | |
427 * This parameter can be one of the following values: | |
428 * @arg UART_WAKEUPMETHOD_IDLELINE: Wake-up by an idle line detection | |
429 * @arg UART_WAKEUPMETHOD_ADDRESSMARK: Wake-up by an address mark | |
430 * @retval HAL status | |
431 */ | |
432 HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod) | |
433 { | |
434 /* Check the UART handle allocation */ | |
435 if(huart == NULL) | |
436 { | |
437 return HAL_ERROR; | |
438 } | |
439 | |
440 /* Check the parameters */ | |
441 assert_param(IS_UART_INSTANCE(huart->Instance)); | |
442 assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod)); | |
443 assert_param(IS_UART_ADDRESS(Address)); | |
444 assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); | |
445 assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling)); | |
446 | |
447 if(huart->gState == HAL_UART_STATE_RESET) | |
448 { | |
449 /* Allocate lock resource and initialize it */ | |
450 huart->Lock = HAL_UNLOCKED; | |
451 /* Init the low level hardware */ | |
452 HAL_UART_MspInit(huart); | |
453 } | |
454 | |
455 huart->gState = HAL_UART_STATE_BUSY; | |
456 | |
457 /* Disable the peripheral */ | |
458 __HAL_UART_DISABLE(huart); | |
459 | |
460 /* Set the UART Communication parameters */ | |
461 UART_SetConfig(huart); | |
462 | |
463 /* In Multi-Processor mode, the following bits must be kept cleared: | |
464 - LINEN and CLKEN bits in the USART_CR2 register, | |
465 - SCEN, HDSEL and IREN bits in the USART_CR3 register */ | |
466 CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); | |
467 CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN)); | |
468 | |
469 /* Clear the USART address */ | |
470 CLEAR_BIT(huart->Instance->CR2, USART_CR2_ADD); | |
471 /* Set the USART address node */ | |
472 SET_BIT(huart->Instance->CR2, Address); | |
473 | |
474 /* Set the wake up method by setting the WAKE bit in the CR1 register */ | |
475 CLEAR_BIT(huart->Instance->CR1, USART_CR1_WAKE); | |
476 SET_BIT(huart->Instance->CR1, WakeUpMethod); | |
477 | |
478 /* Enable the peripheral */ | |
479 __HAL_UART_ENABLE(huart); | |
480 | |
481 /* Initialize the UART state */ | |
482 huart->ErrorCode = HAL_UART_ERROR_NONE; | |
483 huart->gState= HAL_UART_STATE_READY; | |
484 huart->RxState= HAL_UART_STATE_READY; | |
485 | |
486 return HAL_OK; | |
487 } | |
488 | |
489 /** | |
490 * @brief DeInitializes the UART peripheral. | |
491 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
492 * the configuration information for the specified UART module. | |
493 * @retval HAL status | |
494 */ | |
495 HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart) | |
496 { | |
497 /* Check the UART handle allocation */ | |
498 if(huart == NULL) | |
499 { | |
500 return HAL_ERROR; | |
501 } | |
502 | |
503 /* Check the parameters */ | |
504 assert_param(IS_UART_INSTANCE(huart->Instance)); | |
505 | |
506 huart->gState = HAL_UART_STATE_BUSY; | |
507 | |
508 /* DeInit the low level hardware */ | |
509 HAL_UART_MspDeInit(huart); | |
510 | |
511 huart->ErrorCode = HAL_UART_ERROR_NONE; | |
512 huart->gState = HAL_UART_STATE_RESET; | |
513 huart->RxState = HAL_UART_STATE_RESET; | |
514 | |
515 /* Process Lock */ | |
516 __HAL_UNLOCK(huart); | |
517 | |
518 return HAL_OK; | |
519 } | |
520 | |
521 /** | |
522 * @brief UART MSP Init. | |
523 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
524 * the configuration information for the specified UART module. | |
525 * @retval None | |
526 */ | |
527 __weak void HAL_UART_MspInit(UART_HandleTypeDef *huart) | |
528 { | |
529 /* Prevent unused argument(s) compilation warning */ | |
530 UNUSED(huart); | |
531 /* NOTE: This function Should not be modified, when the callback is needed, | |
532 the HAL_UART_MspInit could be implemented in the user file | |
533 */ | |
534 } | |
535 | |
536 /** | |
537 * @brief UART MSP DeInit. | |
538 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
539 * the configuration information for the specified UART module. | |
540 * @retval None | |
541 */ | |
542 __weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart) | |
543 { | |
544 /* Prevent unused argument(s) compilation warning */ | |
545 UNUSED(huart); | |
546 /* NOTE: This function Should not be modified, when the callback is needed, | |
547 the HAL_UART_MspDeInit could be implemented in the user file | |
548 */ | |
549 } | |
550 | |
551 /** | |
552 * @} | |
553 */ | |
554 | |
555 /** @defgroup UART_Exported_Functions_Group2 IO operation functions | |
556 * @brief UART Transmit and Receive functions | |
557 * | |
558 @verbatim | |
559 ============================================================================== | |
560 ##### IO operation functions ##### | |
561 ============================================================================== | |
562 [..] | |
563 This subsection provides a set of functions allowing to manage the UART asynchronous | |
564 and Half duplex data transfers. | |
565 | |
566 (#) There are two modes of transfer: | |
567 (++) Blocking mode: The communication is performed in polling mode. | |
568 The HAL status of all data processing is returned by the same function | |
569 after finishing transfer. | |
570 (++) Non blocking mode: The communication is performed using Interrupts | |
571 or DMA, these APIs return the HAL status. | |
572 The end of the data processing will be indicated through the | |
573 dedicated UART IRQ when using Interrupt mode or the DMA IRQ when | |
574 using DMA mode. | |
575 The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks | |
576 will be executed respectively at the end of the transmit or receive process. | |
577 The HAL_UART_ErrorCallback() user callback will be executed when | |
578 a communication error is detected. | |
579 | |
580 (#) Blocking mode APIs are: | |
581 (++) HAL_UART_Transmit() | |
582 (++) HAL_UART_Receive() | |
583 | |
584 (#) Non Blocking mode APIs with Interrupt are: | |
585 (++) HAL_UART_Transmit_IT() | |
586 (++) HAL_UART_Receive_IT() | |
587 (++) HAL_UART_IRQHandler() | |
588 | |
589 (#) Non Blocking mode functions with DMA are: | |
590 (++) HAL_UART_Transmit_DMA() | |
591 (++) HAL_UART_Receive_DMA() | |
592 | |
593 (#) A set of Transfer Complete Callbacks are provided in non blocking mode: | |
594 (++) HAL_UART_TxCpltCallback() | |
595 (++) HAL_UART_RxCpltCallback() | |
596 (++) HAL_UART_ErrorCallback() | |
597 | |
598 [..] | |
599 (@) In the Half duplex communication, it is forbidden to run the transmit | |
600 and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX | |
601 can't be useful. | |
602 | |
603 @endverbatim | |
604 * @{ | |
605 */ | |
606 | |
607 /** | |
608 * @brief Sends an amount of data in blocking mode. | |
609 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
610 * the configuration information for the specified UART module. | |
611 * @param pData Pointer to data buffer | |
612 * @param Size Amount of data to be sent | |
613 * @param Timeout Timeout duration | |
614 * @retval HAL status | |
615 */ | |
616 HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) | |
617 { | |
618 uint16_t* tmp; | |
619 uint32_t tickstart = 0U; | |
620 | |
621 /* Check that a Tx process is not already ongoing */ | |
622 if(huart->gState == HAL_UART_STATE_READY) | |
623 { | |
624 if((pData == NULL ) || (Size == 0)) | |
625 { | |
626 return HAL_ERROR; | |
627 } | |
628 | |
629 /* Process Locked */ | |
630 __HAL_LOCK(huart); | |
631 | |
632 huart->ErrorCode = HAL_UART_ERROR_NONE; | |
633 huart->gState = HAL_UART_STATE_BUSY_TX; | |
634 | |
635 /* Init tickstart for timeout managment */ | |
636 tickstart = HAL_GetTick(); | |
637 | |
638 huart->TxXferSize = Size; | |
639 huart->TxXferCount = Size; | |
640 while(huart->TxXferCount > 0U) | |
641 { | |
642 huart->TxXferCount--; | |
643 if(huart->Init.WordLength == UART_WORDLENGTH_9B) | |
644 { | |
645 if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) | |
646 { | |
647 return HAL_TIMEOUT; | |
648 } | |
649 tmp = (uint16_t*) pData; | |
650 huart->Instance->DR = (*tmp & (uint16_t)0x01FF); | |
651 if(huart->Init.Parity == UART_PARITY_NONE) | |
652 { | |
653 pData +=2U; | |
654 } | |
655 else | |
656 { | |
657 pData +=1U; | |
658 } | |
659 } | |
660 else | |
661 { | |
662 if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) | |
663 { | |
664 return HAL_TIMEOUT; | |
665 } | |
666 huart->Instance->DR = (*pData++ & (uint8_t)0xFF); | |
667 } | |
668 } | |
669 | |
670 if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) | |
671 { | |
672 return HAL_TIMEOUT; | |
673 } | |
674 | |
675 /* At end of Tx process, restore huart->gState to Ready */ | |
676 huart->gState = HAL_UART_STATE_READY; | |
677 | |
678 /* Process Unlocked */ | |
679 __HAL_UNLOCK(huart); | |
680 | |
681 return HAL_OK; | |
682 } | |
683 else | |
684 { | |
685 return HAL_BUSY; | |
686 } | |
687 } | |
688 | |
689 /** | |
690 * @brief Receives an amount of data in blocking mode. | |
691 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
692 * the configuration information for the specified UART module. | |
693 * @param pData Pointer to data buffer | |
694 * @param Size Amount of data to be received | |
695 * @param Timeout Timeout duration | |
696 * @retval HAL status | |
697 */ | |
698 HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) | |
699 { | |
700 uint16_t* tmp; | |
701 uint32_t tickstart = 0U; | |
702 | |
703 /* Check that a Rx process is not already ongoing */ | |
704 if(huart->RxState == HAL_UART_STATE_READY) | |
705 { | |
706 if((pData == NULL ) || (Size == 0)) | |
707 { | |
708 return HAL_ERROR; | |
709 } | |
710 | |
711 /* Process Locked */ | |
712 __HAL_LOCK(huart); | |
713 | |
714 huart->ErrorCode = HAL_UART_ERROR_NONE; | |
715 huart->RxState = HAL_UART_STATE_BUSY_RX; | |
716 | |
717 /* Init tickstart for timeout managment */ | |
718 tickstart = HAL_GetTick(); | |
719 | |
720 huart->RxXferSize = Size; | |
721 huart->RxXferCount = Size; | |
722 | |
723 /* Check the remain data to be received */ | |
724 while(huart->RxXferCount > 0U) | |
725 { | |
726 huart->RxXferCount--; | |
727 if(huart->Init.WordLength == UART_WORDLENGTH_9B) | |
728 { | |
729 if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) | |
730 { | |
731 return HAL_TIMEOUT; | |
732 } | |
733 tmp = (uint16_t*) pData; | |
734 if(huart->Init.Parity == UART_PARITY_NONE) | |
735 { | |
736 *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF); | |
737 pData +=2U; | |
738 } | |
739 else | |
740 { | |
741 *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF); | |
742 pData +=1U; | |
743 } | |
744 | |
745 } | |
746 else | |
747 { | |
748 if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) | |
749 { | |
750 return HAL_TIMEOUT; | |
751 } | |
752 if(huart->Init.Parity == UART_PARITY_NONE) | |
753 { | |
754 *pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF); | |
755 } | |
756 else | |
757 { | |
758 *pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F); | |
759 } | |
760 | |
761 } | |
762 } | |
763 | |
764 /* At end of Rx process, restore huart->RxState to Ready */ | |
765 huart->RxState = HAL_UART_STATE_READY; | |
766 | |
767 /* Process Unlocked */ | |
768 __HAL_UNLOCK(huart); | |
769 | |
770 return HAL_OK; | |
771 } | |
772 else | |
773 { | |
774 return HAL_BUSY; | |
775 } | |
776 } | |
777 | |
778 /** | |
779 * @brief Sends an amount of data in non blocking mode. | |
780 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
781 * the configuration information for the specified UART module. | |
782 * @param pData Pointer to data buffer | |
783 * @param Size Amount of data to be sent | |
784 * @retval HAL status | |
785 */ | |
786 HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) | |
787 { | |
788 /* Check that a Tx process is not already ongoing */ | |
789 if(huart->gState == HAL_UART_STATE_READY) | |
790 { | |
791 if((pData == NULL ) || (Size == 0)) | |
792 { | |
793 return HAL_ERROR; | |
794 } | |
795 | |
796 /* Process Locked */ | |
797 __HAL_LOCK(huart); | |
798 | |
799 huart->pTxBuffPtr = pData; | |
800 huart->TxXferSize = Size; | |
801 huart->TxXferCount = Size; | |
802 | |
803 huart->ErrorCode = HAL_UART_ERROR_NONE; | |
804 huart->gState = HAL_UART_STATE_BUSY_TX; | |
805 | |
806 /* Process Unlocked */ | |
807 __HAL_UNLOCK(huart); | |
808 | |
809 /* Enable the UART Transmit data register empty Interrupt */ | |
810 SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE); | |
811 | |
812 return HAL_OK; | |
813 } | |
814 else | |
815 { | |
816 return HAL_BUSY; | |
817 } | |
818 } | |
819 | |
820 /** | |
821 * @brief Receives an amount of data in non blocking mode | |
822 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
823 * the configuration information for the specified UART module. | |
824 * @param pData Pointer to data buffer | |
825 * @param Size Amount of data to be received | |
826 * @retval HAL status | |
827 */ | |
828 HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) | |
829 { | |
830 /* Check that a Rx process is not already ongoing */ | |
831 if(huart->RxState == HAL_UART_STATE_READY) | |
832 { | |
833 if((pData == NULL ) || (Size == 0)) | |
834 { | |
835 return HAL_ERROR; | |
836 } | |
837 | |
838 /* Process Locked */ | |
839 __HAL_LOCK(huart); | |
840 | |
841 huart->pRxBuffPtr = pData; | |
842 huart->RxXferSize = Size; | |
843 huart->RxXferCount = Size; | |
844 | |
845 huart->ErrorCode = HAL_UART_ERROR_NONE; | |
846 huart->RxState = HAL_UART_STATE_BUSY_RX; | |
847 | |
848 /* Process Unlocked */ | |
849 __HAL_UNLOCK(huart); | |
850 | |
851 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ | |
852 SET_BIT(huart->Instance->CR3, USART_CR3_EIE); | |
853 | |
854 /* Enable the UART Parity Error and Data Register not empty Interrupts */ | |
855 SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE); | |
856 | |
857 return HAL_OK; | |
858 } | |
859 else | |
860 { | |
861 return HAL_BUSY; | |
862 } | |
863 } | |
864 | |
865 /** | |
866 * @brief Sends an amount of data in non blocking mode. | |
867 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
868 * the configuration information for the specified UART module. | |
869 * @param pData Pointer to data buffer | |
870 * @param Size Amount of data to be sent | |
871 * @retval HAL status | |
872 */ | |
873 HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) | |
874 { | |
875 uint32_t *tmp; | |
876 | |
877 /* Check that a Tx process is not already ongoing */ | |
878 if(huart->gState == HAL_UART_STATE_READY) | |
879 { | |
880 if((pData == NULL ) || (Size == 0)) | |
881 { | |
882 return HAL_ERROR; | |
883 } | |
884 | |
885 /* Process Locked */ | |
886 __HAL_LOCK(huart); | |
887 | |
888 huart->pTxBuffPtr = pData; | |
889 huart->TxXferSize = Size; | |
890 huart->TxXferCount = Size; | |
891 | |
892 huart->ErrorCode = HAL_UART_ERROR_NONE; | |
893 huart->gState = HAL_UART_STATE_BUSY_TX; | |
894 | |
895 /* Set the UART DMA transfer complete callback */ | |
896 huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt; | |
897 | |
898 /* Set the UART DMA Half transfer complete callback */ | |
899 huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt; | |
900 | |
901 /* Set the DMA error callback */ | |
902 huart->hdmatx->XferErrorCallback = UART_DMAError; | |
903 | |
904 /* Set the DMA abort callback */ | |
905 huart->hdmatx->XferAbortCallback = NULL; | |
906 | |
907 /* Enable the UART transmit DMA Stream */ | |
908 tmp = (uint32_t*)&pData; | |
909 HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->DR, Size); | |
910 | |
911 /* Clear the TC flag in the SR register by writing 0 to it */ | |
912 __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC); | |
913 | |
914 /* Process Unlocked */ | |
915 __HAL_UNLOCK(huart); | |
916 | |
917 /* Enable the DMA transfer for transmit request by setting the DMAT bit | |
918 in the UART CR3 register */ | |
919 SET_BIT(huart->Instance->CR3, USART_CR3_DMAT); | |
920 | |
921 return HAL_OK; | |
922 } | |
923 else | |
924 { | |
925 return HAL_BUSY; | |
926 } | |
927 } | |
928 | |
929 /** | |
930 * @brief Receives an amount of data in non blocking mode. | |
931 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
932 * the configuration information for the specified UART module. | |
933 * @param pData Pointer to data buffer | |
934 * @param Size Amount of data to be received | |
935 * @note When the UART parity is enabled (PCE = 1) the data received contain the parity bit. | |
936 * @retval HAL status | |
937 */ | |
938 HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) | |
939 { | |
940 uint32_t *tmp; | |
941 | |
942 /* Check that a Rx process is not already ongoing */ | |
943 if(huart->RxState == HAL_UART_STATE_READY) | |
944 { | |
945 if((pData == NULL ) || (Size == 0)) | |
946 { | |
947 return HAL_ERROR; | |
948 } | |
949 | |
950 /* Process Locked */ | |
951 __HAL_LOCK(huart); | |
952 | |
953 huart->pRxBuffPtr = pData; | |
954 huart->RxXferSize = Size; | |
955 | |
956 huart->ErrorCode = HAL_UART_ERROR_NONE; | |
957 huart->RxState = HAL_UART_STATE_BUSY_RX; | |
958 | |
959 /* Set the UART DMA transfer complete callback */ | |
960 huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt; | |
961 | |
962 /* Set the UART DMA Half transfer complete callback */ | |
963 huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt; | |
964 | |
965 /* Set the DMA error callback */ | |
966 huart->hdmarx->XferErrorCallback = UART_DMAError; | |
967 | |
968 /* Set the DMA abort callback */ | |
969 huart->hdmarx->XferAbortCallback = NULL; | |
970 | |
971 /* Enable the DMA Stream */ | |
972 tmp = (uint32_t*)&pData; | |
973 HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->DR, *(uint32_t*)tmp, Size); | |
974 | |
975 /* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */ | |
976 __HAL_UART_CLEAR_OREFLAG(huart); | |
977 | |
978 /* Process Unlocked */ | |
979 __HAL_UNLOCK(huart); | |
980 | |
981 /* Enable the UART Parity Error Interrupt */ | |
982 SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); | |
983 | |
984 /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ | |
985 SET_BIT(huart->Instance->CR3, USART_CR3_EIE); | |
986 | |
987 /* Enable the DMA transfer for the receiver request by setting the DMAR bit | |
988 in the UART CR3 register */ | |
989 SET_BIT(huart->Instance->CR3, USART_CR3_DMAR); | |
990 | |
991 return HAL_OK; | |
992 } | |
993 else | |
994 { | |
995 return HAL_BUSY; | |
996 } | |
997 } | |
998 | |
999 /** | |
1000 * @brief Pauses the DMA Transfer. | |
1001 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
1002 * the configuration information for the specified UART module. | |
1003 * @retval HAL status | |
1004 */ | |
1005 HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart) | |
1006 { | |
1007 uint32_t dmarequest = 0x00U; | |
1008 | |
1009 /* Process Locked */ | |
1010 __HAL_LOCK(huart); | |
1011 dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT); | |
1012 if((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest) | |
1013 { | |
1014 /* Disable the UART DMA Tx request */ | |
1015 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); | |
1016 } | |
1017 dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR); | |
1018 if((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest) | |
1019 { | |
1020 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ | |
1021 CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); | |
1022 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); | |
1023 | |
1024 /* Disable the UART DMA Rx request */ | |
1025 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); | |
1026 } | |
1027 | |
1028 /* Process Unlocked */ | |
1029 __HAL_UNLOCK(huart); | |
1030 | |
1031 return HAL_OK; | |
1032 } | |
1033 | |
1034 /** | |
1035 * @brief Resumes the DMA Transfer. | |
1036 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
1037 * the configuration information for the specified UART module. | |
1038 * @retval HAL status | |
1039 */ | |
1040 HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart) | |
1041 { | |
1042 /* Process Locked */ | |
1043 __HAL_LOCK(huart); | |
1044 | |
1045 if(huart->gState == HAL_UART_STATE_BUSY_TX) | |
1046 { | |
1047 /* Enable the UART DMA Tx request */ | |
1048 SET_BIT(huart->Instance->CR3, USART_CR3_DMAT); | |
1049 } | |
1050 if(huart->RxState == HAL_UART_STATE_BUSY_RX) | |
1051 { | |
1052 /* Clear the Overrun flag before resuming the Rx transfer*/ | |
1053 __HAL_UART_CLEAR_OREFLAG(huart); | |
1054 | |
1055 /* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */ | |
1056 SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); | |
1057 SET_BIT(huart->Instance->CR3, USART_CR3_EIE); | |
1058 | |
1059 /* Enable the UART DMA Rx request */ | |
1060 SET_BIT(huart->Instance->CR3, USART_CR3_DMAR); | |
1061 } | |
1062 | |
1063 /* Process Unlocked */ | |
1064 __HAL_UNLOCK(huart); | |
1065 | |
1066 return HAL_OK; | |
1067 } | |
1068 | |
1069 /** | |
1070 * @brief Stops the DMA Transfer. | |
1071 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
1072 * the configuration information for the specified UART module. | |
1073 * @retval HAL status | |
1074 */ | |
1075 HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart) | |
1076 { | |
1077 uint32_t dmarequest = 0x00U; | |
1078 /* The Lock is not implemented on this API to allow the user application | |
1079 to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback(): | |
1080 when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated | |
1081 and the correspond call back is executed HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() | |
1082 */ | |
1083 | |
1084 /* Stop UART DMA Tx request if ongoing */ | |
1085 dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT); | |
1086 if((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest) | |
1087 { | |
1088 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); | |
1089 | |
1090 /* Abort the UART DMA Tx channel */ | |
1091 if(huart->hdmatx != NULL) | |
1092 { | |
1093 HAL_DMA_Abort(huart->hdmatx); | |
1094 } | |
1095 UART_EndTxTransfer(huart); | |
1096 } | |
1097 | |
1098 /* Stop UART DMA Rx request if ongoing */ | |
1099 dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR); | |
1100 if((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest) | |
1101 { | |
1102 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); | |
1103 | |
1104 /* Abort the UART DMA Rx channel */ | |
1105 if(huart->hdmarx != NULL) | |
1106 { | |
1107 HAL_DMA_Abort(huart->hdmarx); | |
1108 } | |
1109 UART_EndRxTransfer(huart); | |
1110 } | |
1111 | |
1112 return HAL_OK; | |
1113 } | |
1114 | |
1115 /** | |
1116 * @brief Abort ongoing transfers (blocking mode). | |
1117 * @param huart UART handle. | |
1118 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. | |
1119 * This procedure performs following operations : | |
1120 * - Disable PPP Interrupts | |
1121 * - Disable the DMA transfer in the peripheral register (if enabled) | |
1122 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) | |
1123 * - Set handle State to READY | |
1124 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. | |
1125 * @retval HAL status | |
1126 */ | |
1127 HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart) | |
1128 { | |
1129 /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ | |
1130 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE)); | |
1131 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); | |
1132 | |
1133 /* Disable the UART DMA Tx request if enabled */ | |
1134 if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) | |
1135 { | |
1136 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); | |
1137 | |
1138 /* Abort the UART DMA Tx channel: use blocking DMA Abort API (no callback) */ | |
1139 if(huart->hdmatx != NULL) | |
1140 { | |
1141 /* Set the UART DMA Abort callback to Null. | |
1142 No call back execution at end of DMA abort procedure */ | |
1143 huart->hdmatx->XferAbortCallback = NULL; | |
1144 | |
1145 HAL_DMA_Abort(huart->hdmatx); | |
1146 } | |
1147 } | |
1148 | |
1149 /* Disable the UART DMA Rx request if enabled */ | |
1150 if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) | |
1151 { | |
1152 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); | |
1153 | |
1154 /* Abort the UART DMA Rx channel: use blocking DMA Abort API (no callback) */ | |
1155 if(huart->hdmarx != NULL) | |
1156 { | |
1157 /* Set the UART DMA Abort callback to Null. | |
1158 No call back execution at end of DMA abort procedure */ | |
1159 huart->hdmarx->XferAbortCallback = NULL; | |
1160 | |
1161 HAL_DMA_Abort(huart->hdmarx); | |
1162 } | |
1163 } | |
1164 | |
1165 /* Reset Tx and Rx transfer counters */ | |
1166 huart->TxXferCount = 0x00U; | |
1167 huart->RxXferCount = 0x00U; | |
1168 | |
1169 /* Reset ErrorCode */ | |
1170 huart->ErrorCode = HAL_UART_ERROR_NONE; | |
1171 | |
1172 /* Restore huart->RxState and huart->gState to Ready */ | |
1173 huart->RxState = HAL_UART_STATE_READY; | |
1174 huart->gState = HAL_UART_STATE_READY; | |
1175 | |
1176 return HAL_OK; | |
1177 } | |
1178 | |
1179 /** | |
1180 * @brief Abort ongoing Transmit transfer (blocking mode). | |
1181 * @param huart UART handle. | |
1182 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. | |
1183 * This procedure performs following operations : | |
1184 * - Disable PPP Interrupts | |
1185 * - Disable the DMA transfer in the peripheral register (if enabled) | |
1186 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) | |
1187 * - Set handle State to READY | |
1188 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. | |
1189 * @retval HAL status | |
1190 */ | |
1191 HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart) | |
1192 { | |
1193 /* Disable TXEIE and TCIE interrupts */ | |
1194 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); | |
1195 | |
1196 /* Disable the UART DMA Tx request if enabled */ | |
1197 if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) | |
1198 { | |
1199 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); | |
1200 | |
1201 /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */ | |
1202 if(huart->hdmatx != NULL) | |
1203 { | |
1204 /* Set the UART DMA Abort callback to Null. | |
1205 No call back execution at end of DMA abort procedure */ | |
1206 huart->hdmatx->XferAbortCallback = NULL; | |
1207 | |
1208 HAL_DMA_Abort(huart->hdmatx); | |
1209 } | |
1210 } | |
1211 | |
1212 /* Reset Tx transfer counter */ | |
1213 huart->TxXferCount = 0x00U; | |
1214 | |
1215 /* Restore huart->gState to Ready */ | |
1216 huart->gState = HAL_UART_STATE_READY; | |
1217 | |
1218 return HAL_OK; | |
1219 } | |
1220 | |
1221 /** | |
1222 * @brief Abort ongoing Receive transfer (blocking mode). | |
1223 * @param huart UART handle. | |
1224 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. | |
1225 * This procedure performs following operations : | |
1226 * - Disable PPP Interrupts | |
1227 * - Disable the DMA transfer in the peripheral register (if enabled) | |
1228 * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) | |
1229 * - Set handle State to READY | |
1230 * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. | |
1231 * @retval HAL status | |
1232 */ | |
1233 HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart) | |
1234 { | |
1235 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ | |
1236 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); | |
1237 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); | |
1238 | |
1239 /* Disable the UART DMA Rx request if enabled */ | |
1240 if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) | |
1241 { | |
1242 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); | |
1243 | |
1244 /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */ | |
1245 if(huart->hdmarx != NULL) | |
1246 { | |
1247 /* Set the UART DMA Abort callback to Null. | |
1248 No call back execution at end of DMA abort procedure */ | |
1249 huart->hdmarx->XferAbortCallback = NULL; | |
1250 | |
1251 HAL_DMA_Abort(huart->hdmarx); | |
1252 } | |
1253 } | |
1254 | |
1255 /* Reset Rx transfer counter */ | |
1256 huart->RxXferCount = 0x00U; | |
1257 | |
1258 /* Restore huart->RxState to Ready */ | |
1259 huart->RxState = HAL_UART_STATE_READY; | |
1260 | |
1261 return HAL_OK; | |
1262 } | |
1263 | |
1264 /** | |
1265 * @brief Abort ongoing transfers (Interrupt mode). | |
1266 * @param huart UART handle. | |
1267 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. | |
1268 * This procedure performs following operations : | |
1269 * - Disable PPP Interrupts | |
1270 * - Disable the DMA transfer in the peripheral register (if enabled) | |
1271 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) | |
1272 * - Set handle State to READY | |
1273 * - At abort completion, call user abort complete callback | |
1274 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be | |
1275 * considered as completed only when user abort complete callback is executed (not when exiting function). | |
1276 * @retval HAL status | |
1277 */ | |
1278 HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart) | |
1279 { | |
1280 uint32_t AbortCplt = 0x01U; | |
1281 | |
1282 /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ | |
1283 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE)); | |
1284 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); | |
1285 | |
1286 /* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised | |
1287 before any call to DMA Abort functions */ | |
1288 /* DMA Tx Handle is valid */ | |
1289 if(huart->hdmatx != NULL) | |
1290 { | |
1291 /* Set DMA Abort Complete callback if UART DMA Tx request if enabled. | |
1292 Otherwise, set it to NULL */ | |
1293 if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) | |
1294 { | |
1295 huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback; | |
1296 } | |
1297 else | |
1298 { | |
1299 huart->hdmatx->XferAbortCallback = NULL; | |
1300 } | |
1301 } | |
1302 /* DMA Rx Handle is valid */ | |
1303 if(huart->hdmarx != NULL) | |
1304 { | |
1305 /* Set DMA Abort Complete callback if UART DMA Rx request if enabled. | |
1306 Otherwise, set it to NULL */ | |
1307 if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) | |
1308 { | |
1309 huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback; | |
1310 } | |
1311 else | |
1312 { | |
1313 huart->hdmarx->XferAbortCallback = NULL; | |
1314 } | |
1315 } | |
1316 | |
1317 /* Disable the UART DMA Tx request if enabled */ | |
1318 if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) | |
1319 { | |
1320 /* Disable DMA Tx at UART level */ | |
1321 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); | |
1322 | |
1323 /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */ | |
1324 if(huart->hdmatx != NULL) | |
1325 { | |
1326 /* UART Tx DMA Abort callback has already been initialised : | |
1327 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ | |
1328 | |
1329 /* Abort DMA TX */ | |
1330 if(HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK) | |
1331 { | |
1332 huart->hdmatx->XferAbortCallback = NULL; | |
1333 } | |
1334 else | |
1335 { | |
1336 AbortCplt = 0x00U; | |
1337 } | |
1338 } | |
1339 } | |
1340 | |
1341 /* Disable the UART DMA Rx request if enabled */ | |
1342 if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) | |
1343 { | |
1344 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); | |
1345 | |
1346 /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */ | |
1347 if(huart->hdmarx != NULL) | |
1348 { | |
1349 /* UART Rx DMA Abort callback has already been initialised : | |
1350 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ | |
1351 | |
1352 /* Abort DMA RX */ | |
1353 if(HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) | |
1354 { | |
1355 huart->hdmarx->XferAbortCallback = NULL; | |
1356 AbortCplt = 0x01U; | |
1357 } | |
1358 else | |
1359 { | |
1360 AbortCplt = 0x00U; | |
1361 } | |
1362 } | |
1363 } | |
1364 | |
1365 /* if no DMA abort complete callback execution is required => call user Abort Complete callback */ | |
1366 if(AbortCplt == 0x01U) | |
1367 { | |
1368 /* Reset Tx and Rx transfer counters */ | |
1369 huart->TxXferCount = 0x00U; | |
1370 huart->RxXferCount = 0x00U; | |
1371 | |
1372 /* Reset ErrorCode */ | |
1373 huart->ErrorCode = HAL_UART_ERROR_NONE; | |
1374 | |
1375 /* Restore huart->gState and huart->RxState to Ready */ | |
1376 huart->gState = HAL_UART_STATE_READY; | |
1377 huart->RxState = HAL_UART_STATE_READY; | |
1378 | |
1379 /* As no DMA to be aborted, call directly user Abort complete callback */ | |
1380 HAL_UART_AbortCpltCallback(huart); | |
1381 } | |
1382 | |
1383 return HAL_OK; | |
1384 } | |
1385 | |
1386 /** | |
1387 * @brief Abort ongoing Transmit transfer (Interrupt mode). | |
1388 * @param huart UART handle. | |
1389 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. | |
1390 * This procedure performs following operations : | |
1391 * - Disable PPP Interrupts | |
1392 * - Disable the DMA transfer in the peripheral register (if enabled) | |
1393 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) | |
1394 * - Set handle State to READY | |
1395 * - At abort completion, call user abort complete callback | |
1396 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be | |
1397 * considered as completed only when user abort complete callback is executed (not when exiting function). | |
1398 * @retval HAL status | |
1399 */ | |
1400 HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart) | |
1401 { | |
1402 /* Disable TXEIE and TCIE interrupts */ | |
1403 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); | |
1404 | |
1405 /* Disable the UART DMA Tx request if enabled */ | |
1406 if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) | |
1407 { | |
1408 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); | |
1409 | |
1410 /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */ | |
1411 if(huart->hdmatx != NULL) | |
1412 { | |
1413 /* Set the UART DMA Abort callback : | |
1414 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ | |
1415 huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback; | |
1416 | |
1417 /* Abort DMA TX */ | |
1418 if(HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK) | |
1419 { | |
1420 /* Call Directly huart->hdmatx->XferAbortCallback function in case of error */ | |
1421 huart->hdmatx->XferAbortCallback(huart->hdmatx); | |
1422 } | |
1423 } | |
1424 else | |
1425 { | |
1426 /* Reset Tx transfer counter */ | |
1427 huart->TxXferCount = 0x00U; | |
1428 | |
1429 /* Restore huart->gState to Ready */ | |
1430 huart->gState = HAL_UART_STATE_READY; | |
1431 | |
1432 /* As no DMA to be aborted, call directly user Abort complete callback */ | |
1433 HAL_UART_AbortTransmitCpltCallback(huart); | |
1434 } | |
1435 } | |
1436 else | |
1437 { | |
1438 /* Reset Tx transfer counter */ | |
1439 huart->TxXferCount = 0x00U; | |
1440 | |
1441 /* Restore huart->gState to Ready */ | |
1442 huart->gState = HAL_UART_STATE_READY; | |
1443 | |
1444 /* As no DMA to be aborted, call directly user Abort complete callback */ | |
1445 HAL_UART_AbortTransmitCpltCallback(huart); | |
1446 } | |
1447 | |
1448 return HAL_OK; | |
1449 } | |
1450 | |
1451 /** | |
1452 * @brief Abort ongoing Receive transfer (Interrupt mode). | |
1453 * @param huart UART handle. | |
1454 * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. | |
1455 * This procedure performs following operations : | |
1456 * - Disable PPP Interrupts | |
1457 * - Disable the DMA transfer in the peripheral register (if enabled) | |
1458 * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) | |
1459 * - Set handle State to READY | |
1460 * - At abort completion, call user abort complete callback | |
1461 * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be | |
1462 * considered as completed only when user abort complete callback is executed (not when exiting function). | |
1463 * @retval HAL status | |
1464 */ | |
1465 HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart) | |
1466 { | |
1467 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ | |
1468 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); | |
1469 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); | |
1470 | |
1471 /* Disable the UART DMA Rx request if enabled */ | |
1472 if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) | |
1473 { | |
1474 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); | |
1475 | |
1476 /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */ | |
1477 if(huart->hdmarx != NULL) | |
1478 { | |
1479 /* Set the UART DMA Abort callback : | |
1480 will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ | |
1481 huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback; | |
1482 | |
1483 /* Abort DMA RX */ | |
1484 if(HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) | |
1485 { | |
1486 /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */ | |
1487 huart->hdmarx->XferAbortCallback(huart->hdmarx); | |
1488 } | |
1489 } | |
1490 else | |
1491 { | |
1492 /* Reset Rx transfer counter */ | |
1493 huart->RxXferCount = 0x00U; | |
1494 | |
1495 /* Restore huart->RxState to Ready */ | |
1496 huart->RxState = HAL_UART_STATE_READY; | |
1497 | |
1498 /* As no DMA to be aborted, call directly user Abort complete callback */ | |
1499 HAL_UART_AbortReceiveCpltCallback(huart); | |
1500 } | |
1501 } | |
1502 else | |
1503 { | |
1504 /* Reset Rx transfer counter */ | |
1505 huart->RxXferCount = 0x00U; | |
1506 | |
1507 /* Restore huart->RxState to Ready */ | |
1508 huart->RxState = HAL_UART_STATE_READY; | |
1509 | |
1510 /* As no DMA to be aborted, call directly user Abort complete callback */ | |
1511 HAL_UART_AbortReceiveCpltCallback(huart); | |
1512 } | |
1513 | |
1514 return HAL_OK; | |
1515 } | |
1516 | |
1517 /** | |
1518 * @brief This function handles UART interrupt request. | |
1519 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
1520 * the configuration information for the specified UART module. | |
1521 * @retval None | |
1522 */ | |
1523 void HAL_UART_IRQHandler(UART_HandleTypeDef *huart) | |
1524 { | |
1525 uint32_t isrflags = READ_REG(huart->Instance->SR); | |
1526 uint32_t cr1its = READ_REG(huart->Instance->CR1); | |
1527 uint32_t cr3its = READ_REG(huart->Instance->CR3); | |
1528 uint32_t errorflags = 0x00U; | |
1529 uint32_t dmarequest = 0x00U; | |
1530 | |
1531 /* If no error occurs */ | |
1532 errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE)); | |
1533 if(errorflags == RESET) | |
1534 { | |
1535 /* UART in mode Receiver -------------------------------------------------*/ | |
1536 if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) | |
1537 { | |
1538 UART_Receive_IT(huart); | |
1539 return; | |
1540 } | |
1541 } | |
1542 | |
1543 /* If some errors occur */ | |
1544 if((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET))) | |
1545 { | |
1546 /* UART parity error interrupt occurred ----------------------------------*/ | |
1547 if(((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET)) | |
1548 { | |
1549 huart->ErrorCode |= HAL_UART_ERROR_PE; | |
1550 } | |
1551 | |
1552 /* UART noise error interrupt occurred -----------------------------------*/ | |
1553 if(((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) | |
1554 { | |
1555 huart->ErrorCode |= HAL_UART_ERROR_NE; | |
1556 } | |
1557 | |
1558 /* UART frame error interrupt occurred -----------------------------------*/ | |
1559 if(((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) | |
1560 { | |
1561 huart->ErrorCode |= HAL_UART_ERROR_FE; | |
1562 } | |
1563 | |
1564 /* UART Over-Run interrupt occurred --------------------------------------*/ | |
1565 if(((isrflags & USART_SR_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) | |
1566 { | |
1567 huart->ErrorCode |= HAL_UART_ERROR_ORE; | |
1568 } | |
1569 | |
1570 /* Call UART Error Call back function if need be --------------------------*/ | |
1571 if(huart->ErrorCode != HAL_UART_ERROR_NONE) | |
1572 { | |
1573 /* UART in mode Receiver -----------------------------------------------*/ | |
1574 if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) | |
1575 { | |
1576 UART_Receive_IT(huart); | |
1577 } | |
1578 | |
1579 /* If Overrun error occurs, or if any error occurs in DMA mode reception, | |
1580 consider error as blocking */ | |
1581 dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR); | |
1582 if(((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) || dmarequest) | |
1583 { | |
1584 /* Blocking error : transfer is aborted | |
1585 Set the UART state ready to be able to start again the process, | |
1586 Disable Rx Interrupts, and disable Rx DMA request, if ongoing */ | |
1587 UART_EndRxTransfer(huart); | |
1588 | |
1589 /* Disable the UART DMA Rx request if enabled */ | |
1590 if(HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) | |
1591 { | |
1592 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); | |
1593 | |
1594 /* Abort the UART DMA Rx channel */ | |
1595 if(huart->hdmarx != NULL) | |
1596 { | |
1597 /* Set the UART DMA Abort callback : | |
1598 will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */ | |
1599 huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError; | |
1600 if(HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) | |
1601 { | |
1602 /* Call Directly XferAbortCallback function in case of error */ | |
1603 huart->hdmarx->XferAbortCallback(huart->hdmarx); | |
1604 } | |
1605 } | |
1606 else | |
1607 { | |
1608 /* Call user error callback */ | |
1609 HAL_UART_ErrorCallback(huart); | |
1610 } | |
1611 } | |
1612 else | |
1613 { | |
1614 /* Call user error callback */ | |
1615 HAL_UART_ErrorCallback(huart); | |
1616 } | |
1617 } | |
1618 else | |
1619 { | |
1620 /* Non Blocking error : transfer could go on. | |
1621 Error is notified to user through user error callback */ | |
1622 HAL_UART_ErrorCallback(huart); | |
1623 huart->ErrorCode = HAL_UART_ERROR_NONE; | |
1624 } | |
1625 } | |
1626 return; | |
1627 } /* End if some error occurs */ | |
1628 | |
1629 /* UART in mode Transmitter ------------------------------------------------*/ | |
1630 if(((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET)) | |
1631 { | |
1632 UART_Transmit_IT(huart); | |
1633 return; | |
1634 } | |
1635 | |
1636 /* UART in mode Transmitter end --------------------------------------------*/ | |
1637 if(((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET)) | |
1638 { | |
1639 UART_EndTransmit_IT(huart); | |
1640 return; | |
1641 } | |
1642 } | |
1643 | |
1644 /** | |
1645 * @brief Tx Transfer completed callbacks. | |
1646 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
1647 * the configuration information for the specified UART module. | |
1648 * @retval None | |
1649 */ | |
1650 __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) | |
1651 { | |
1652 /* Prevent unused argument(s) compilation warning */ | |
1653 UNUSED(huart); | |
1654 /* NOTE: This function Should not be modified, when the callback is needed, | |
1655 the HAL_UART_TxCpltCallback could be implemented in the user file | |
1656 */ | |
1657 } | |
1658 | |
1659 /** | |
1660 * @brief Tx Half Transfer completed callbacks. | |
1661 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
1662 * the configuration information for the specified UART module. | |
1663 * @retval None | |
1664 */ | |
1665 __weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart) | |
1666 { | |
1667 /* Prevent unused argument(s) compilation warning */ | |
1668 UNUSED(huart); | |
1669 /* NOTE: This function Should not be modified, when the callback is needed, | |
1670 the HAL_UART_TxCpltCallback could be implemented in the user file | |
1671 */ | |
1672 } | |
1673 | |
1674 /** | |
1675 * @brief Rx Transfer completed callbacks. | |
1676 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
1677 * the configuration information for the specified UART module. | |
1678 * @retval None | |
1679 */ | |
1680 __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) | |
1681 { | |
1682 /* Prevent unused argument(s) compilation warning */ | |
1683 UNUSED(huart); | |
1684 /* NOTE: This function Should not be modified, when the callback is needed, | |
1685 the HAL_UART_TxCpltCallback could be implemented in the user file | |
1686 */ | |
1687 } | |
1688 | |
1689 /** | |
1690 * @brief Rx Half Transfer completed callbacks. | |
1691 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
1692 * the configuration information for the specified UART module. | |
1693 * @retval None | |
1694 */ | |
1695 __weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) | |
1696 { | |
1697 /* Prevent unused argument(s) compilation warning */ | |
1698 UNUSED(huart); | |
1699 /* NOTE: This function Should not be modified, when the callback is needed, | |
1700 the HAL_UART_TxCpltCallback could be implemented in the user file | |
1701 */ | |
1702 } | |
1703 | |
1704 /** | |
1705 * @brief UART error callbacks. | |
1706 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
1707 * the configuration information for the specified UART module. | |
1708 * @retval None | |
1709 */ | |
1710 __weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) | |
1711 { | |
1712 /* Prevent unused argument(s) compilation warning */ | |
1713 UNUSED(huart); | |
1714 /* NOTE: This function Should not be modified, when the callback is needed, | |
1715 the HAL_UART_ErrorCallback could be implemented in the user file | |
1716 */ | |
1717 } | |
1718 | |
1719 /** | |
1720 * @brief UART Abort Complete callback. | |
1721 * @param huart UART handle. | |
1722 * @retval None | |
1723 */ | |
1724 __weak void HAL_UART_AbortCpltCallback (UART_HandleTypeDef *huart) | |
1725 { | |
1726 /* Prevent unused argument(s) compilation warning */ | |
1727 UNUSED(huart); | |
1728 | |
1729 /* NOTE : This function should not be modified, when the callback is needed, | |
1730 the HAL_UART_AbortCpltCallback can be implemented in the user file. | |
1731 */ | |
1732 } | |
1733 /** | |
1734 * @brief UART Abort Complete callback. | |
1735 * @param huart UART handle. | |
1736 * @retval None | |
1737 */ | |
1738 __weak void HAL_UART_AbortTransmitCpltCallback (UART_HandleTypeDef *huart) | |
1739 { | |
1740 /* Prevent unused argument(s) compilation warning */ | |
1741 UNUSED(huart); | |
1742 | |
1743 /* NOTE : This function should not be modified, when the callback is needed, | |
1744 the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file. | |
1745 */ | |
1746 } | |
1747 | |
1748 /** | |
1749 * @brief UART Abort Receive Complete callback. | |
1750 * @param huart UART handle. | |
1751 * @retval None | |
1752 */ | |
1753 __weak void HAL_UART_AbortReceiveCpltCallback (UART_HandleTypeDef *huart) | |
1754 { | |
1755 /* Prevent unused argument(s) compilation warning */ | |
1756 UNUSED(huart); | |
1757 | |
1758 /* NOTE : This function should not be modified, when the callback is needed, | |
1759 the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file. | |
1760 */ | |
1761 } | |
1762 | |
1763 /** | |
1764 * @} | |
1765 */ | |
1766 | |
1767 /** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions | |
1768 * @brief UART control functions | |
1769 * | |
1770 @verbatim | |
1771 ============================================================================== | |
1772 ##### Peripheral Control functions ##### | |
1773 ============================================================================== | |
1774 [..] | |
1775 This subsection provides a set of functions allowing to control the UART: | |
1776 (+) HAL_LIN_SendBreak() API can be helpful to transmit the break character. | |
1777 (+) HAL_MultiProcessor_EnterMuteMode() API can be helpful to enter the UART in mute mode. | |
1778 (+) HAL_MultiProcessor_ExitMuteMode() API can be helpful to exit the UART mute mode by software. | |
1779 | |
1780 @endverbatim | |
1781 * @{ | |
1782 */ | |
1783 | |
1784 /** | |
1785 * @brief Transmits break characters. | |
1786 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
1787 * the configuration information for the specified UART module. | |
1788 * @retval HAL status | |
1789 */ | |
1790 HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart) | |
1791 { | |
1792 /* Check the parameters */ | |
1793 assert_param(IS_UART_INSTANCE(huart->Instance)); | |
1794 | |
1795 /* Process Locked */ | |
1796 __HAL_LOCK(huart); | |
1797 | |
1798 huart->gState = HAL_UART_STATE_BUSY; | |
1799 | |
1800 /* Send break characters */ | |
1801 SET_BIT(huart->Instance->CR1, USART_CR1_SBK); | |
1802 | |
1803 huart->gState = HAL_UART_STATE_READY; | |
1804 | |
1805 /* Process Unlocked */ | |
1806 __HAL_UNLOCK(huart); | |
1807 | |
1808 return HAL_OK; | |
1809 } | |
1810 | |
1811 /** | |
1812 * @brief Enters the UART in mute mode. | |
1813 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
1814 * the configuration information for the specified UART module. | |
1815 * @retval HAL status | |
1816 */ | |
1817 HAL_StatusTypeDef HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart) | |
1818 { | |
1819 /* Check the parameters */ | |
1820 assert_param(IS_UART_INSTANCE(huart->Instance)); | |
1821 | |
1822 /* Process Locked */ | |
1823 __HAL_LOCK(huart); | |
1824 | |
1825 huart->gState = HAL_UART_STATE_BUSY; | |
1826 | |
1827 /* Enable the USART mute mode by setting the RWU bit in the CR1 register */ | |
1828 SET_BIT(huart->Instance->CR1, USART_CR1_RWU); | |
1829 | |
1830 huart->gState = HAL_UART_STATE_READY; | |
1831 | |
1832 /* Process Unlocked */ | |
1833 __HAL_UNLOCK(huart); | |
1834 | |
1835 return HAL_OK; | |
1836 } | |
1837 | |
1838 /** | |
1839 * @brief Exits the UART mute mode: wake up software. | |
1840 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
1841 * the configuration information for the specified UART module. | |
1842 * @retval HAL status | |
1843 */ | |
1844 HAL_StatusTypeDef HAL_MultiProcessor_ExitMuteMode(UART_HandleTypeDef *huart) | |
1845 { | |
1846 /* Check the parameters */ | |
1847 assert_param(IS_UART_INSTANCE(huart->Instance)); | |
1848 | |
1849 /* Process Locked */ | |
1850 __HAL_LOCK(huart); | |
1851 | |
1852 huart->gState = HAL_UART_STATE_BUSY; | |
1853 | |
1854 /* Disable the USART mute mode by clearing the RWU bit in the CR1 register */ | |
1855 CLEAR_BIT(huart->Instance->CR1, USART_CR1_RWU); | |
1856 | |
1857 huart->gState = HAL_UART_STATE_READY; | |
1858 | |
1859 /* Process Unlocked */ | |
1860 __HAL_UNLOCK(huart); | |
1861 | |
1862 return HAL_OK; | |
1863 } | |
1864 | |
1865 /** | |
1866 * @brief Enables the UART transmitter and disables the UART receiver. | |
1867 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
1868 * the configuration information for the specified UART module. | |
1869 * @retval HAL status | |
1870 */ | |
1871 HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart) | |
1872 { | |
1873 uint32_t tmpreg = 0x00U; | |
1874 | |
1875 /* Process Locked */ | |
1876 __HAL_LOCK(huart); | |
1877 | |
1878 huart->gState = HAL_UART_STATE_BUSY; | |
1879 | |
1880 /*-------------------------- USART CR1 Configuration -----------------------*/ | |
1881 tmpreg = huart->Instance->CR1; | |
1882 | |
1883 /* Clear TE and RE bits */ | |
1884 tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE)); | |
1885 | |
1886 /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */ | |
1887 tmpreg |= (uint32_t)USART_CR1_TE; | |
1888 | |
1889 /* Write to USART CR1 */ | |
1890 WRITE_REG(huart->Instance->CR1, (uint32_t)tmpreg); | |
1891 | |
1892 huart->gState = HAL_UART_STATE_READY; | |
1893 | |
1894 /* Process Unlocked */ | |
1895 __HAL_UNLOCK(huart); | |
1896 | |
1897 return HAL_OK; | |
1898 } | |
1899 | |
1900 /** | |
1901 * @brief Enables the UART receiver and disables the UART transmitter. | |
1902 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
1903 * the configuration information for the specified UART module. | |
1904 * @retval HAL status | |
1905 */ | |
1906 HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart) | |
1907 { | |
1908 uint32_t tmpreg = 0x00U; | |
1909 | |
1910 /* Process Locked */ | |
1911 __HAL_LOCK(huart); | |
1912 | |
1913 huart->gState = HAL_UART_STATE_BUSY; | |
1914 | |
1915 /*-------------------------- USART CR1 Configuration -----------------------*/ | |
1916 tmpreg = huart->Instance->CR1; | |
1917 | |
1918 /* Clear TE and RE bits */ | |
1919 tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE)); | |
1920 | |
1921 /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */ | |
1922 tmpreg |= (uint32_t)USART_CR1_RE; | |
1923 | |
1924 /* Write to USART CR1 */ | |
1925 WRITE_REG(huart->Instance->CR1, (uint32_t)tmpreg); | |
1926 | |
1927 huart->gState = HAL_UART_STATE_READY; | |
1928 | |
1929 /* Process Unlocked */ | |
1930 __HAL_UNLOCK(huart); | |
1931 | |
1932 return HAL_OK; | |
1933 } | |
1934 | |
1935 /** | |
1936 * @} | |
1937 */ | |
1938 | |
1939 /** @defgroup UART_Exported_Functions_Group4 Peripheral State and Errors functions | |
1940 * @brief UART State and Errors functions | |
1941 * | |
1942 @verbatim | |
1943 ============================================================================== | |
1944 ##### Peripheral State and Errors functions ##### | |
1945 ============================================================================== | |
1946 [..] | |
1947 This subsection provides a set of functions allowing to return the State of | |
1948 UART communication process, return Peripheral Errors occurred during communication | |
1949 process | |
1950 (+) HAL_UART_GetState() API can be helpful to check in run-time the state of the UART peripheral. | |
1951 (+) HAL_UART_GetError() check in run-time errors that could be occurred during communication. | |
1952 | |
1953 @endverbatim | |
1954 * @{ | |
1955 */ | |
1956 | |
1957 /** | |
1958 * @brief Returns the UART state. | |
1959 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
1960 * the configuration information for the specified UART module. | |
1961 * @retval HAL state | |
1962 */ | |
1963 HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart) | |
1964 { | |
1965 uint32_t temp1= 0x00U, temp2 = 0x00U; | |
1966 temp1 = huart->gState; | |
1967 temp2 = huart->RxState; | |
1968 | |
1969 return (HAL_UART_StateTypeDef)(temp1 | temp2); | |
1970 } | |
1971 | |
1972 /** | |
1973 * @brief Return the UART error code | |
1974 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
1975 * the configuration information for the specified UART. | |
1976 * @retval UART Error Code | |
1977 */ | |
1978 uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart) | |
1979 { | |
1980 return huart->ErrorCode; | |
1981 } | |
1982 | |
1983 /** | |
1984 * @} | |
1985 */ | |
1986 | |
1987 /** | |
1988 * @brief DMA UART transmit process complete callback. | |
1989 * @param hdma DMA handle | |
1990 * @retval None | |
1991 */ | |
1992 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma) | |
1993 { | |
1994 UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; | |
1995 /* DMA Normal mode*/ | |
1996 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U) | |
1997 { | |
1998 huart->TxXferCount = 0U; | |
1999 | |
2000 /* Disable the DMA transfer for transmit request by setting the DMAT bit | |
2001 in the UART CR3 register */ | |
2002 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); | |
2003 | |
2004 /* Enable the UART Transmit Complete Interrupt */ | |
2005 SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); | |
2006 | |
2007 } | |
2008 /* DMA Circular mode */ | |
2009 else | |
2010 { | |
2011 HAL_UART_TxCpltCallback(huart); | |
2012 } | |
2013 } | |
2014 | |
2015 /** | |
2016 * @brief DMA UART transmit process half complete callback | |
2017 * @param hdma pointer to a DMA_HandleTypeDef structure that contains | |
2018 * the configuration information for the specified DMA module. | |
2019 * @retval None | |
2020 */ | |
2021 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma) | |
2022 { | |
2023 UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; | |
2024 | |
2025 HAL_UART_TxHalfCpltCallback(huart); | |
2026 } | |
2027 | |
2028 /** | |
2029 * @brief DMA UART receive process complete callback. | |
2030 * @param hdma DMA handle | |
2031 * @retval None | |
2032 */ | |
2033 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) | |
2034 { | |
2035 UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; | |
2036 /* DMA Normal mode*/ | |
2037 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U) | |
2038 { | |
2039 huart->RxXferCount = 0U; | |
2040 | |
2041 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ | |
2042 CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); | |
2043 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); | |
2044 | |
2045 /* Disable the DMA transfer for the receiver request by setting the DMAR bit | |
2046 in the UART CR3 register */ | |
2047 CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); | |
2048 | |
2049 /* At end of Rx process, restore huart->RxState to Ready */ | |
2050 huart->RxState = HAL_UART_STATE_READY; | |
2051 } | |
2052 HAL_UART_RxCpltCallback(huart); | |
2053 } | |
2054 | |
2055 /** | |
2056 * @brief DMA UART receive process half complete callback | |
2057 * @param hdma pointer to a DMA_HandleTypeDef structure that contains | |
2058 * the configuration information for the specified DMA module. | |
2059 * @retval None | |
2060 */ | |
2061 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma) | |
2062 { | |
2063 UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; | |
2064 | |
2065 HAL_UART_RxHalfCpltCallback(huart); | |
2066 } | |
2067 | |
2068 /** | |
2069 * @brief DMA UART communication error callback. | |
2070 * @param hdma DMA handle | |
2071 * @retval None | |
2072 */ | |
2073 static void UART_DMAError(DMA_HandleTypeDef *hdma) | |
2074 { | |
2075 uint32_t dmarequest = 0x00U; | |
2076 UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; | |
2077 | |
2078 /* Stop UART DMA Tx request if ongoing */ | |
2079 dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT); | |
2080 if((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest) | |
2081 { | |
2082 huart->TxXferCount = 0U; | |
2083 UART_EndTxTransfer(huart); | |
2084 } | |
2085 | |
2086 /* Stop UART DMA Rx request if ongoing */ | |
2087 dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR); | |
2088 if((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest) | |
2089 { | |
2090 huart->RxXferCount = 0U; | |
2091 UART_EndRxTransfer(huart); | |
2092 } | |
2093 | |
2094 huart->ErrorCode |= HAL_UART_ERROR_DMA; | |
2095 HAL_UART_ErrorCallback(huart); | |
2096 } | |
2097 | |
2098 /** | |
2099 * @brief This function handles UART Communication Timeout. | |
2100 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
2101 * the configuration information for the specified UART module. | |
2102 * @param Flag specifies the UART flag to check. | |
2103 * @param Status The new Flag status (SET or RESET). | |
2104 * @param Tickstart Tick start value | |
2105 * @param Timeout Timeout duration | |
2106 * @retval HAL status | |
2107 */ | |
2108 static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout) | |
2109 { | |
2110 /* Wait until flag is set */ | |
2111 while((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status) | |
2112 { | |
2113 /* Check for the Timeout */ | |
2114 if(Timeout != HAL_MAX_DELAY) | |
2115 { | |
2116 if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout)) | |
2117 { | |
2118 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ | |
2119 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE)); | |
2120 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); | |
2121 | |
2122 huart->gState = HAL_UART_STATE_READY; | |
2123 huart->RxState = HAL_UART_STATE_READY; | |
2124 | |
2125 /* Process Unlocked */ | |
2126 __HAL_UNLOCK(huart); | |
2127 | |
2128 return HAL_TIMEOUT; | |
2129 } | |
2130 } | |
2131 } | |
2132 | |
2133 return HAL_OK; | |
2134 } | |
2135 | |
2136 /** | |
2137 * @brief End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion). | |
2138 * @param huart UART handle. | |
2139 * @retval None | |
2140 */ | |
2141 static void UART_EndTxTransfer(UART_HandleTypeDef *huart) | |
2142 { | |
2143 /* Disable TXEIE and TCIE interrupts */ | |
2144 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE)); | |
2145 | |
2146 /* At end of Tx process, restore huart->gState to Ready */ | |
2147 huart->gState = HAL_UART_STATE_READY; | |
2148 } | |
2149 | |
2150 /** | |
2151 * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion). | |
2152 * @param huart UART handle. | |
2153 * @retval None | |
2154 */ | |
2155 static void UART_EndRxTransfer(UART_HandleTypeDef *huart) | |
2156 { | |
2157 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ | |
2158 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); | |
2159 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); | |
2160 | |
2161 /* At end of Rx process, restore huart->RxState to Ready */ | |
2162 huart->RxState = HAL_UART_STATE_READY; | |
2163 } | |
2164 | |
2165 /** | |
2166 * @brief DMA UART communication abort callback, when initiated by HAL services on Error | |
2167 * (To be called at end of DMA Abort procedure following error occurrence). | |
2168 * @param hdma DMA handle. | |
2169 * @retval None | |
2170 */ | |
2171 static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma) | |
2172 { | |
2173 UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; | |
2174 huart->RxXferCount = 0U; | |
2175 huart->TxXferCount = 0U; | |
2176 | |
2177 HAL_UART_ErrorCallback(huart); | |
2178 } | |
2179 | |
2180 /** | |
2181 * @brief DMA UART Tx communication abort callback, when initiated by user | |
2182 * (To be called at end of DMA Tx Abort procedure following user abort request). | |
2183 * @note When this callback is executed, User Abort complete call back is called only if no | |
2184 * Abort still ongoing for Rx DMA Handle. | |
2185 * @param hdma DMA handle. | |
2186 * @retval None | |
2187 */ | |
2188 static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma) | |
2189 { | |
2190 UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; | |
2191 | |
2192 huart->hdmatx->XferAbortCallback = NULL; | |
2193 | |
2194 /* Check if an Abort process is still ongoing */ | |
2195 if(huart->hdmarx != NULL) | |
2196 { | |
2197 if(huart->hdmarx->XferAbortCallback != NULL) | |
2198 { | |
2199 return; | |
2200 } | |
2201 } | |
2202 | |
2203 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ | |
2204 huart->TxXferCount = 0x00U; | |
2205 huart->RxXferCount = 0x00U; | |
2206 | |
2207 /* Reset ErrorCode */ | |
2208 huart->ErrorCode = HAL_UART_ERROR_NONE; | |
2209 | |
2210 /* Restore huart->gState and huart->RxState to Ready */ | |
2211 huart->gState = HAL_UART_STATE_READY; | |
2212 huart->RxState = HAL_UART_STATE_READY; | |
2213 | |
2214 /* Call user Abort complete callback */ | |
2215 HAL_UART_AbortCpltCallback(huart); | |
2216 } | |
2217 | |
2218 /** | |
2219 * @brief DMA UART Rx communication abort callback, when initiated by user | |
2220 * (To be called at end of DMA Rx Abort procedure following user abort request). | |
2221 * @note When this callback is executed, User Abort complete call back is called only if no | |
2222 * Abort still ongoing for Tx DMA Handle. | |
2223 * @param hdma DMA handle. | |
2224 * @retval None | |
2225 */ | |
2226 static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma) | |
2227 { | |
2228 UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; | |
2229 | |
2230 huart->hdmarx->XferAbortCallback = NULL; | |
2231 | |
2232 /* Check if an Abort process is still ongoing */ | |
2233 if(huart->hdmatx != NULL) | |
2234 { | |
2235 if(huart->hdmatx->XferAbortCallback != NULL) | |
2236 { | |
2237 return; | |
2238 } | |
2239 } | |
2240 | |
2241 /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ | |
2242 huart->TxXferCount = 0x00U; | |
2243 huart->RxXferCount = 0x00U; | |
2244 | |
2245 /* Reset ErrorCode */ | |
2246 huart->ErrorCode = HAL_UART_ERROR_NONE; | |
2247 | |
2248 /* Restore huart->gState and huart->RxState to Ready */ | |
2249 huart->gState = HAL_UART_STATE_READY; | |
2250 huart->RxState = HAL_UART_STATE_READY; | |
2251 | |
2252 /* Call user Abort complete callback */ | |
2253 HAL_UART_AbortCpltCallback(huart); | |
2254 } | |
2255 | |
2256 /** | |
2257 * @brief DMA UART Tx communication abort callback, when initiated by user by a call to | |
2258 * HAL_UART_AbortTransmit_IT API (Abort only Tx transfer) | |
2259 * (This callback is executed at end of DMA Tx Abort procedure following user abort request, | |
2260 * and leads to user Tx Abort Complete callback execution). | |
2261 * @param hdma DMA handle. | |
2262 * @retval None | |
2263 */ | |
2264 static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma) | |
2265 { | |
2266 UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; | |
2267 | |
2268 huart->TxXferCount = 0x00U; | |
2269 | |
2270 /* Restore huart->gState to Ready */ | |
2271 huart->gState = HAL_UART_STATE_READY; | |
2272 | |
2273 /* Call user Abort complete callback */ | |
2274 HAL_UART_AbortTransmitCpltCallback(huart); | |
2275 } | |
2276 | |
2277 /** | |
2278 * @brief DMA UART Rx communication abort callback, when initiated by user by a call to | |
2279 * HAL_UART_AbortReceive_IT API (Abort only Rx transfer) | |
2280 * (This callback is executed at end of DMA Rx Abort procedure following user abort request, | |
2281 * and leads to user Rx Abort Complete callback execution). | |
2282 * @param hdma DMA handle. | |
2283 * @retval None | |
2284 */ | |
2285 static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma) | |
2286 { | |
2287 UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; | |
2288 | |
2289 huart->RxXferCount = 0x00U; | |
2290 | |
2291 /* Restore huart->RxState to Ready */ | |
2292 huart->RxState = HAL_UART_STATE_READY; | |
2293 | |
2294 /* Call user Abort complete callback */ | |
2295 HAL_UART_AbortReceiveCpltCallback(huart); | |
2296 } | |
2297 | |
2298 /** | |
2299 * @brief Sends an amount of data in non blocking mode. | |
2300 * @param huart Pointer to a UART_HandleTypeDef structure that contains | |
2301 * the configuration information for the specified UART module. | |
2302 * @retval HAL status | |
2303 */ | |
2304 static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart) | |
2305 { | |
2306 uint16_t* tmp; | |
2307 | |
2308 /* Check that a Tx process is ongoing */ | |
2309 if(huart->gState == HAL_UART_STATE_BUSY_TX) | |
2310 { | |
2311 if(huart->Init.WordLength == UART_WORDLENGTH_9B) | |
2312 { | |
2313 tmp = (uint16_t*) huart->pTxBuffPtr; | |
2314 huart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF); | |
2315 if(huart->Init.Parity == UART_PARITY_NONE) | |
2316 { | |
2317 huart->pTxBuffPtr += 2U; | |
2318 } | |
2319 else | |
2320 { | |
2321 huart->pTxBuffPtr += 1U; | |
2322 } | |
2323 } | |
2324 else | |
2325 { | |
2326 huart->Instance->DR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0x00FF); | |
2327 } | |
2328 | |
2329 if(--huart->TxXferCount == 0U) | |
2330 { | |
2331 /* Disable the UART Transmit Complete Interrupt */ | |
2332 CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE); | |
2333 | |
2334 /* Enable the UART Transmit Complete Interrupt */ | |
2335 SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); | |
2336 } | |
2337 return HAL_OK; | |
2338 } | |
2339 else | |
2340 { | |
2341 return HAL_BUSY; | |
2342 } | |
2343 } | |
2344 | |
2345 /** | |
2346 * @brief Wraps up transmission in non blocking mode. | |
2347 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
2348 * the configuration information for the specified UART module. | |
2349 * @retval HAL status | |
2350 */ | |
2351 static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart) | |
2352 { | |
2353 /* Disable the UART Transmit Complete Interrupt */ | |
2354 CLEAR_BIT(huart->Instance->CR1, USART_CR1_TCIE); | |
2355 | |
2356 /* Tx process is ended, restore huart->gState to Ready */ | |
2357 huart->gState = HAL_UART_STATE_READY; | |
2358 | |
2359 HAL_UART_TxCpltCallback(huart); | |
2360 | |
2361 return HAL_OK; | |
2362 } | |
2363 | |
2364 /** | |
2365 * @brief Receives an amount of data in non blocking mode | |
2366 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
2367 * the configuration information for the specified UART module. | |
2368 * @retval HAL status | |
2369 */ | |
2370 static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart) | |
2371 { | |
2372 uint16_t* tmp; | |
2373 | |
2374 /* Check that a Rx process is ongoing */ | |
2375 if(huart->RxState == HAL_UART_STATE_BUSY_RX) | |
2376 { | |
2377 if(huart->Init.WordLength == UART_WORDLENGTH_9B) | |
2378 { | |
2379 tmp = (uint16_t*) huart->pRxBuffPtr; | |
2380 if(huart->Init.Parity == UART_PARITY_NONE) | |
2381 { | |
2382 *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF); | |
2383 huart->pRxBuffPtr += 2U; | |
2384 } | |
2385 else | |
2386 { | |
2387 *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF); | |
2388 huart->pRxBuffPtr += 1U; | |
2389 } | |
2390 } | |
2391 else | |
2392 { | |
2393 if(huart->Init.Parity == UART_PARITY_NONE) | |
2394 { | |
2395 *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF); | |
2396 } | |
2397 else | |
2398 { | |
2399 *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F); | |
2400 } | |
2401 } | |
2402 | |
2403 if(--huart->RxXferCount == 0U) | |
2404 { | |
2405 /* Disable the UART Parity Error Interrupt and RXNE interrupt*/ | |
2406 CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); | |
2407 | |
2408 /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ | |
2409 CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); | |
2410 | |
2411 /* Rx process is completed, restore huart->RxState to Ready */ | |
2412 huart->RxState = HAL_UART_STATE_READY; | |
2413 | |
2414 HAL_UART_RxCpltCallback(huart); | |
2415 | |
2416 return HAL_OK; | |
2417 } | |
2418 return HAL_OK; | |
2419 } | |
2420 else | |
2421 { | |
2422 return HAL_BUSY; | |
2423 } | |
2424 } | |
2425 | |
2426 /** | |
2427 * @brief Configures the UART peripheral. | |
2428 * @param huart pointer to a UART_HandleTypeDef structure that contains | |
2429 * the configuration information for the specified UART module. | |
2430 * @retval None | |
2431 */ | |
2432 static void UART_SetConfig(UART_HandleTypeDef *huart) | |
2433 { | |
2434 uint32_t tmpreg = 0x00U; | |
2435 | |
2436 /* Check the parameters */ | |
2437 assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate)); | |
2438 assert_param(IS_UART_STOPBITS(huart->Init.StopBits)); | |
2439 assert_param(IS_UART_PARITY(huart->Init.Parity)); | |
2440 assert_param(IS_UART_MODE(huart->Init.Mode)); | |
2441 | |
2442 /*-------------------------- USART CR2 Configuration -----------------------*/ | |
2443 tmpreg = huart->Instance->CR2; | |
2444 | |
2445 /* Clear STOP[13:12] bits */ | |
2446 tmpreg &= (uint32_t)~((uint32_t)USART_CR2_STOP); | |
2447 | |
2448 /* Configure the UART Stop Bits: Set STOP[13:12] bits according to huart->Init.StopBits value */ | |
2449 tmpreg |= (uint32_t)huart->Init.StopBits; | |
2450 | |
2451 /* Write to USART CR2 */ | |
2452 WRITE_REG(huart->Instance->CR2, (uint32_t)tmpreg); | |
2453 | |
2454 /*-------------------------- USART CR1 Configuration -----------------------*/ | |
2455 tmpreg = huart->Instance->CR1; | |
2456 | |
2457 /* Clear M, PCE, PS, TE and RE bits */ | |
2458 tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | \ | |
2459 USART_CR1_RE | USART_CR1_OVER8)); | |
2460 | |
2461 /* Configure the UART Word Length, Parity and mode: | |
2462 Set the M bits according to huart->Init.WordLength value | |
2463 Set PCE and PS bits according to huart->Init.Parity value | |
2464 Set TE and RE bits according to huart->Init.Mode value | |
2465 Set OVER8 bit according to huart->Init.OverSampling value */ | |
2466 tmpreg |= (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling; | |
2467 | |
2468 /* Write to USART CR1 */ | |
2469 WRITE_REG(huart->Instance->CR1, (uint32_t)tmpreg); | |
2470 | |
2471 /*-------------------------- USART CR3 Configuration -----------------------*/ | |
2472 tmpreg = huart->Instance->CR3; | |
2473 | |
2474 /* Clear CTSE and RTSE bits */ | |
2475 tmpreg &= (uint32_t)~((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE)); | |
2476 | |
2477 /* Configure the UART HFC: Set CTSE and RTSE bits according to huart->Init.HwFlowCtl value */ | |
2478 tmpreg |= huart->Init.HwFlowCtl; | |
2479 | |
2480 /* Write to USART CR3 */ | |
2481 WRITE_REG(huart->Instance->CR3, (uint32_t)tmpreg); | |
2482 | |
2483 /* Check the Over Sampling */ | |
2484 if(huart->Init.OverSampling == UART_OVERSAMPLING_8) | |
2485 { | |
2486 /*-------------------------- USART BRR Configuration ---------------------*/ | |
2487 #if defined(USART6) | |
2488 if((huart->Instance == USART1) || (huart->Instance == USART6)) | |
2489 { | |
2490 huart->Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate); | |
2491 } | |
2492 #else | |
2493 if(huart->Instance == USART1) | |
2494 { | |
2495 huart->Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate); | |
2496 } | |
2497 #endif /* USART6 */ | |
2498 else | |
2499 { | |
2500 huart->Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate); | |
2501 } | |
2502 } | |
2503 else | |
2504 { | |
2505 /*-------------------------- USART BRR Configuration ---------------------*/ | |
2506 #if defined(USART6) | |
2507 if((huart->Instance == USART1) || (huart->Instance == USART6)) | |
2508 { | |
2509 huart->Instance->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate); | |
2510 } | |
2511 #else | |
2512 if(huart->Instance == USART1) | |
2513 { | |
2514 huart->Instance->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate); | |
2515 } | |
2516 #endif /* USART6 */ | |
2517 else | |
2518 { | |
2519 huart->Instance->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate); | |
2520 } | |
2521 } | |
2522 } | |
2523 | |
2524 /** | |
2525 * @} | |
2526 */ | |
2527 | |
2528 #endif /* HAL_UART_MODULE_ENABLED */ | |
2529 /** | |
2530 * @} | |
2531 */ | |
2532 | |
2533 /** | |
2534 * @} | |
2535 */ | |
2536 | |
2537 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |