xref: /btstack/port/stm32-l073rz-nucleo-em9304/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_hal_uart_ex.c (revision e838079242074edcbcbb400962776e15fe6ca6cb)
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>&copy; 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