1 /**
2   ******************************************************************************
3   * @file    stm32f7xx_ll_usart.c
4   * @author  MCD Application Team
5   * @brief   USART LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2017 STMicroelectronics.
10   * All rights reserved.
11   *
12   * This software is licensed under terms that can be found in the LICENSE file
13   * in the root directory of this software component.
14   * If no LICENSE file comes with this software, it is provided AS-IS.
15   *
16   ******************************************************************************
17   */
18 #if defined(USE_FULL_LL_DRIVER)
19 
20 /* Includes ------------------------------------------------------------------*/
21 #include "stm32f7xx_ll_usart.h"
22 #include "stm32f7xx_ll_rcc.h"
23 #include "stm32f7xx_ll_bus.h"
24 #ifdef USE_FULL_ASSERT
25 #include "stm32_assert.h"
26 #else
27 #define assert_param(expr) ((void)0U)
28 #endif /* USE_FULL_ASSERT */
29 
30 /** @addtogroup STM32F7xx_LL_Driver
31   * @{
32   */
33 
34 #if defined (USART1) || defined (USART2) || defined (USART3) || defined (USART6) || defined (UART4) || defined (UART5) || defined (UART7) || defined (UART8)
35 
36 /** @addtogroup USART_LL
37   * @{
38   */
39 
40 /* Private types -------------------------------------------------------------*/
41 /* Private variables ---------------------------------------------------------*/
42 /* Private constants ---------------------------------------------------------*/
43 /* Private macros ------------------------------------------------------------*/
44 /** @addtogroup USART_LL_Private_Macros
45   * @{
46   */
47 
48 /* __BAUDRATE__ The maximum Baud Rate is derived from the maximum clock available
49  *              divided by the smallest oversampling used on the USART (i.e. 8)    */
50 #define IS_LL_USART_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) <= 27000000U)
51 
52 /* __VALUE__ In case of oversampling by 16 and 8, BRR content must be greater than or equal to 16d. */
53 #define IS_LL_USART_BRR_MIN(__VALUE__) ((__VALUE__) >= 16U)
54 
55 #define IS_LL_USART_DIRECTION(__VALUE__) (((__VALUE__) == LL_USART_DIRECTION_NONE) \
56                                           || ((__VALUE__) == LL_USART_DIRECTION_RX) \
57                                           || ((__VALUE__) == LL_USART_DIRECTION_TX) \
58                                           || ((__VALUE__) == LL_USART_DIRECTION_TX_RX))
59 
60 #define IS_LL_USART_PARITY(__VALUE__) (((__VALUE__) == LL_USART_PARITY_NONE) \
61                                        || ((__VALUE__) == LL_USART_PARITY_EVEN) \
62                                        || ((__VALUE__) == LL_USART_PARITY_ODD))
63 
64 #define IS_LL_USART_DATAWIDTH(__VALUE__) (((__VALUE__) == LL_USART_DATAWIDTH_7B) \
65                                           || ((__VALUE__) == LL_USART_DATAWIDTH_8B) \
66                                           || ((__VALUE__) == LL_USART_DATAWIDTH_9B))
67 
68 #define IS_LL_USART_OVERSAMPLING(__VALUE__) (((__VALUE__) == LL_USART_OVERSAMPLING_16) \
69                                              || ((__VALUE__) == LL_USART_OVERSAMPLING_8))
70 
71 #define IS_LL_USART_LASTBITCLKOUTPUT(__VALUE__) (((__VALUE__) == LL_USART_LASTCLKPULSE_NO_OUTPUT) \
72                                                  || ((__VALUE__) == LL_USART_LASTCLKPULSE_OUTPUT))
73 
74 #define IS_LL_USART_CLOCKPHASE(__VALUE__) (((__VALUE__) == LL_USART_PHASE_1EDGE) \
75                                            || ((__VALUE__) == LL_USART_PHASE_2EDGE))
76 
77 #define IS_LL_USART_CLOCKPOLARITY(__VALUE__) (((__VALUE__) == LL_USART_POLARITY_LOW) \
78                                               || ((__VALUE__) == LL_USART_POLARITY_HIGH))
79 
80 #define IS_LL_USART_CLOCKOUTPUT(__VALUE__) (((__VALUE__) == LL_USART_CLOCK_DISABLE) \
81                                             || ((__VALUE__) == LL_USART_CLOCK_ENABLE))
82 
83 #define IS_LL_USART_STOPBITS(__VALUE__) (((__VALUE__) == LL_USART_STOPBITS_0_5) \
84                                          || ((__VALUE__) == LL_USART_STOPBITS_1) \
85                                          || ((__VALUE__) == LL_USART_STOPBITS_1_5) \
86                                          || ((__VALUE__) == LL_USART_STOPBITS_2))
87 
88 #define IS_LL_USART_HWCONTROL(__VALUE__) (((__VALUE__) == LL_USART_HWCONTROL_NONE) \
89                                           || ((__VALUE__) == LL_USART_HWCONTROL_RTS) \
90                                           || ((__VALUE__) == LL_USART_HWCONTROL_CTS) \
91                                           || ((__VALUE__) == LL_USART_HWCONTROL_RTS_CTS))
92 
93 /**
94   * @}
95   */
96 
97 /* Private function prototypes -----------------------------------------------*/
98 
99 /* Exported functions --------------------------------------------------------*/
100 /** @addtogroup USART_LL_Exported_Functions
101   * @{
102   */
103 
104 /** @addtogroup USART_LL_EF_Init
105   * @{
106   */
107 
108 /**
109   * @brief  De-initialize USART registers (Registers restored to their default values).
110   * @param  USARTx USART Instance
111   * @retval An ErrorStatus enumeration value:
112   *          - SUCCESS: USART registers are de-initialized
113   *          - ERROR: USART registers are not de-initialized
114   */
LL_USART_DeInit(const USART_TypeDef * USARTx)115 ErrorStatus LL_USART_DeInit(const USART_TypeDef *USARTx)
116 {
117   ErrorStatus status = SUCCESS;
118 
119   /* Check the parameters */
120   assert_param(IS_UART_INSTANCE(USARTx));
121 
122   if (USARTx == USART1)
123   {
124     /* Force reset of USART clock */
125     LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_USART1);
126 
127     /* Release reset of USART clock */
128     LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_USART1);
129   }
130   else if (USARTx == USART2)
131   {
132     /* Force reset of USART clock */
133     LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_USART2);
134 
135     /* Release reset of USART clock */
136     LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_USART2);
137   }
138   else if (USARTx == USART3)
139   {
140     /* Force reset of USART clock */
141     LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_USART3);
142 
143     /* Release reset of USART clock */
144     LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_USART3);
145   }
146   else if (USARTx == UART4)
147   {
148     /* Force reset of UART clock */
149     LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_UART4);
150 
151     /* Release reset of UART clock */
152     LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_UART4);
153   }
154   else if (USARTx == UART5)
155   {
156     /* Force reset of UART clock */
157     LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_UART5);
158 
159     /* Release reset of UART clock */
160     LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_UART5);
161   }
162   else if (USARTx == USART6)
163   {
164     /* Force reset of USART clock */
165     LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_USART6);
166 
167     /* Release reset of USART clock */
168     LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_USART6);
169   }
170   else if (USARTx == UART7)
171   {
172     /* Force reset of UART clock */
173     LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_UART7);
174 
175     /* Release reset of UART clock */
176     LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_UART7);
177   }
178   else if (USARTx == UART8)
179   {
180     /* Force reset of UART clock */
181     LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_UART8);
182 
183     /* Release reset of UART clock */
184     LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_UART8);
185   }
186   else
187   {
188     status = ERROR;
189   }
190 
191   return (status);
192 }
193 
194 /**
195   * @brief  Initialize USART registers according to the specified
196   *         parameters in USART_InitStruct.
197   * @note   As some bits in USART configuration registers can only be written when
198   *         the USART is disabled (USART_CR1_UE bit =0), USART Peripheral should be in disabled state prior calling
199   *         this function. Otherwise, ERROR result will be returned.
200   * @note   Baud rate value stored in USART_InitStruct BaudRate field, should be valid (different from 0).
201   * @param  USARTx USART Instance
202   * @param  USART_InitStruct pointer to a LL_USART_InitTypeDef structure
203   *         that contains the configuration information for the specified USART peripheral.
204   * @retval An ErrorStatus enumeration value:
205   *          - SUCCESS: USART registers are initialized according to USART_InitStruct content
206   *          - ERROR: Problem occurred during USART Registers initialization
207   */
LL_USART_Init(USART_TypeDef * USARTx,const LL_USART_InitTypeDef * USART_InitStruct)208 ErrorStatus LL_USART_Init(USART_TypeDef *USARTx, const LL_USART_InitTypeDef *USART_InitStruct)
209 {
210   ErrorStatus status = ERROR;
211   uint32_t periphclk = LL_RCC_PERIPH_FREQUENCY_NO;
212 
213   /* Check the parameters */
214   assert_param(IS_UART_INSTANCE(USARTx));
215   assert_param(IS_LL_USART_BAUDRATE(USART_InitStruct->BaudRate));
216   assert_param(IS_LL_USART_DATAWIDTH(USART_InitStruct->DataWidth));
217   assert_param(IS_LL_USART_STOPBITS(USART_InitStruct->StopBits));
218   assert_param(IS_LL_USART_PARITY(USART_InitStruct->Parity));
219   assert_param(IS_LL_USART_DIRECTION(USART_InitStruct->TransferDirection));
220   assert_param(IS_LL_USART_HWCONTROL(USART_InitStruct->HardwareFlowControl));
221   assert_param(IS_LL_USART_OVERSAMPLING(USART_InitStruct->OverSampling));
222 
223   /* USART needs to be in disabled state, in order to be able to configure some bits in
224      CRx registers */
225   if (LL_USART_IsEnabled(USARTx) == 0U)
226   {
227     /*---------------------------- USART CR1 Configuration ---------------------
228      * Configure USARTx CR1 (USART Word Length, Parity, Mode and Oversampling bits) with parameters:
229      * - DataWidth:          USART_CR1_M bits according to USART_InitStruct->DataWidth value
230      * - Parity:             USART_CR1_PCE, USART_CR1_PS bits according to USART_InitStruct->Parity value
231      * - TransferDirection:  USART_CR1_TE, USART_CR1_RE bits according to USART_InitStruct->TransferDirection value
232      * - Oversampling:       USART_CR1_OVER8 bit according to USART_InitStruct->OverSampling value.
233      */
234     MODIFY_REG(USARTx->CR1,
235                (USART_CR1_M | USART_CR1_PCE | USART_CR1_PS |
236                 USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8),
237                (USART_InitStruct->DataWidth | USART_InitStruct->Parity |
238                 USART_InitStruct->TransferDirection | USART_InitStruct->OverSampling));
239 
240     /*---------------------------- USART CR2 Configuration ---------------------
241      * Configure USARTx CR2 (Stop bits) with parameters:
242      * - Stop Bits:          USART_CR2_STOP bits according to USART_InitStruct->StopBits value.
243      * - CLKEN, CPOL, CPHA and LBCL bits are to be configured using LL_USART_ClockInit().
244      */
245     LL_USART_SetStopBitsLength(USARTx, USART_InitStruct->StopBits);
246 
247     /*---------------------------- USART CR3 Configuration ---------------------
248      * Configure USARTx CR3 (Hardware Flow Control) with parameters:
249      * - HardwareFlowControl: USART_CR3_RTSE, USART_CR3_CTSE bits according to
250      *   USART_InitStruct->HardwareFlowControl value.
251      */
252     LL_USART_SetHWFlowCtrl(USARTx, USART_InitStruct->HardwareFlowControl);
253 
254     /*---------------------------- USART BRR Configuration ---------------------
255      * Retrieve Clock frequency used for USART Peripheral
256      */
257     if (USARTx == USART1)
258     {
259       periphclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART1_CLKSOURCE);
260     }
261     else if (USARTx == USART2)
262     {
263       periphclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART2_CLKSOURCE);
264     }
265     else if (USARTx == USART3)
266     {
267       periphclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART3_CLKSOURCE);
268     }
269     else if (USARTx == UART4)
270     {
271       periphclk = LL_RCC_GetUARTClockFreq(LL_RCC_UART4_CLKSOURCE);
272     }
273     else if (USARTx == UART5)
274     {
275       periphclk = LL_RCC_GetUARTClockFreq(LL_RCC_UART5_CLKSOURCE);
276     }
277     else if (USARTx == USART6)
278     {
279       periphclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART6_CLKSOURCE);
280     }
281     else if (USARTx == UART7)
282     {
283       periphclk = LL_RCC_GetUARTClockFreq(LL_RCC_UART7_CLKSOURCE);
284     }
285     else if (USARTx == UART8)
286     {
287       periphclk = LL_RCC_GetUARTClockFreq(LL_RCC_UART8_CLKSOURCE);
288     }
289     else
290     {
291       /* Nothing to do, as error code is already assigned to ERROR value */
292     }
293 
294     /* Configure the USART Baud Rate :
295        - valid baud rate value (different from 0) is required
296        - Peripheral clock as returned by RCC service, should be valid (different from 0).
297     */
298     if ((periphclk != LL_RCC_PERIPH_FREQUENCY_NO)
299         && (USART_InitStruct->BaudRate != 0U))
300     {
301       status = SUCCESS;
302       LL_USART_SetBaudRate(USARTx,
303                            periphclk,
304                            USART_InitStruct->OverSampling,
305                            USART_InitStruct->BaudRate);
306 
307       /* Check BRR is greater than or equal to 16d */
308       assert_param(IS_LL_USART_BRR_MIN(USARTx->BRR));
309     }
310   }
311   /* Endif (=> USART not in Disabled state => return ERROR) */
312 
313   return (status);
314 }
315 
316 /**
317   * @brief Set each @ref LL_USART_InitTypeDef field to default value.
318   * @param USART_InitStruct pointer to a @ref LL_USART_InitTypeDef structure
319   *                         whose fields will be set to default values.
320   * @retval None
321   */
322 
LL_USART_StructInit(LL_USART_InitTypeDef * USART_InitStruct)323 void LL_USART_StructInit(LL_USART_InitTypeDef *USART_InitStruct)
324 {
325   /* Set USART_InitStruct fields to default values */
326   USART_InitStruct->BaudRate            = 9600U;
327   USART_InitStruct->DataWidth           = LL_USART_DATAWIDTH_8B;
328   USART_InitStruct->StopBits            = LL_USART_STOPBITS_1;
329   USART_InitStruct->Parity              = LL_USART_PARITY_NONE ;
330   USART_InitStruct->TransferDirection   = LL_USART_DIRECTION_TX_RX;
331   USART_InitStruct->HardwareFlowControl = LL_USART_HWCONTROL_NONE;
332   USART_InitStruct->OverSampling        = LL_USART_OVERSAMPLING_16;
333 }
334 
335 /**
336   * @brief  Initialize USART Clock related settings according to the
337   *         specified parameters in the USART_ClockInitStruct.
338   * @note   As some bits in USART configuration registers can only be written when
339   *         the USART is disabled (USART_CR1_UE bit =0), USART Peripheral should be in disabled state prior calling
340   *         this function. Otherwise, ERROR result will be returned.
341   * @param  USARTx USART Instance
342   * @param  USART_ClockInitStruct pointer to a @ref LL_USART_ClockInitTypeDef structure
343   *         that contains the Clock configuration information for the specified USART peripheral.
344   * @retval An ErrorStatus enumeration value:
345   *          - SUCCESS: USART registers related to Clock settings are initialized according
346   *                     to USART_ClockInitStruct content
347   *          - ERROR: Problem occurred during USART Registers initialization
348   */
LL_USART_ClockInit(USART_TypeDef * USARTx,const LL_USART_ClockInitTypeDef * USART_ClockInitStruct)349 ErrorStatus LL_USART_ClockInit(USART_TypeDef *USARTx, const LL_USART_ClockInitTypeDef *USART_ClockInitStruct)
350 {
351   ErrorStatus status = SUCCESS;
352 
353   /* Check USART Instance and Clock signal output parameters */
354   assert_param(IS_UART_INSTANCE(USARTx));
355   assert_param(IS_LL_USART_CLOCKOUTPUT(USART_ClockInitStruct->ClockOutput));
356 
357   /* USART needs to be in disabled state, in order to be able to configure some bits in
358      CRx registers */
359   if (LL_USART_IsEnabled(USARTx) == 0U)
360   {
361     /* If USART Clock signal is disabled */
362     if (USART_ClockInitStruct->ClockOutput == LL_USART_CLOCK_DISABLE)
363     {
364       /* Deactivate Clock signal delivery :
365        * - Disable Clock Output:        USART_CR2_CLKEN cleared
366        */
367       LL_USART_DisableSCLKOutput(USARTx);
368     }
369     else
370     {
371       /* Ensure USART instance is USART capable */
372       assert_param(IS_USART_INSTANCE(USARTx));
373 
374       /* Check clock related parameters */
375       assert_param(IS_LL_USART_CLOCKPOLARITY(USART_ClockInitStruct->ClockPolarity));
376       assert_param(IS_LL_USART_CLOCKPHASE(USART_ClockInitStruct->ClockPhase));
377       assert_param(IS_LL_USART_LASTBITCLKOUTPUT(USART_ClockInitStruct->LastBitClockPulse));
378 
379       /*---------------------------- USART CR2 Configuration -----------------------
380        * Configure USARTx CR2 (Clock signal related bits) with parameters:
381        * - Enable Clock Output:         USART_CR2_CLKEN set
382        * - Clock Polarity:              USART_CR2_CPOL bit according to USART_ClockInitStruct->ClockPolarity value
383        * - Clock Phase:                 USART_CR2_CPHA bit according to USART_ClockInitStruct->ClockPhase value
384        * - Last Bit Clock Pulse Output: USART_CR2_LBCL bit according to USART_ClockInitStruct->LastBitClockPulse value.
385        */
386       MODIFY_REG(USARTx->CR2,
387                  USART_CR2_CLKEN | USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_LBCL,
388                  USART_CR2_CLKEN | USART_ClockInitStruct->ClockPolarity |
389                  USART_ClockInitStruct->ClockPhase | USART_ClockInitStruct->LastBitClockPulse);
390     }
391   }
392   /* Else (USART not in Disabled state => return ERROR */
393   else
394   {
395     status = ERROR;
396   }
397 
398   return (status);
399 }
400 
401 /**
402   * @brief Set each field of a @ref LL_USART_ClockInitTypeDef type structure to default value.
403   * @param USART_ClockInitStruct pointer to a @ref LL_USART_ClockInitTypeDef structure
404   *                              whose fields will be set to default values.
405   * @retval None
406   */
LL_USART_ClockStructInit(LL_USART_ClockInitTypeDef * USART_ClockInitStruct)407 void LL_USART_ClockStructInit(LL_USART_ClockInitTypeDef *USART_ClockInitStruct)
408 {
409   /* Set LL_USART_ClockInitStruct fields with default values */
410   USART_ClockInitStruct->ClockOutput       = LL_USART_CLOCK_DISABLE;
411   USART_ClockInitStruct->ClockPolarity     = LL_USART_POLARITY_LOW;            /* Not relevant when ClockOutput =
412                                                                                   LL_USART_CLOCK_DISABLE */
413   USART_ClockInitStruct->ClockPhase        = LL_USART_PHASE_1EDGE;             /* Not relevant when ClockOutput =
414                                                                                   LL_USART_CLOCK_DISABLE */
415   USART_ClockInitStruct->LastBitClockPulse = LL_USART_LASTCLKPULSE_NO_OUTPUT;  /* Not relevant when ClockOutput =
416                                                                                   LL_USART_CLOCK_DISABLE */
417 }
418 
419 /**
420   * @}
421   */
422 
423 /**
424   * @}
425   */
426 
427 /**
428   * @}
429   */
430 
431 #endif /* USART1 || USART2 || USART3 || USART6 || UART4 || UART5 || UART7 || UART8 */
432 
433 /**
434   * @}
435   */
436 
437 #endif /* USE_FULL_LL_DRIVER */
438 
439 
440