1 /*****************************************************************************
2  * Copyright (c) 2022, Nations Technologies Inc.
3  *
4  * All rights reserved.
5  * ****************************************************************************
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * - Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the disclaimer below.
12  *
13  * Nations' name may not be used to endorse or promote products derived from
14  * this software without specific prior written permission.
15  *
16  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
19  * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  * ****************************************************************************/
27 
28 /**
29  * @file n32g43x_usart.c
30  * @author Nations
31  * @version v1.2.0
32  *
33  * @copyright Copyright (c) 2022, Nations Technologies Inc. All rights reserved.
34  */
35 #include "n32g43x_usart.h"
36 #include "n32g43x_rcc.h"
37 
38 /** @addtogroup N32G43x_StdPeriph_Driver
39  * @{
40  */
41 
42 /** @addtogroup USART
43  * @brief USART driver modules
44  * @{
45  */
46 
47 /** @addtogroup USART_Private_TypesDefinitions
48  * @{
49  */
50 
51 /**
52  * @}
53  */
54 
55 /** @addtogroup USART_Private_Defines
56  * @{
57  */
58 
59 #define CTRL1_UEN_SET   ((uint16_t)0x2000) /*!< USART Enable Mask */
60 #define CTRL1_UEN_RESET ((uint16_t)0xDFFF) /*!< USART Disable Mask */
61 
62 #define CTRL1_WUM_MASK ((uint16_t)0xF7FF) /*!< USART WakeUp Method Mask */
63 
64 #define CTRL1_RCVWU_SET   ((uint16_t)0x0002) /*!< USART mute mode Enable Mask */
65 #define CTRL1_RCVWU_RESET ((uint16_t)0xFFFD) /*!< USART mute mode Enable Mask */
66 #define CTRL1_SDBRK_SET   ((uint16_t)0x0001) /*!< USART Break Character send Mask */
67 #define CTRL1_CLR_MASK    ((uint16_t)0xE9F3) /*!< USART CTRL1 Mask */
68 #define CTRL2_ADDR_MASK   ((uint16_t)0xFFF0) /*!< USART address Mask */
69 
70 #define CTRL2_LINMEN_SET   ((uint16_t)0x4000) /*!< USART LIN Enable Mask */
71 #define CTRL2_LINMEN_RESET ((uint16_t)0xBFFF) /*!< USART LIN Disable Mask */
72 
73 #define CTRL2_LINBDL_MASK    ((uint16_t)0xFFDF) /*!< USART LIN Break detection Mask */
74 #define CTRL2_STPB_CLR_MASK  ((uint16_t)0xCFFF) /*!< USART CTRL2 STOP Bits Mask */
75 #define CTRL2_CLOCK_CLR_MASK ((uint16_t)0xF0FF) /*!< USART CTRL2 Clock Mask */
76 
77 #define CTRL3_SCMEN_SET   ((uint16_t)0x0020) /*!< USART SC Enable Mask */
78 #define CTRL3_SCMEN_RESET ((uint16_t)0xFFDF) /*!< USART SC Disable Mask */
79 
80 #define CTRL3_SCNACK_SET   ((uint16_t)0x0010) /*!< USART SC NACK Enable Mask */
81 #define CTRL3_SCNACK_RESET ((uint16_t)0xFFEF) /*!< USART SC NACK Disable Mask */
82 
83 #define CTRL3_HDMEN_SET   ((uint16_t)0x0008) /*!< USART Half-Duplex Enable Mask */
84 #define CTRL3_HDMEN_RESET ((uint16_t)0xFFF7) /*!< USART Half-Duplex Disable Mask */
85 
86 #define CTRL3_IRDALP_MASK ((uint16_t)0xFFFB) /*!< USART IrDA LowPower mode Mask */
87 #define CTRL3_CLR_MASK    ((uint16_t)0xFCFF) /*!< USART CTRL3 Mask */
88 
89 #define CTRL3_IRDAMEN_SET   ((uint16_t)0x0002) /*!< USART IrDA Enable Mask */
90 #define CTRL3_IRDAMEN_RESET ((uint16_t)0xFFFD) /*!< USART IrDA Disable Mask */
91 #define GTP_LSB_MASK        ((uint16_t)0x00FF) /*!< Guard Time Register LSB Mask */
92 #define GTP_MSB_MASK        ((uint16_t)0xFF00) /*!< Guard Time Register MSB Mask */
93 #define INT_MASK            ((uint16_t)0x001F) /*!< USART Interrupt Mask */
94 
95 /**
96  * @}
97  */
98 
99 /** @addtogroup USART_Private_Macros
100  * @{
101  */
102 
103 /**
104  * @}
105  */
106 
107 /** @addtogroup USART_Private_Variables
108  * @{
109  */
110 
111 /**
112  * @}
113  */
114 
115 /** @addtogroup USART_Private_FunctionPrototypes
116  * @{
117  */
118 
119 /**
120  * @}
121  */
122 
123 /** @addtogroup USART_Private_Functions
124  * @{
125  */
126 
127 /**
128  * @brief  Deinitializes the USARTx peripheral registers to their default reset values.
129  * @param USARTx Select the USART or the UART peripheral.
130  *   This parameter can be one of the following values:
131  *      USART1, USART2, USART3, UART4 or UART5.
132  */
USART_DeInit(USART_Module * USARTx)133 void USART_DeInit(USART_Module* USARTx)
134 {
135     /* Check the parameters */
136     assert_param(IS_USART_ALL_PERIPH(USARTx));
137 
138     if (USARTx == USART1)
139     {
140         RCC_EnableAPB2PeriphReset(RCC_APB2_PERIPH_USART1, ENABLE);
141         RCC_EnableAPB2PeriphReset(RCC_APB2_PERIPH_USART1, DISABLE);
142     }
143     else if (USARTx == USART2)
144     {
145         RCC_EnableAPB1PeriphReset(RCC_APB1_PERIPH_USART2, ENABLE);
146         RCC_EnableAPB1PeriphReset(RCC_APB1_PERIPH_USART2, DISABLE);
147     }
148     else if (USARTx == USART3)
149     {
150         RCC_EnableAPB1PeriphReset(RCC_APB1_PERIPH_USART3, ENABLE);
151         RCC_EnableAPB1PeriphReset(RCC_APB1_PERIPH_USART3, DISABLE);
152     }
153     else if (USARTx == UART4)
154     {
155         RCC_EnableAPB2PeriphReset(RCC_APB2_PERIPH_UART4, ENABLE);
156         RCC_EnableAPB2PeriphReset(RCC_APB2_PERIPH_UART4, DISABLE);
157     }
158     else if (USARTx == UART5)
159     {
160         RCC_EnableAPB2PeriphReset(RCC_APB2_PERIPH_UART5, ENABLE);
161         RCC_EnableAPB2PeriphReset(RCC_APB2_PERIPH_UART5, DISABLE);
162     }
163 }
164 
165 /**
166  * @brief  Initializes the USARTx peripheral according to the specified
167  *         parameters in the USART_InitStruct .
168  * @param USARTx Select the USART or the UART peripheral.
169  *   This parameter can be one of the following values:
170  *   USART1, USART2, USART3, UART4 or UART5.
171  * @param USART_InitStruct pointer to a USART_InitType structure
172  *         that contains the configuration information for the specified USART
173  *         peripheral.
174  */
USART_Init(USART_Module * USARTx,USART_InitType * USART_InitStruct)175 void USART_Init(USART_Module* USARTx, USART_InitType* USART_InitStruct)
176 {
177     uint32_t tmpregister = 0x00, apbclock = 0x00;
178     uint32_t integerdivider    = 0x00;
179     uint32_t fractionaldivider = 0x00;
180     uint32_t usartxbase        = 0;
181     RCC_ClocksType RCC_ClocksStatus;
182     /* Check the parameters */
183     assert_param(IS_USART_ALL_PERIPH(USARTx));
184     assert_param(IS_USART_BAUDRATE(USART_InitStruct->BaudRate));
185     assert_param(IS_USART_WORD_LENGTH(USART_InitStruct->WordLength));
186     assert_param(IS_USART_STOPBITS(USART_InitStruct->StopBits));
187     assert_param(IS_USART_PARITY(USART_InitStruct->Parity));
188     assert_param(IS_USART_MODE(USART_InitStruct->Mode));
189     assert_param(IS_USART_HARDWARE_FLOW_CONTROL(USART_InitStruct->HardwareFlowControl));
190     /* The hardware flow control is available only for USART1, USART2 and USART3 */
191     if (USART_InitStruct->HardwareFlowControl != USART_HFCTRL_NONE)
192     {
193         assert_param(IS_USART_123_PERIPH(USARTx));
194     }
195 
196     usartxbase = (uint32_t)USARTx;
197 
198     /*---------------------------- USART CTRL2 Configuration -----------------------*/
199     tmpregister = USARTx->CTRL2;
200     /* Clear STOP[13:12] bits */
201     tmpregister &= CTRL2_STPB_CLR_MASK;
202     /* Configure the USART Stop Bits, Clock, CPOL, CPHA and LastBit ------------*/
203     /* Set STOP[13:12] bits according to StopBits value */
204     tmpregister |= (uint32_t)USART_InitStruct->StopBits;
205 
206     /* Write to USART CTRL2 */
207     USARTx->CTRL2 = (uint16_t)tmpregister;
208 
209     /*---------------------------- USART CTRL1 Configuration -----------------------*/
210     tmpregister = USARTx->CTRL1;
211     /* Clear M, PCE, PS, TE and RE bits */
212     tmpregister &= CTRL1_CLR_MASK;
213     /* Configure the USART Word Length, Parity and mode ----------------------- */
214     /* Set the M bits according to WordLength value */
215     /* Set PCE and PS bits according to Parity value */
216     /* Set TE and RE bits according to Mode value */
217     tmpregister |= (uint32_t)USART_InitStruct->WordLength | USART_InitStruct->Parity | USART_InitStruct->Mode;
218     /* Write to USART CTRL1 */
219     USARTx->CTRL1 = (uint16_t)tmpregister;
220 
221     /*---------------------------- USART CTRL3 Configuration -----------------------*/
222     tmpregister = USARTx->CTRL3;
223     /* Clear CTSE and RTSE bits */
224     tmpregister &= CTRL3_CLR_MASK;
225     /* Configure the USART HFC -------------------------------------------------*/
226     /* Set CTSE and RTSE bits according to HardwareFlowControl value */
227     tmpregister |= USART_InitStruct->HardwareFlowControl;
228     /* Write to USART CTRL3 */
229     USARTx->CTRL3 = (uint16_t)tmpregister;
230 
231     /*---------------------------- USART PBC Configuration -----------------------*/
232     /* Configure the USART Baud Rate -------------------------------------------*/
233     RCC_GetClocksFreqValue(&RCC_ClocksStatus);
234     if ((usartxbase == USART1_BASE) || (usartxbase == UART4_BASE) || (usartxbase == UART5_BASE))
235     {
236         apbclock = RCC_ClocksStatus.Pclk2Freq;
237     }
238     else
239     {
240         apbclock = RCC_ClocksStatus.Pclk1Freq;
241     }
242 
243     /* Determine the integer part */
244     integerdivider = ((25 * apbclock) / (4 * (USART_InitStruct->BaudRate)));
245     tmpregister = (integerdivider / 100) << 4;
246 
247     /* Determine the fractional part */
248     fractionaldivider = integerdivider - (100 * (tmpregister >> 4));
249 
250     /* Implement the fractional part in the register */
251     tmpregister |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F);
252 
253     /* Write to USART PBC */
254     USARTx->BRCF = (uint16_t)tmpregister;
255 }
256 
257 /**
258  * @brief  Fills each USART_InitStruct member with its default value.
259  * @param USART_InitStruct pointer to a USART_InitType structure
260  *         which will be initialized.
261  */
USART_StructInit(USART_InitType * USART_InitStruct)262 void USART_StructInit(USART_InitType* USART_InitStruct)
263 {
264     /* USART_InitStruct members default value */
265     USART_InitStruct->BaudRate            = 9600;
266     USART_InitStruct->WordLength          = USART_WL_8B;
267     USART_InitStruct->StopBits            = USART_STPB_1;
268     USART_InitStruct->Parity              = USART_PE_NO;
269     USART_InitStruct->Mode                = USART_MODE_RX | USART_MODE_TX;
270     USART_InitStruct->HardwareFlowControl = USART_HFCTRL_NONE;
271 }
272 
273 /**
274  * @brief  Initializes the USARTx peripheral Clock according to the
275  *          specified parameters in the USART_ClockInitStruct .
276  * @param USARTx where x can be 1, 2, 3 to select the USART peripheral.
277  * @param USART_ClockInitStruct pointer to a USART_ClockInitType
278  *         structure that contains the configuration information for the specified
279  *         USART peripheral.
280  * @note The Smart Card and Synchronous modes are not available for UART4/UART5.
281  */
USART_ClockInit(USART_Module * USARTx,USART_ClockInitType * USART_ClockInitStruct)282 void USART_ClockInit(USART_Module* USARTx, USART_ClockInitType* USART_ClockInitStruct)
283 {
284     uint32_t tmpregister = 0x00;
285     /* Check the parameters */
286     assert_param(IS_USART_123_PERIPH(USARTx));
287     assert_param(IS_USART_CLOCK(USART_ClockInitStruct->Clock));
288     assert_param(IS_USART_CPOL(USART_ClockInitStruct->Polarity));
289     assert_param(IS_USART_CPHA(USART_ClockInitStruct->Phase));
290     assert_param(IS_USART_LASTBIT(USART_ClockInitStruct->LastBit));
291 
292     /*---------------------------- USART CTRL2 Configuration -----------------------*/
293     tmpregister = USARTx->CTRL2;
294     /* Clear CLKEN, CPOL, CPHA and LBCL bits */
295     tmpregister &= CTRL2_CLOCK_CLR_MASK;
296     /* Configure the USART Clock, CPOL, CPHA and LastBit ------------*/
297     /* Set CLKEN bit according to Clock value */
298     /* Set CPOL bit according to Polarity value */
299     /* Set CPHA bit according to Phase value */
300     /* Set LBCL bit according to LastBit value */
301     tmpregister |= (uint32_t)USART_ClockInitStruct->Clock | USART_ClockInitStruct->Polarity
302                    | USART_ClockInitStruct->Phase | USART_ClockInitStruct->LastBit;
303     /* Write to USART CTRL2 */
304     USARTx->CTRL2 = (uint16_t)tmpregister;
305 }
306 
307 /**
308  * @brief  Fills each USART_ClockInitStruct member with its default value.
309  * @param USART_ClockInitStruct pointer to a USART_ClockInitType
310  *         structure which will be initialized.
311  */
USART_ClockStructInit(USART_ClockInitType * USART_ClockInitStruct)312 void USART_ClockStructInit(USART_ClockInitType* USART_ClockInitStruct)
313 {
314     /* USART_ClockInitStruct members default value */
315     USART_ClockInitStruct->Clock    = USART_CLK_DISABLE;
316     USART_ClockInitStruct->Polarity = USART_CLKPOL_LOW;
317     USART_ClockInitStruct->Phase    = USART_CLKPHA_1EDGE;
318     USART_ClockInitStruct->LastBit  = USART_CLKLB_DISABLE;
319 }
320 
321 /**
322  * @brief  Enables or disables the specified USART peripheral.
323  * @param USARTx Select the USART or the UART peripheral.
324  *         This parameter can be one of the following values:
325  *           USART1, USART2, USART3, UART4 or UART5.
326  * @param Cmd new state of the USARTx peripheral.
327  *         This parameter can be: ENABLE or DISABLE.
328  */
USART_Enable(USART_Module * USARTx,FunctionalState Cmd)329 void USART_Enable(USART_Module* USARTx, FunctionalState Cmd)
330 {
331     /* Check the parameters */
332     assert_param(IS_USART_ALL_PERIPH(USARTx));
333     assert_param(IS_FUNCTIONAL_STATE(Cmd));
334 
335     if (Cmd != DISABLE)
336     {
337         /* Enable the selected USART by setting the UE bit in the CTRL1 register */
338         USARTx->CTRL1 |= CTRL1_UEN_SET;
339     }
340     else
341     {
342         /* Disable the selected USART by clearing the UE bit in the CTRL1 register */
343         USARTx->CTRL1 &= CTRL1_UEN_RESET;
344     }
345 }
346 
347 /**
348  * @brief  Enables or disables the specified USART interrupts.
349  * @param USARTx Select the USART or the UART peripheral.
350  *   This parameter can be one of the following values:
351  *   USART1, USART2, USART3, UART4 or UART5.
352  * @param USART_INT specifies the USART interrupt sources to be enabled or disabled.
353  *   This parameter can be one of the following values:
354  *     @arg USART_INT_CTSF CTS change interrupt (not available for UART4 and UART5)
355  *     @arg USART_INT_LINBD LIN Break detection interrupt
356  *     @arg USART_INT_TXDE Transmit Data Register empty interrupt
357  *     @arg USART_INT_TXC Transmission complete interrupt
358  *     @arg USART_INT_RXDNE Receive Data register not empty interrupt
359  *     @arg USART_INT_IDLEF Idle line detection interrupt
360  *     @arg USART_INT_PEF Parity Error interrupt
361  *     @arg USART_INT_ERRF Error interrupt(Frame error, noise error, overrun error)
362  * @param Cmd new state of the specified USARTx interrupts.
363  *   This parameter can be: ENABLE or DISABLE.
364  */
USART_ConfigInt(USART_Module * USARTx,uint16_t USART_INT,FunctionalState Cmd)365 void USART_ConfigInt(USART_Module* USARTx, uint16_t USART_INT, FunctionalState Cmd)
366 {
367     uint32_t usartreg = 0x00, itpos = 0x00, itmask = 0x00;
368     uint32_t usartxbase = 0x00;
369     /* Check the parameters */
370     assert_param(IS_USART_ALL_PERIPH(USARTx));
371     assert_param(IS_USART_CFG_INT(USART_INT));
372     assert_param(IS_FUNCTIONAL_STATE(Cmd));
373     /* The CTS interrupt is not available for UART4/UART5 */
374     if (USART_INT == USART_INT_CTSF)
375     {
376         assert_param(IS_USART_123_PERIPH(USARTx));
377     }
378 
379     usartxbase = (uint32_t)USARTx;
380 
381     /* Get the USART register index */
382     usartreg = (((uint8_t)USART_INT) >> 0x05);
383 
384     /* Get the interrupt position */
385     itpos  = USART_INT & INT_MASK;
386     itmask = (((uint32_t)0x01) << itpos);
387 
388     if (usartreg == 0x01) /* The IT is in CTRL1 register */
389     {
390         usartxbase += 0x0C;
391     }
392     else if (usartreg == 0x02) /* The IT is in CTRL2 register */
393     {
394         usartxbase += 0x10;
395     }
396     else /* The IT is in CTRL3 register */
397     {
398         usartxbase += 0x14;
399     }
400     if (Cmd != DISABLE)
401     {
402         *(__IO uint32_t*)usartxbase |= itmask;
403     }
404     else
405     {
406         *(__IO uint32_t*)usartxbase &= ~itmask;
407     }
408 }
409 
410 /**
411  * @brief  Enables or disables the USART's DMA interface.
412  * @param USARTx Select the USART or the UART peripheral.
413  *   This parameter can be one of the following values:
414  *   USART1, USART2, USART3, UART4 or UART5.
415  * @param USART_DMAReq specifies the DMA request.
416  *   This parameter can be any combination of the following values:
417  *     @arg USART_DMAREQ_TX USART DMA transmit request
418  *     @arg USART_DMAREQ_RX USART DMA receive request
419  * @param Cmd new state of the DMA Request sources.
420  *   This parameter can be: ENABLE or DISABLE.
421  */
USART_EnableDMA(USART_Module * USARTx,uint16_t USART_DMAReq,FunctionalState Cmd)422 void USART_EnableDMA(USART_Module* USARTx, uint16_t USART_DMAReq, FunctionalState Cmd)
423 {
424     /* Check the parameters */
425     assert_param(IS_USART_ALL_PERIPH(USARTx));
426     assert_param(IS_USART_DMAREQ(USART_DMAReq));
427     assert_param(IS_FUNCTIONAL_STATE(Cmd));
428     if (Cmd != DISABLE)
429     {
430         /* Enable the DMA transfer for selected requests by setting the DMAT and/or
431            DADDR bits in the USART CTRL3 register */
432         USARTx->CTRL3 |= USART_DMAReq;
433     }
434     else
435     {
436         /* Disable the DMA transfer for selected requests by clearing the DMAT and/or
437            DADDR bits in the USART CTRL3 register */
438         USARTx->CTRL3 &= (uint16_t)~USART_DMAReq;
439     }
440 }
441 
442 /**
443  * @brief  Sets the address of the USART node.
444  * @param USARTx Select the USART or the UART peripheral.
445  *   This parameter can be one of the following values:
446  *   USART1, USART2, USART3, UART4 or UART5.
447  * @param USART_Addr Indicates the address of the USART node.
448  */
USART_SetAddr(USART_Module * USARTx,uint8_t USART_Addr)449 void USART_SetAddr(USART_Module* USARTx, uint8_t USART_Addr)
450 {
451     /* Check the parameters */
452     assert_param(IS_USART_ALL_PERIPH(USARTx));
453     assert_param(IS_USART_ADDRESS(USART_Addr));
454 
455     /* Clear the USART address */
456     USARTx->CTRL2 &= CTRL2_ADDR_MASK;
457     /* Set the USART address node */
458     USARTx->CTRL2 |= USART_Addr;
459 }
460 
461 /**
462  * @brief  Selects the USART WakeUp method.
463  * @param USARTx Select the USART or the UART peripheral.
464  *   This parameter can be one of the following values:
465  *   USART1, USART2, USART3, UART4 or UART5.
466  * @param USART_WakeUpMode specifies the USART wakeup method.
467  *   This parameter can be one of the following values:
468  *     @arg USART_WUM_IDLELINE WakeUp by an idle line detection
469  *     @arg USART_WUM_ADDRMASK WakeUp by an address mark
470  */
USART_ConfigWakeUpMode(USART_Module * USARTx,uint16_t USART_WakeUpMode)471 void USART_ConfigWakeUpMode(USART_Module* USARTx, uint16_t USART_WakeUpMode)
472 {
473     /* Check the parameters */
474     assert_param(IS_USART_ALL_PERIPH(USARTx));
475     assert_param(IS_USART_WAKEUP(USART_WakeUpMode));
476 
477     USARTx->CTRL1 &= CTRL1_WUM_MASK;
478     USARTx->CTRL1 |= USART_WakeUpMode;
479 }
480 
481 /**
482  * @brief  Determines if the USART is in mute mode or not.
483  * @param USARTx Select the USART or the UART peripheral.
484  *   This parameter can be one of the following values:
485  *   USART1, USART2, USART3, UART4 or UART5.
486  * @param Cmd new state of the USART mute mode.
487  *   This parameter can be: ENABLE or DISABLE.
488  */
USART_EnableRcvWakeUp(USART_Module * USARTx,FunctionalState Cmd)489 void USART_EnableRcvWakeUp(USART_Module* USARTx, FunctionalState Cmd)
490 {
491     /* Check the parameters */
492     assert_param(IS_USART_ALL_PERIPH(USARTx));
493     assert_param(IS_FUNCTIONAL_STATE(Cmd));
494 
495     if (Cmd != DISABLE)
496     {
497         /* Enable the USART mute mode  by setting the RWU bit in the CTRL1 register */
498         USARTx->CTRL1 |= CTRL1_RCVWU_SET;
499     }
500     else
501     {
502         /* Disable the USART mute mode by clearing the RWU bit in the CTRL1 register */
503         USARTx->CTRL1 &= CTRL1_RCVWU_RESET;
504     }
505 }
506 
507 /**
508  * @brief  Sets the USART LIN Break detection length.
509  * @param USARTx Select the USART or the UART peripheral.
510  *   This parameter can be one of the following values:
511  *   USART1, USART2, USART3, UART4 or UART5.
512  * @param USART_LINBreakDetectLength specifies the LIN break detection length.
513  *   This parameter can be one of the following values:
514  *     @arg USART_LINBDL_10B 10-bit break detection
515  *     @arg USART_LINBDL_11B 11-bit break detection
516  */
USART_ConfigLINBreakDetectLength(USART_Module * USARTx,uint16_t USART_LINBreakDetectLength)517 void USART_ConfigLINBreakDetectLength(USART_Module* USARTx, uint16_t USART_LINBreakDetectLength)
518 {
519     /* Check the parameters */
520     assert_param(IS_USART_ALL_PERIPH(USARTx));
521     assert_param(IS_USART_LIN_BREAK_DETECT_LENGTH(USART_LINBreakDetectLength));
522 
523     USARTx->CTRL2 &= CTRL2_LINBDL_MASK;
524     USARTx->CTRL2 |= USART_LINBreakDetectLength;
525 }
526 
527 /**
528  * @brief  Enables or disables the USART's LIN mode.
529  * @param USARTx Select the USART or the UART peripheral.
530  *   This parameter can be one of the following values:
531  *   USART1, USART2, USART3, UART4 or UART5.
532  * @param Cmd new state of the USART LIN mode.
533  *   This parameter can be: ENABLE or DISABLE.
534  */
USART_EnableLIN(USART_Module * USARTx,FunctionalState Cmd)535 void USART_EnableLIN(USART_Module* USARTx, FunctionalState Cmd)
536 {
537     /* Check the parameters */
538     assert_param(IS_USART_ALL_PERIPH(USARTx));
539     assert_param(IS_FUNCTIONAL_STATE(Cmd));
540 
541     if (Cmd != DISABLE)
542     {
543         /* Enable the LIN mode by setting the LINEN bit in the CTRL2 register */
544         USARTx->CTRL2 |= CTRL2_LINMEN_SET;
545     }
546     else
547     {
548         /* Disable the LIN mode by clearing the LINEN bit in the CTRL2 register */
549         USARTx->CTRL2 &= CTRL2_LINMEN_RESET;
550     }
551 }
552 
553 /**
554  * @brief  Transmits single data through the USARTx peripheral.
555  * @param USARTx Select the USART or the UART peripheral.
556  *   This parameter can be one of the following values:
557  *   USART1, USART2, USART3, UART4 or UART5.
558  * @param Data the data to transmit.
559  */
USART_SendData(USART_Module * USARTx,uint16_t Data)560 void USART_SendData(USART_Module* USARTx, uint16_t Data)
561 {
562     /* Check the parameters */
563     assert_param(IS_USART_ALL_PERIPH(USARTx));
564     assert_param(IS_USART_DATA(Data));
565 
566     /* Transmit Data */
567     USARTx->DAT = (Data & (uint16_t)0x01FF);
568 }
569 
570 /**
571  * @brief  Returns the most recent received data by the USARTx peripheral.
572  * @param USARTx Select the USART or the UART peripheral.
573  *   This parameter can be one of the following values:
574  *   USART1, USART2, USART3, UART4 or UART5.
575  * @return The received data.
576  */
USART_ReceiveData(USART_Module * USARTx)577 uint16_t USART_ReceiveData(USART_Module* USARTx)
578 {
579     /* Check the parameters */
580     assert_param(IS_USART_ALL_PERIPH(USARTx));
581 
582     /* Receive Data */
583     return (uint16_t)(USARTx->DAT & (uint16_t)0x01FF);
584 }
585 
586 /**
587  * @brief  Transmits break characters.
588  * @param USARTx Select the USART or the UART peripheral.
589  *   This parameter can be one of the following values:
590  *   USART1, USART2, USART3, UART4 or UART5.
591  */
USART_SendBreak(USART_Module * USARTx)592 void USART_SendBreak(USART_Module* USARTx)
593 {
594     /* Check the parameters */
595     assert_param(IS_USART_ALL_PERIPH(USARTx));
596 
597     /* Send break characters */
598     USARTx->CTRL1 |= CTRL1_SDBRK_SET;
599 }
600 
601 /**
602  * @brief  Sets the specified USART guard time.
603  * @param USARTx where x can be 1, 2 or 3 to select the USART peripheral.
604  * @param USART_GuardTime specifies the guard time.
605  * @note The guard time bits are not available for UART4/UART5.
606  */
USART_SetGuardTime(USART_Module * USARTx,uint8_t USART_GuardTime)607 void USART_SetGuardTime(USART_Module* USARTx, uint8_t USART_GuardTime)
608 {
609     /* Check the parameters */
610     assert_param(IS_USART_123_PERIPH(USARTx));
611 
612     /* Clear the USART Guard time */
613     USARTx->GTP &= GTP_LSB_MASK;
614     /* Set the USART guard time */
615     USARTx->GTP |= (uint16_t)((uint16_t)USART_GuardTime << 0x08);
616 }
617 
618 /**
619  * @brief  Sets the system clock prescaler.
620  * @param USARTx Select the USART or the UART peripheral.
621  *   This parameter can be one of the following values:
622  *   USART1, USART2, USART3, UART4 or UART5.
623  * @param USART_Prescaler specifies the prescaler clock.
624  * @note   The function is used for IrDA mode with UART4 and UART5.
625  */
USART_SetPrescaler(USART_Module * USARTx,uint8_t USART_Prescaler)626 void USART_SetPrescaler(USART_Module* USARTx, uint8_t USART_Prescaler)
627 {
628     /* Check the parameters */
629     assert_param(IS_USART_ALL_PERIPH(USARTx));
630 
631     /* Clear the USART prescaler */
632     USARTx->GTP &= GTP_MSB_MASK;
633     /* Set the USART prescaler */
634     USARTx->GTP |= USART_Prescaler;
635 }
636 
637 /**
638  * @brief  Enables or disables the USART's Smart Card mode.
639  * @param USARTx where x can be 1, 2 or 3 to select the USART peripheral.
640  * @param Cmd new state of the Smart Card mode.
641  *   This parameter can be: ENABLE or DISABLE.
642  * @note The Smart Card mode is not available for UART4/UART5.
643  */
USART_EnableSmartCard(USART_Module * USARTx,FunctionalState Cmd)644 void USART_EnableSmartCard(USART_Module* USARTx, FunctionalState Cmd)
645 {
646     /* Check the parameters */
647     assert_param(IS_USART_123_PERIPH(USARTx));
648     assert_param(IS_FUNCTIONAL_STATE(Cmd));
649     if (Cmd != DISABLE)
650     {
651         /* Enable the SC mode by setting the SCEN bit in the CTRL3 register */
652         USARTx->CTRL3 |= CTRL3_SCMEN_SET;
653     }
654     else
655     {
656         /* Disable the SC mode by clearing the SCEN bit in the CTRL3 register */
657         USARTx->CTRL3 &= CTRL3_SCMEN_RESET;
658     }
659 }
660 
661 /**
662  * @brief  Enables or disables NACK transmission.
663  * @param USARTx where x can be 1, 2 or 3 to select the USART peripheral.
664  * @param Cmd new state of the NACK transmission.
665  *   This parameter can be: ENABLE or DISABLE.
666  * @note The Smart Card mode is not available for UART4/UART5.
667  */
USART_SetSmartCardNACK(USART_Module * USARTx,FunctionalState Cmd)668 void USART_SetSmartCardNACK(USART_Module* USARTx, FunctionalState Cmd)
669 {
670     /* Check the parameters */
671     assert_param(IS_USART_123_PERIPH(USARTx));
672     assert_param(IS_FUNCTIONAL_STATE(Cmd));
673     if (Cmd != DISABLE)
674     {
675         /* Enable the NACK transmission by setting the NACK bit in the CTRL3 register */
676         USARTx->CTRL3 |= CTRL3_SCNACK_SET;
677     }
678     else
679     {
680         /* Disable the NACK transmission by clearing the NACK bit in the CTRL3 register */
681         USARTx->CTRL3 &= CTRL3_SCNACK_RESET;
682     }
683 }
684 
685 /**
686  * @brief  Enables or disables the USART's Half Duplex communication.
687  * @param USARTx Select the USART or the UART peripheral.
688  *   This parameter can be one of the following values:
689  *   USART1, USART2, USART3, UART4 or UART5.
690  * @param Cmd new state of the USART Communication.
691  *   This parameter can be: ENABLE or DISABLE.
692  */
USART_EnableHalfDuplex(USART_Module * USARTx,FunctionalState Cmd)693 void USART_EnableHalfDuplex(USART_Module* USARTx, FunctionalState Cmd)
694 {
695     /* Check the parameters */
696     assert_param(IS_USART_ALL_PERIPH(USARTx));
697     assert_param(IS_FUNCTIONAL_STATE(Cmd));
698 
699     if (Cmd != DISABLE)
700     {
701         /* Enable the Half-Duplex mode by setting the HDSEL bit in the CTRL3 register */
702         USARTx->CTRL3 |= CTRL3_HDMEN_SET;
703     }
704     else
705     {
706         /* Disable the Half-Duplex mode by clearing the HDSEL bit in the CTRL3 register */
707         USARTx->CTRL3 &= CTRL3_HDMEN_RESET;
708     }
709 }
710 
711 /**
712  * @brief  Configures the USART's IrDA interface.
713  * @param USARTx Select the USART or the UART peripheral.
714  *   This parameter can be one of the following values:
715  *   USART1, USART2, USART3, UART4 or UART5.
716  * @param USART_IrDAMode specifies the IrDA mode.
717  *   This parameter can be one of the following values:
718  *     @arg USART_IRDAMODE_LOWPPWER
719  *     @arg USART_IRDAMODE_NORMAL
720  */
USART_ConfigIrDAMode(USART_Module * USARTx,uint16_t USART_IrDAMode)721 void USART_ConfigIrDAMode(USART_Module* USARTx, uint16_t USART_IrDAMode)
722 {
723     /* Check the parameters */
724     assert_param(IS_USART_ALL_PERIPH(USARTx));
725     assert_param(IS_USART_IRDA_MODE(USART_IrDAMode));
726 
727     USARTx->CTRL3 &= CTRL3_IRDALP_MASK;
728     USARTx->CTRL3 |= USART_IrDAMode;
729 }
730 
731 /**
732  * @brief  Enables or disables the USART's IrDA interface.
733  * @param USARTx Select the USART or the UART peripheral.
734  *   This parameter can be one of the following values:
735  *   USART1, USART2, USART3, UART4 or UART5.
736  * @param Cmd new state of the IrDA mode.
737  *   This parameter can be: ENABLE or DISABLE.
738  */
USART_EnableIrDA(USART_Module * USARTx,FunctionalState Cmd)739 void USART_EnableIrDA(USART_Module* USARTx, FunctionalState Cmd)
740 {
741     /* Check the parameters */
742     assert_param(IS_USART_ALL_PERIPH(USARTx));
743     assert_param(IS_FUNCTIONAL_STATE(Cmd));
744 
745     if (Cmd != DISABLE)
746     {
747         /* Enable the IrDA mode by setting the IREN bit in the CTRL3 register */
748         USARTx->CTRL3 |= CTRL3_IRDAMEN_SET;
749     }
750     else
751     {
752         /* Disable the IrDA mode by clearing the IREN bit in the CTRL3 register */
753         USARTx->CTRL3 &= CTRL3_IRDAMEN_RESET;
754     }
755 }
756 
757 /**
758  * @brief  Checks whether the specified USART flag is set or not.
759  * @param USARTx Select the USART or the UART peripheral.
760  *   This parameter can be one of the following values:
761  *   USART1, USART2, USART3, UART4 or UART5.
762  * @param USART_FLAG specifies the flag to check.
763  *   This parameter can be one of the following values:
764  *     @arg USART_FLAG_CTSF CTS Change flag (not available for UART4 and UART5)
765  *     @arg USART_FLAG_LINBD LIN Break detection flag
766  *     @arg USART_FLAG_TXDE Transmit data register empty flag
767  *     @arg USART_FLAG_TXC Transmission Complete flag
768  *     @arg USART_FLAG_RXDNE Receive data register not empty flag
769  *     @arg USART_FLAG_IDLEF Idle Line detection flag
770  *     @arg USART_FLAG_OREF OverRun Error flag
771  *     @arg USART_FLAG_NEF Noise Error flag
772  *     @arg USART_FLAG_FEF Framing Error flag
773  *     @arg USART_FLAG_PEF Parity Error flag
774  * @return The new state of USART_FLAG (SET or RESET).
775  */
USART_GetFlagStatus(USART_Module * USARTx,uint16_t USART_FLAG)776 FlagStatus USART_GetFlagStatus(USART_Module* USARTx, uint16_t USART_FLAG)
777 {
778     FlagStatus bitstatus = RESET;
779     /* Check the parameters */
780     assert_param(IS_USART_ALL_PERIPH(USARTx));
781     assert_param(IS_USART_FLAG(USART_FLAG));
782     /* The CTS flag is not available for UART4/UART5 */
783     if (USART_FLAG == USART_FLAG_CTSF)
784     {
785         assert_param(IS_USART_123_PERIPH(USARTx));
786     }
787 
788     if ((USARTx->STS & USART_FLAG) != (uint16_t)RESET)
789     {
790         bitstatus = SET;
791     }
792     else
793     {
794         bitstatus = RESET;
795     }
796     return bitstatus;
797 }
798 
799 /**
800  * @brief  Clears the USARTx's pending flags.
801  * @param USARTx Select the USART or the UART peripheral.
802  *   This parameter can be one of the following values:
803  *   USART1, USART2, USART3, UART4 or UART5.
804  * @param USART_FLAG specifies the flag to clear.
805  *   This parameter can be any combination of the following values:
806  *     @arg USART_FLAG_CTSF CTS Change flag (not available for UART4 and UART5).
807  *     @arg USART_FLAG_LINBD LIN Break detection flag.
808  *     @arg USART_FLAG_TXC Transmission Complete flag.
809  *     @arg USART_FLAG_RXDNE Receive data register not empty flag.
810  *
811  * @note
812  *   - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun
813  *     error) and IDLE (Idle line detected) flags are cleared by software
814  *     sequence: a read operation to USART_SR register (USART_GetFlagStatus())
815  *     followed by a read operation to USART_DR register (USART_ReceiveData()).
816  *   - RXNE flag can be also cleared by a read to the USART_DR register
817  *     (USART_ReceiveData()).
818  *   - TC flag can be also cleared by software sequence: a read operation to
819  *     USART_SR register (USART_GetFlagStatus()) followed by a write operation
820  *     to USART_DR register (USART_SendData()).
821  *   - TXE flag is cleared only by a write to the USART_DR register
822  *     (USART_SendData()).
823  */
USART_ClrFlag(USART_Module * USARTx,uint16_t USART_FLAG)824 void USART_ClrFlag(USART_Module* USARTx, uint16_t USART_FLAG)
825 {
826     /* Check the parameters */
827     assert_param(IS_USART_ALL_PERIPH(USARTx));
828     assert_param(IS_USART_CLEAR_FLAG(USART_FLAG));
829     /* The CTS flag is not available for UART4/UART5 */
830     if ((USART_FLAG & USART_FLAG_CTSF) == USART_FLAG_CTSF)
831     {
832         assert_param(IS_USART_123_PERIPH(USARTx));
833     }
834 
835     USARTx->STS = (uint16_t)~USART_FLAG;
836 }
837 
838 /**
839  * @brief  Checks whether the specified USART interrupt has occurred or not.
840  * @param USARTx Select the USART or the UART peripheral.
841  *   This parameter can be one of the following values:
842  *   USART1, USART2, USART3, UART4 or UART5.
843  * @param USART_INT specifies the USART interrupt source to check.
844  *   This parameter can be one of the following values:
845  *     @arg USART_INT_CTSF CTS change interrupt (not available for UART4 and UART5)
846  *     @arg USART_INT_LINBD LIN Break detection interrupt
847  *     @arg USART_INT_TXDE Tansmit Data Register empty interrupt
848  *     @arg USART_INT_TXC Transmission complete interrupt
849  *     @arg USART_INT_RXDNE Receive Data register not empty interrupt
850  *     @arg USART_INT_IDLEF Idle line detection interrupt
851  *     @arg USART_INT_OREF OverRun Error interrupt
852  *     @arg USART_INT_NEF Noise Error interrupt
853  *     @arg USART_INT_FEF Framing Error interrupt
854  *     @arg USART_INT_PEF Parity Error interrupt
855  * @return The new state of USART_INT (SET or RESET).
856  */
USART_GetIntStatus(USART_Module * USARTx,uint16_t USART_INT)857 INTStatus USART_GetIntStatus(USART_Module* USARTx, uint16_t USART_INT)
858 {
859     uint32_t bitpos = 0x00, itmask = 0x00, usartreg = 0x00;
860     INTStatus bitstatus = RESET;
861     /* Check the parameters */
862     assert_param(IS_USART_ALL_PERIPH(USARTx));
863     assert_param(IS_USART_GET_INT(USART_INT));
864     /* The CTS interrupt is not available for UART4/UART5 */
865     if (USART_INT == USART_INT_CTSF)
866     {
867         assert_param(IS_USART_123_PERIPH(USARTx));
868     }
869 
870     /* Get the USART register index */
871     usartreg = (((uint8_t)USART_INT) >> 0x05);
872     /* Get the interrupt position */
873     itmask = USART_INT & INT_MASK;
874     itmask = (uint32_t)0x01 << itmask;
875 
876     if (usartreg == 0x01) /* The IT  is in CTRL1 register */
877     {
878         itmask &= USARTx->CTRL1;
879     }
880     else if (usartreg == 0x02) /* The IT  is in CTRL2 register */
881     {
882         itmask &= USARTx->CTRL2;
883     }
884     else /* The IT  is in CTRL3 register */
885     {
886         itmask &= USARTx->CTRL3;
887     }
888 
889     bitpos = USART_INT >> 0x08;
890     bitpos = (uint32_t)0x01 << bitpos;
891     bitpos &= USARTx->STS;
892     if ((itmask != (uint16_t)RESET) && (bitpos != (uint16_t)RESET))
893     {
894         bitstatus = SET;
895     }
896     else
897     {
898         bitstatus = RESET;
899     }
900 
901     return bitstatus;
902 }
903 
904 /**
905  * @brief  Clears the USARTx's interrupt pending bits.
906  * @param USARTx Select the USART or the UART peripheral.
907  *   This parameter can be one of the following values:
908  *   USART1, USART2, USART3, UART4 or UART5.
909  * @param USART_INT specifies the interrupt pending bit to clear.
910  *   This parameter can be one of the following values:
911  *     @arg USART_INT_CTSF CTS change interrupt (not available for UART4 and UART5)
912  *     @arg USART_INT_LINBD LIN Break detection interrupt
913  *     @arg USART_INT_TXC Transmission complete interrupt.
914  *     @arg USART_INT_RXDNE Receive Data register not empty interrupt.
915  *
916  * @note
917  *   - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun
918  *     error) and IDLE (Idle line detected) pending bits are cleared by
919  *     software sequence: a read operation to USART_SR register
920  *     (USART_GetIntStatus()) followed by a read operation to USART_DR register
921  *     (USART_ReceiveData()).
922  *   - RXNE pending bit can be also cleared by a read to the USART_DR register
923  *     (USART_ReceiveData()).
924  *   - TC pending bit can be also cleared by software sequence: a read
925  *     operation to USART_SR register (USART_GetIntStatus()) followed by a write
926  *     operation to USART_DR register (USART_SendData()).
927  *   - TXE pending bit is cleared only by a write to the USART_DR register
928  *     (USART_SendData()).
929  */
USART_ClrIntPendingBit(USART_Module * USARTx,uint16_t USART_INT)930 void USART_ClrIntPendingBit(USART_Module* USARTx, uint16_t USART_INT)
931 {
932     uint16_t bitpos = 0x00, itmask = 0x00;
933     /* Check the parameters */
934     assert_param(IS_USART_ALL_PERIPH(USARTx));
935     assert_param(IS_USART_CLR_INT(USART_INT));
936     /* The CTS interrupt is not available for UART4/UART5 */
937     if (USART_INT == USART_INT_CTSF)
938     {
939         assert_param(IS_USART_123_PERIPH(USARTx));
940     }
941 
942     bitpos      = USART_INT >> 0x08;
943     itmask      = ((uint16_t)0x01 << (uint16_t)bitpos);
944     USARTx->STS = (uint16_t)~itmask;
945 }
946 /**
947  * @}
948  */
949 
950 /**
951  * @}
952  */
953 
954 /**
955  * @}
956  */
957