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