1 /**
2 ******************************************************************************
3 * @file stm32l0xx_hal_uart_ex.c
4 * @author MCD Application Team
5 * @brief Extended UART HAL module driver.
6 * This file provides firmware functions to manage the following extended
7 * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART).
8 * + Initialization and de-initialization functions
9 * + Peripheral Control functions
10 *
11 *
12 @verbatim
13 ==============================================================================
14 ##### UART peripheral extended features #####
15 ==============================================================================
16
17 (#) Declare a UART_HandleTypeDef handle structure.
18
19 (#) For the UART RS485 Driver Enable mode, initialize the UART registers
20 by calling the HAL_RS485Ex_Init() API.
21
22 @endverbatim
23 ******************************************************************************
24 * @attention
25 *
26 * <h2><center>© Copyright (c) 2016 STMicroelectronics.
27 * All rights reserved.</center></h2>
28 *
29 * This software component is licensed by ST under BSD 3-Clause license,
30 * the "License"; You may not use this file except in compliance with the
31 * License. You may obtain a copy of the License at:
32 * opensource.org/licenses/BSD-3-Clause
33 *
34 ******************************************************************************
35 */
36
37 /* Includes ------------------------------------------------------------------*/
38 #include "stm32l0xx_hal.h"
39
40 /** @addtogroup STM32L0xx_HAL_Driver
41 * @{
42 */
43
44 /** @defgroup UARTEx UARTEx
45 * @brief UART Extended HAL module driver
46 * @{
47 */
48
49 #ifdef HAL_UART_MODULE_ENABLED
50
51 /* Private typedef -----------------------------------------------------------*/
52 /* Private define ------------------------------------------------------------*/
53
54 /* Private macros ------------------------------------------------------------*/
55 /* Private variables ---------------------------------------------------------*/
56 /* Private function prototypes -----------------------------------------------*/
57 /** @defgroup UARTEx_Private_Functions UARTEx Private Functions
58 * @{
59 */
60 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
61 extern void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart);
62 #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
63 static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection);
64 /**
65 * @}
66 */
67
68 /* Exported functions --------------------------------------------------------*/
69
70 /** @defgroup UARTEx_Exported_Functions UARTEx Exported Functions
71 * @{
72 */
73
74 /** @defgroup UARTEx_Exported_Functions_Group1 Initialization and de-initialization functions
75 * @brief Extended Initialization and Configuration Functions
76 *
77 @verbatim
78 ===============================================================================
79 ##### Initialization and Configuration functions #####
80 ===============================================================================
81 [..]
82 This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
83 in asynchronous mode.
84 (+) For the asynchronous mode the parameters below can be configured:
85 (++) Baud Rate
86 (++) Word Length
87 (++) Stop Bit
88 (++) Parity: If the parity is enabled, then the MSB bit of the data written
89 in the data register is transmitted but is changed by the parity bit.
90 (++) Hardware flow control
91 (++) Receiver/transmitter modes
92 (++) Over Sampling Method
93 (++) One-Bit Sampling Method
94 (+) For the asynchronous mode, the following advanced features can be configured as well:
95 (++) TX and/or RX pin level inversion
96 (++) data logical level inversion
97 (++) RX and TX pins swap
98 (++) RX overrun detection disabling
99 (++) DMA disabling on RX error
100 (++) MSB first on communication line
101 (++) auto Baud rate detection
102 [..]
103 The HAL_RS485Ex_Init() API follows the UART RS485 mode configuration
104 procedures (details for the procedures are available in reference manual).
105
106 @endverbatim
107
108 Depending on the frame length defined by the M1 and M0 bits (7-bit,
109 8-bit or 9-bit), the possible UART formats are listed in the
110 following table.
111
112 Table 1. UART frame format.
113 +-----------------------------------------------------------------------+
114 | M1 bit | M0 bit | PCE bit | UART frame |
115 |---------|---------|-----------|---------------------------------------|
116 | 0 | 0 | 0 | | SB | 8 bit data | STB | |
117 |---------|---------|-----------|---------------------------------------|
118 | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | |
119 |---------|---------|-----------|---------------------------------------|
120 | 0 | 1 | 0 | | SB | 9 bit data | STB | |
121 |---------|---------|-----------|---------------------------------------|
122 | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | |
123 |---------|---------|-----------|---------------------------------------|
124 | 1 | 0 | 0 | | SB | 7 bit data | STB | |
125 |---------|---------|-----------|---------------------------------------|
126 | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | |
127 +-----------------------------------------------------------------------+
128
129 * @{
130 */
131
132 /**
133 * @brief Initialize the RS485 Driver enable feature according to the specified
134 * parameters in the UART_InitTypeDef and creates the associated handle.
135 * @param huart UART handle.
136 * @param Polarity Select the driver enable polarity.
137 * This parameter can be one of the following values:
138 * @arg @ref UART_DE_POLARITY_HIGH DE signal is active high
139 * @arg @ref UART_DE_POLARITY_LOW DE signal is active low
140 * @param AssertionTime Driver Enable assertion time:
141 * 5-bit value defining the time between the activation of the DE (Driver Enable)
142 * signal and the beginning of the start bit. It is expressed in sample time
143 * units (1/8 or 1/16 bit time, depending on the oversampling rate)
144 * @param DeassertionTime Driver Enable deassertion time:
145 * 5-bit value defining the time between the end of the last stop bit, in a
146 * transmitted message, and the de-activation of the DE (Driver Enable) signal.
147 * It is expressed in sample time units (1/8 or 1/16 bit time, depending on the
148 * oversampling rate).
149 * @retval HAL status
150 */
HAL_RS485Ex_Init(UART_HandleTypeDef * huart,uint32_t Polarity,uint32_t AssertionTime,uint32_t DeassertionTime)151 HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, uint32_t AssertionTime, uint32_t DeassertionTime)
152 {
153 uint32_t temp;
154
155 /* Check the UART handle allocation */
156 if (huart == NULL)
157 {
158 return HAL_ERROR;
159 }
160 /* Check the Driver Enable UART instance */
161 assert_param(IS_UART_DRIVER_ENABLE_INSTANCE(huart->Instance));
162
163 /* Check the Driver Enable polarity */
164 assert_param(IS_UART_DE_POLARITY(Polarity));
165
166 /* Check the Driver Enable assertion time */
167 assert_param(IS_UART_ASSERTIONTIME(AssertionTime));
168
169 /* Check the Driver Enable deassertion time */
170 assert_param(IS_UART_DEASSERTIONTIME(DeassertionTime));
171
172 if (huart->gState == HAL_UART_STATE_RESET)
173 {
174 /* Allocate lock resource and initialize it */
175 huart->Lock = HAL_UNLOCKED;
176
177 #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
178 UART_InitCallbacksToDefault(huart);
179
180 if (huart->MspInitCallback == NULL)
181 {
182 huart->MspInitCallback = HAL_UART_MspInit;
183 }
184
185 /* Init the low level hardware */
186 huart->MspInitCallback(huart);
187 #else
188 /* Init the low level hardware : GPIO, CLOCK, CORTEX */
189 HAL_UART_MspInit(huart);
190 #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
191 }
192
193 huart->gState = HAL_UART_STATE_BUSY;
194
195 /* Disable the Peripheral */
196 __HAL_UART_DISABLE(huart);
197
198 /* Set the UART Communication parameters */
199 if (UART_SetConfig(huart) == HAL_ERROR)
200 {
201 return HAL_ERROR;
202 }
203
204 if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
205 {
206 UART_AdvFeatureConfig(huart);
207 }
208
209 /* Enable the Driver Enable mode by setting the DEM bit in the CR3 register */
210 SET_BIT(huart->Instance->CR3, USART_CR3_DEM);
211
212 /* Set the Driver Enable polarity */
213 MODIFY_REG(huart->Instance->CR3, USART_CR3_DEP, Polarity);
214
215 /* Set the Driver Enable assertion and deassertion times */
216 temp = (AssertionTime << UART_CR1_DEAT_ADDRESS_LSB_POS);
217 temp |= (DeassertionTime << UART_CR1_DEDT_ADDRESS_LSB_POS);
218 MODIFY_REG(huart->Instance->CR1, (USART_CR1_DEDT | USART_CR1_DEAT), temp);
219
220 /* Enable the Peripheral */
221 __HAL_UART_ENABLE(huart);
222
223 /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
224 return (UART_CheckIdleState(huart));
225 }
226
227 /**
228 * @}
229 */
230
231 /** @defgroup UARTEx_Exported_Functions_Group2 IO operation functions
232 * @brief Extended functions
233 *
234 @verbatim
235 ===============================================================================
236 ##### IO operation functions #####
237 ===============================================================================
238 This subsection provides a set of Wakeup and FIFO mode related callback functions.
239
240 (#) Wakeup from Stop mode Callback:
241 (+) HAL_UARTEx_WakeupCallback()
242
243 @endverbatim
244 * @{
245 */
246
247 /**
248 * @brief UART wakeup from Stop mode callback.
249 * @param huart UART handle.
250 * @retval None
251 */
HAL_UARTEx_WakeupCallback(UART_HandleTypeDef * huart)252 __weak void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart)
253 {
254 /* Prevent unused argument(s) compilation warning */
255 UNUSED(huart);
256
257 /* NOTE : This function should not be modified, when the callback is needed,
258 the HAL_UARTEx_WakeupCallback can be implemented in the user file.
259 */
260 }
261
262
263 /**
264 * @}
265 */
266
267 /** @defgroup UARTEx_Exported_Functions_Group3 Peripheral Control functions
268 * @brief Extended Peripheral Control functions
269 *
270 @verbatim
271 ===============================================================================
272 ##### Peripheral Control functions #####
273 ===============================================================================
274 [..] This section provides the following functions:
275 (+) HAL_UARTEx_EnableClockStopMode() API enables the UART clock (HSI or LSE only) during stop mode
276 (+) HAL_UARTEx_DisableClockStopMode() API disables the above functionality
277 (+) HAL_MultiProcessorEx_AddressLength_Set() API optionally sets the UART node address
278 detection length to more than 4 bits for multiprocessor address mark wake up.
279 (+) HAL_UARTEx_StopModeWakeUpSourceConfig() API defines the wake-up from stop mode
280 trigger: address match, Start Bit detection or RXNE bit status.
281 (+) HAL_UARTEx_EnableStopMode() API enables the UART to wake up the MCU from stop mode
282 (+) HAL_UARTEx_DisableStopMode() API disables the above functionality
283
284 @endverbatim
285 * @{
286 */
287
288
289
290 /**
291 * @brief Keep UART Clock enabled when in Stop Mode.
292 * @note When the USART clock source is configured to be LSE or HSI, it is possible to keep enabled
293 * this clock during STOP mode by setting the UCESM bit in USART_CR3 control register.
294 * @note When LPUART is used to wakeup from stop with LSE is selected as LPUART clock source,
295 * and desired baud rate is 9600 baud, the bit UCESM bit in LPUART_CR3 control register must be set.
296 * @param huart UART handle.
297 * @retval HAL status
298 */
HAL_UARTEx_EnableClockStopMode(UART_HandleTypeDef * huart)299 HAL_StatusTypeDef HAL_UARTEx_EnableClockStopMode(UART_HandleTypeDef *huart)
300 {
301 /* Process Locked */
302 __HAL_LOCK(huart);
303
304 /* Set UCESM bit */
305 SET_BIT(huart->Instance->CR3, USART_CR3_UCESM);
306
307 /* Process Unlocked */
308 __HAL_UNLOCK(huart);
309
310 return HAL_OK;
311 }
312
313 /**
314 * @brief Disable UART Clock when in Stop Mode.
315 * @param huart UART handle.
316 * @retval HAL status
317 */
HAL_UARTEx_DisableClockStopMode(UART_HandleTypeDef * huart)318 HAL_StatusTypeDef HAL_UARTEx_DisableClockStopMode(UART_HandleTypeDef *huart)
319 {
320 /* Process Locked */
321 __HAL_LOCK(huart);
322
323 /* Clear UCESM bit */
324 CLEAR_BIT(huart->Instance->CR3, USART_CR3_UCESM);
325
326 /* Process Unlocked */
327 __HAL_UNLOCK(huart);
328
329 return HAL_OK;
330 }
331
332 /**
333 * @brief By default in multiprocessor mode, when the wake up method is set
334 * to address mark, the UART handles only 4-bit long addresses detection;
335 * this API allows to enable longer addresses detection (6-, 7- or 8-bit
336 * long).
337 * @note Addresses detection lengths are: 6-bit address detection in 7-bit data mode,
338 * 7-bit address detection in 8-bit data mode, 8-bit address detection in 9-bit data mode.
339 * @param huart UART handle.
340 * @param AddressLength This parameter can be one of the following values:
341 * @arg @ref UART_ADDRESS_DETECT_4B 4-bit long address
342 * @arg @ref UART_ADDRESS_DETECT_7B 6-, 7- or 8-bit long address
343 * @retval HAL status
344 */
HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef * huart,uint32_t AddressLength)345 HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *huart, uint32_t AddressLength)
346 {
347 /* Check the UART handle allocation */
348 if (huart == NULL)
349 {
350 return HAL_ERROR;
351 }
352
353 /* Check the address length parameter */
354 assert_param(IS_UART_ADDRESSLENGTH_DETECT(AddressLength));
355
356 huart->gState = HAL_UART_STATE_BUSY;
357
358 /* Disable the Peripheral */
359 __HAL_UART_DISABLE(huart);
360
361 /* Set the address length */
362 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, AddressLength);
363
364 /* Enable the Peripheral */
365 __HAL_UART_ENABLE(huart);
366
367 /* TEACK and/or REACK to check before moving huart->gState to Ready */
368 return (UART_CheckIdleState(huart));
369 }
370
371 /**
372 * @brief Set Wakeup from Stop mode interrupt flag selection.
373 * @note It is the application responsibility to enable the interrupt used as
374 * usart_wkup interrupt source before entering low-power mode.
375 * @param huart UART handle.
376 * @param WakeUpSelection Address match, Start Bit detection or RXNE/RXFNE bit status.
377 * This parameter can be one of the following values:
378 * @arg @ref UART_WAKEUP_ON_ADDRESS
379 * @arg @ref UART_WAKEUP_ON_STARTBIT
380 * @arg @ref UART_WAKEUP_ON_READDATA_NONEMPTY
381 * @retval HAL status
382 */
HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef * huart,UART_WakeUpTypeDef WakeUpSelection)383 HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
384 {
385 HAL_StatusTypeDef status = HAL_OK;
386 uint32_t tickstart;
387
388 /* check the wake-up from stop mode UART instance */
389 assert_param(IS_UART_WAKEUP_FROMSTOP_INSTANCE(huart->Instance));
390 /* check the wake-up selection parameter */
391 assert_param(IS_UART_WAKEUP_SELECTION(WakeUpSelection.WakeUpEvent));
392
393 /* Process Locked */
394 __HAL_LOCK(huart);
395
396 huart->gState = HAL_UART_STATE_BUSY;
397
398 /* Disable the Peripheral */
399 __HAL_UART_DISABLE(huart);
400
401 /* Set the wake-up selection scheme */
402 MODIFY_REG(huart->Instance->CR3, USART_CR3_WUS, WakeUpSelection.WakeUpEvent);
403
404 if (WakeUpSelection.WakeUpEvent == UART_WAKEUP_ON_ADDRESS)
405 {
406 UARTEx_Wakeup_AddressConfig(huart, WakeUpSelection);
407 }
408
409 /* Enable the Peripheral */
410 __HAL_UART_ENABLE(huart);
411
412 /* Init tickstart for timeout managment*/
413 tickstart = HAL_GetTick();
414
415 /* Wait until REACK flag is set */
416 if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
417 {
418 status = HAL_TIMEOUT;
419 }
420 else
421 {
422 /* Initialize the UART State */
423 huart->gState = HAL_UART_STATE_READY;
424 }
425
426 /* Process Unlocked */
427 __HAL_UNLOCK(huart);
428
429 return status;
430 }
431
432 /**
433 * @brief Enable UART Stop Mode.
434 * @note The UART is able to wake up the MCU from Stop 1 mode as long as UART clock is HSI or LSE.
435 * @param huart UART handle.
436 * @retval HAL status
437 */
HAL_UARTEx_EnableStopMode(UART_HandleTypeDef * huart)438 HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart)
439 {
440 /* Process Locked */
441 __HAL_LOCK(huart);
442
443 /* Set UESM bit */
444 SET_BIT(huart->Instance->CR1, USART_CR1_UESM);
445
446 /* Process Unlocked */
447 __HAL_UNLOCK(huart);
448
449 return HAL_OK;
450 }
451
452 /**
453 * @brief Disable UART Stop Mode.
454 * @param huart UART handle.
455 * @retval HAL status
456 */
HAL_UARTEx_DisableStopMode(UART_HandleTypeDef * huart)457 HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart)
458 {
459 /* Process Locked */
460 __HAL_LOCK(huart);
461
462 /* Clear UESM bit */
463 CLEAR_BIT(huart->Instance->CR1, USART_CR1_UESM);
464
465 /* Process Unlocked */
466 __HAL_UNLOCK(huart);
467
468 return HAL_OK;
469 }
470
471
472 /**
473 * @}
474 */
475
476 /**
477 * @}
478 */
479
480 /** @addtogroup UARTEx_Private_Functions
481 * @{
482 */
483
484 /**
485 * @brief Initialize the UART wake-up from stop mode parameters when triggered by address detection.
486 * @param huart UART handle.
487 * @param WakeUpSelection UART wake up from stop mode parameters.
488 * @retval None
489 */
UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef * huart,UART_WakeUpTypeDef WakeUpSelection)490 static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection)
491 {
492 assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength));
493
494 /* Set the USART address length */
495 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, WakeUpSelection.AddressLength);
496
497 /* Set the USART address node */
498 MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS));
499 }
500
501 /**
502 * @}
503 */
504
505 #endif /* HAL_UART_MODULE_ENABLED */
506
507 /**
508 * @}
509 */
510
511 /**
512 * @}
513 */
514
515 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
516