1 /*!
2  * @file        apm32f4xx_usart.c
3  *
4  * @brief       This file provides all the USART firmware functions
5  *
6  * @version     V1.0.2
7  *
8  * @date        2022-06-23
9  *
10  * @attention
11  *
12  *  Copyright (C) 2021-2022 Geehy Semiconductor
13  *
14  *  You may not use this file except in compliance with the
15  *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16  *
17  *  The program is only for reference, which is distributed in the hope
18  *  that it will be usefull and instructional for customers to develop
19  *  their software. Unless required by applicable law or agreed to in
20  *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21  *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22  *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23  *  and limitations under the License.
24  */
25 
26 #include "apm32f4xx_usart.h"
27 #include "apm32f4xx_rcm.h"
28 
29 /** @addtogroup APM32F4xx_StdPeriphDriver
30   @{
31 */
32 
33 /** @defgroup USART_Driver
34   * @brief USART driver modules
35   @{
36 */
37 
38 /** @defgroup USART_Functions
39   @{
40 */
41 
42 /*!
43  * @brief     Reset usart peripheral registers to their default reset values
44  *
45  * @param     USARTx: where x can be 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or
46  *                    UART peripheral.
47  *
48  * @retval    None
49  */
USART_Reset(USART_T * usart)50 void USART_Reset(USART_T *usart)
51 {
52     if (USART1 == usart)
53     {
54         RCM_EnableAPB2PeriphReset(RCM_APB2_PERIPH_USART1);
55         RCM_DisableAPB2PeriphReset(RCM_APB2_PERIPH_USART1);
56     }
57     else if (USART2 == usart)
58     {
59         RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_USART2);
60         RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_USART2);
61     }
62     else if (USART3 == usart)
63     {
64         RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_USART3);
65         RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_USART3);
66     }
67     else if (UART4 == usart)
68     {
69         RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_UART4);
70         RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_UART4);
71     }
72     else if (UART5 == usart)
73     {
74         RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_UART5);
75         RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_UART5);
76     }
77     else if (USART6 == usart)
78     {
79         RCM_EnableAPB2PeriphReset(RCM_APB2_PERIPH_USART6);
80         RCM_DisableAPB2PeriphReset(RCM_APB2_PERIPH_USART6);
81     }
82     else if (UART7 == usart)
83     {
84         RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_UART7);
85         RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_UART7);
86     }
87     else if (UART8 == usart)
88     {
89         RCM_EnableAPB1PeriphReset((uint32_t)RCM_APB1_PERIPH_UART8);
90         RCM_DisableAPB1PeriphReset((uint32_t)RCM_APB1_PERIPH_UART8);
91     }
92 }
93 
94 /*!
95  * @brief     Config the USART peripheral according to the specified parameters in the usartConfig
96  *
97  * @param     usart:         Select the USART or the UART peripheral
98  *
99  * @param     usartConfig:  pointer to a USART_Config_T structure
100  *
101  * @retval    None
102  *
103  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
104  */
USART_Config(USART_T * usart,USART_Config_T * usartConfig)105 void USART_Config(USART_T *usart, USART_Config_T *usartConfig)
106 {
107     uint32_t temp, fCLK, intDiv, fractionalDiv;
108 
109     usart->CTRL1_B.RXEN = usartConfig->mode & 0x01;
110     usart->CTRL1_B.TXEN = usartConfig->mode >> 1;
111     usart->CTRL1_B.PCFG = usartConfig->parity >> 1;
112     usart->CTRL1_B.PCEN = usartConfig->parity & 0x01;
113     usart->CTRL1_B.DBLCFG = usartConfig->wordLength;
114 
115     usart->CTRL2_B.STOPCFG = usartConfig->stopBits;
116 
117     usart->CTRL3_B.RTSEN = usartConfig->hardwareFlow & 0x01;
118     usart->CTRL3_B.CTSEN = usartConfig->hardwareFlow >> 1;
119 
120     if ((usart == USART1) || (usart == USART6))
121     {
122         RCM_ReadPCLKFreq(NULL, &fCLK);
123     }
124     else
125     {
126         RCM_ReadPCLKFreq(&fCLK, NULL);
127     }
128 
129     /* Compute the integer part */
130     if (usart->CTRL1_B.OSMCFG != RESET) /*!< Oversampling by 8 */
131     {
132         intDiv = ((25 * fCLK) / (2 * (usartConfig->baudRate)));
133     }
134     else /*!< Oversampling by 16 */
135     {
136         intDiv = ((25 * fCLK) / (4 * (usartConfig->baudRate)));
137     }
138 
139     temp = (intDiv / 100) << 4;
140     fractionalDiv = intDiv - (100 * (temp >> 4));
141 
142     /* Implement the fractional part in the register */
143     if (usart->CTRL1_B.OSMCFG != RESET) /*!< Oversampling by 8 */
144     {
145         temp |= ((((fractionalDiv * 8) + 50) / 100)) & ((uint8_t)0x07);
146     }
147     else /*!< Oversampling by 16 */
148     {
149         temp |= ((((fractionalDiv * 16) + 50) / 100)) & ((uint8_t)0x0F);
150     }
151 
152     usart->BR = temp;
153 }
154 
155 /*!
156  * @brief     Fills each USART_InitStruct member with its default value
157  *
158  * @param     usartConfig:   pointer to a USART_Config_T structure which will be initialized
159  *
160  * @retval    None
161  */
USART_ConfigStructInit(USART_Config_T * usartConfig)162 void USART_ConfigStructInit(USART_Config_T *usartConfig)
163 {
164     usartConfig->baudRate = 9600;
165     usartConfig->wordLength = USART_WORD_LEN_8B;
166     usartConfig->stopBits = USART_STOP_BIT_1;
167     usartConfig->parity = USART_PARITY_NONE ;
168     usartConfig->mode = USART_MODE_TX_RX;
169     usartConfig->hardwareFlow = USART_HARDWARE_FLOW_NONE;
170 }
171 
172 /*!
173  * @brief     Configuration communication clock
174  *
175  * @param     usart:  Select the USART or the UART peripheral
176  *
177  * @param     clockConfig:   Pointer to a USART_clockConfig_T structure
178  *
179  * @retval    None
180  *
181  * @note      The usart can be USART1, USART2, USART3 and USART6
182  */
USART_ConfigClock(USART_T * usart,USART_ClockConfig_T * clockConfig)183 void USART_ConfigClock(USART_T *usart, USART_ClockConfig_T *clockConfig)
184 {
185     usart->CTRL2_B.CLKEN   = clockConfig->clock;
186     usart->CTRL2_B.CPHA    = clockConfig->phase;
187     usart->CTRL2_B.CPOL    = clockConfig->polarity;
188     usart->CTRL2_B.LBCPOEN = clockConfig->lastBit;
189 }
190 
191 /*!
192  * @brief     Fills each clockConfig member with its default value
193  *
194  * @param     clockConfig:   Pointer to a USART_clockConfig_T structure
195  *
196  * @retval    None
197  *
198  * @note
199  */
USART_ConfigClockStructInit(USART_ClockConfig_T * clockConfig)200 void USART_ConfigClockStructInit(USART_ClockConfig_T *clockConfig)
201 {
202     clockConfig->clock     = USART_CLKEN_DISABLE;
203     clockConfig->phase     = USART_CLKPHA_1EDGE;
204     clockConfig->polarity  = USART_CLKPOL_LOW;
205     clockConfig->lastBit   = USART_LBCP_DISABLE;
206 }
207 
208 /*!
209  * @brief     Enables the specified USART peripheral
210  *
211  * @param     usart:   Select the USART or the UART peripheral
212  *
213  * @retval    None
214  *
215  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
216  */
USART_Enable(USART_T * usart)217 void USART_Enable(USART_T *usart)
218 {
219     usart->CTRL1_B.UEN = BIT_SET;
220 }
221 
222 /*!
223  * @brief     Disable the specified USART peripheral
224  *
225  * @param     usart:   Select the USART or the UART peripheral
226  *
227  * @retval    None
228  *
229  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
230  */
USART_Disable(USART_T * usart)231 void USART_Disable(USART_T *usart)
232 {
233     usart->CTRL1_B.UEN = BIT_RESET;
234 }
235 
236 /*!
237  * @brief     Sets the system clock divider number
238  *
239  * @param     usart: Select the USART or the UART peripheral
240  *
241  * @param     div:   specifies the divider number
242  *
243  * @retval    None
244  *
245  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
246  */
USART_ConfigPrescaler(USART_T * usart,uint8_t div)247 void USART_ConfigPrescaler(USART_T *usart, uint8_t div)
248 {
249     usart->GTPSC_B.PSC = div;
250 }
251 
252 /*!
253  * @brief     Enables the USART's 8x oversampling mode
254  *
255  * @param     usart:   Select the USART or the UART peripheral
256  *
257  * @retval    None
258  *
259  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
260  */
USART_EnableOverSampling8(USART_T * usart)261 void USART_EnableOverSampling8(USART_T *usart)
262 {
263     usart->CTRL1_B.OSMCFG = BIT_SET;
264 }
265 
266 /*!
267  * @brief     Disable the USART's 8x oversampling mode
268  *
269  * @param     usart:   Select the USART or the UART peripheral
270  *
271  * @retval    None
272  *
273  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
274  */
USART_DisableOverSampling8(USART_T * usart)275 void USART_DisableOverSampling8(USART_T *usart)
276 {
277     usart->CTRL1_B.OSMCFG = BIT_RESET;
278 }
279 
280 /*!
281  * @brief     Enables the USART's sample method
282  *
283  * @param     usart:   Select the USART or the UART peripheral
284  *
285  * @retval    None
286  *
287  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
288  */
USART_EnableOverSampling(USART_T * usart)289 void USART_EnableOverSampling(USART_T *usart)
290 {
291     usart->CTRL3_B.SAMCFG = BIT_SET;
292 }
293 
294 /*!
295  * @brief     Disable the USART's sample method
296  *
297  * @param     usart:   Select the USART or the UART peripheral
298  *
299  * @retval    None
300  *
301  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
302  */
USART_DisableOverSampling(USART_T * usart)303 void USART_DisableOverSampling(USART_T *usart)
304 {
305     usart->CTRL3_B.SAMCFG = BIT_RESET;
306 }
307 
308 /*!
309  * @brief     Transmits single data
310  *
311  * @param     usart: Select the USART or the UART peripheral
312  *
313  * @param     data:  the data to transmit
314  *
315  * @retval    None
316  *
317  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
318  */
USART_TxData(USART_T * usart,uint16_t data)319 void USART_TxData(USART_T *usart, uint16_t data)
320 {
321     usart->DATA_B.DATA = data;
322 }
323 
324 /*!
325  * @brief     Returns the most recent received data
326  *
327  * @param     usart: Select the USART or the UART peripheral
328  *
329  * @retval    None
330  *
331  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
332  */
USART_RxData(USART_T * usart)333 uint16_t USART_RxData(USART_T *usart)
334 {
335     return (uint16_t)(usart->DATA_B.DATA);
336 }
337 
338 /*!
339  * @brief     Configures the address of the USART node
340  *
341  * @param     usart:   Select the USART or the UART peripheral
342  *
343  * @param     address: Indicates the address of the USART node
344  *
345  * @retval    None
346  *
347  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
348  */
USART_Address(USART_T * usart,uint8_t address)349 void USART_Address(USART_T *usart, uint8_t address)
350 {
351     usart->CTRL2_B.ADDR = address;
352 }
353 
354 /*!
355  * @brief     Enable USART Receiver in mute mode
356  *
357  * @param     usart: Select the USART or the UART peripheral
358  *
359  * @retval    None
360  *
361  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
362  */
USART_EnableMuteMode(USART_T * usart)363 void USART_EnableMuteMode(USART_T *usart)
364 {
365     usart->CTRL1_B.RXMUTEEN = BIT_SET;
366 }
367 
368 /*!
369  * @brief     Disable USART Receiver in active mode
370  *
371  * @param     usart: Select the USART or the UART peripheral
372  *
373  * @retval    None
374  *
375  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
376  */
USART_DisableMuteMode(USART_T * usart)377 void USART_DisableMuteMode(USART_T *usart)
378 {
379     usart->CTRL1_B.RXMUTEEN = BIT_RESET;
380 }
381 
382 /*!
383  * @brief     Selects the USART WakeUp method.
384  *
385  * @param     usart:  Select the USART or the UART peripheral
386  *
387  * @param     wakeup: Specifies the selected USART auto baud rate method
388  *                    This parameter can be one of the following values:
389  *                    @arg USART_WAKEUP_IDLE_LINE    : WakeUp by an idle line detection
390  *                    @arg USART_WAKEUP_ADDRESS_MARK : WakeUp by an address mark
391  *
392  * @retval    None
393  *
394  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
395  */
USART_ConfigWakeUp(USART_T * usart,USART_WAKEUP_T wakeup)396 void USART_ConfigWakeUp(USART_T *usart, USART_WAKEUP_T wakeup)
397 {
398     usart->CTRL1_B.WUPMCFG = wakeup;
399 }
400 
401 /*!
402  * @brief     Sets the USART LIN Break detection length
403  *
404  * @param     usart:   Select the USART or the UART peripheral
405  *
406  * @param     length:  Specifies the LIN break detection length
407  *                     This parameter can be one of the following values:
408  *                     @arg USART_LBDL_10B : 10-bit break detection
409  *                     @arg USART_LBDL_11B : 11-bit break detection
410  *
411  * @retval    None
412  *
413  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
414  */
USART_ConfigLINBreakDetectLength(USART_T * usart,USART_LBDL_T length)415 void USART_ConfigLINBreakDetectLength(USART_T *usart, USART_LBDL_T length)
416 {
417     usart->CTRL2_B.LBDLCFG = length;
418 }
419 
420 /*!
421  * @brief     Enables the USART LIN MODE
422  *
423  * @param     usart:   Select the USART or the UART peripheral
424  *
425  * @retval    None
426  *
427  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
428  */
USART_EnableLIN(USART_T * usart)429 void USART_EnableLIN(USART_T *usart)
430 {
431     usart->CTRL2_B.LINMEN = BIT_SET;
432 }
433 
434 /*!
435  * @brief     Disable the USART LIN MODE
436  *
437  * @param     usart: Select the USART or the UART peripheral
438  *
439  * @retval    None
440  *
441  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
442  */
USART_DisableLIN(USART_T * usart)443 void USART_DisableLIN(USART_T *usart)
444 {
445     usart->CTRL2_B.LINMEN = BIT_RESET;
446 }
447 
448 /*!
449  * @brief     Transmits break characters
450  *
451  * @param     usart: Select the USART or the UART peripheral
452  *
453  * @retval    None
454  *
455  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
456  */
USART_TxBreak(USART_T * usart)457 void USART_TxBreak(USART_T *usart)
458 {
459     usart->CTRL1_B.TXBF = BIT_SET;
460 }
461 
462 /*!
463  * @brief     Enables USART Half Duplex communication
464  *
465  * @param     usart: Select the USART or the UART peripheral
466  *
467  * @retval    None
468  *
469  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
470  */
USART_EnableHalfDuplex(USART_T * usart)471 void USART_EnableHalfDuplex(USART_T *usart)
472 {
473     usart->CTRL3_B.HDEN = BIT_SET;
474 }
475 
476 /*!
477  * @brief     Disable USART Half Duplex communication
478  *
479  * @param     usart: Select the USART or the UART peripheral
480  *
481  * @retval    None
482  *
483  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
484  */
USART_DisableHalfDuplex(USART_T * usart)485 void USART_DisableHalfDuplex(USART_T *usart)
486 {
487     usart->CTRL3_B.HDEN = BIT_RESET;
488 }
489 
490 /*!
491  * @brief     Sets the specified USART guard time
492  *
493  * @param     usart:     Select the USART or the UART peripheral
494  *
495  * @param     guardTime: Specifies the guard time
496  *
497  * @retval    None
498  *
499  * @note      The specified USART guard time is not available for UART4 and UART5
500  */
USART_ConfigGuardTime(USART_T * usart,uint8_t guardTime)501 void USART_ConfigGuardTime(USART_T *usart, uint8_t guardTime)
502 {
503     usart->GTPSC_B.GRDT = guardTime;
504 }
505 
506 /*!
507  * @brief     Enables the USART Smart Card mode
508  *
509  * @param     usart: Select the USART or the UART peripheral
510  *
511  * @retval    None
512  *
513  * @note      The Smart Card mode is not available for UART4 and UART5
514  */
USART_EnableSmartCard(USART_T * usart)515 void USART_EnableSmartCard(USART_T *usart)
516 {
517     usart->CTRL3_B.SCEN = BIT_SET;
518 }
519 
520 /*!
521  * @brief     Disable the USART Smart Card mode
522  *
523  * @param     usart: Select the USART or the UART peripheral
524  *
525  * @retval    None
526  *
527  * @note      The Smart Card mode is not available for UART4 and UART5
528  */
USART_DisableSmartCard(USART_T * usart)529 void USART_DisableSmartCard(USART_T *usart)
530 {
531     usart->CTRL3_B.SCEN = BIT_RESET;
532 }
533 
534 /*!
535  * @brief     Enables NACK transmission
536  *
537  * @param     usart: Select the USART or the UART peripheral
538  *
539  * @retval    None
540  *
541  * @note      The Smart Card mode is not available for UART4 and UART5
542  */
USART_EnableSmartCardNACK(USART_T * usart)543 void USART_EnableSmartCardNACK(USART_T *usart)
544 {
545     usart->CTRL3_B.SCNACKEN = BIT_SET;
546 }
547 
548 /*!
549  * @brief     Disable NACK transmission
550  *
551  * @param     usart: Select the USART or the UART peripheral
552  *
553  * @retval    None
554  *
555  * @note      The Smart Card mode is not available for UART4 and UART5
556  */
USART_DisableSmartCardNACK(USART_T * usart)557 void USART_DisableSmartCardNACK(USART_T *usart)
558 {
559     usart->CTRL3_B.SCNACKEN = BIT_RESET;
560 }
561 
562 /*!
563  * @brief     Configures the USART's IrDA interface
564  *
565  * @param     usart:    Select the USART or the UART peripheral
566  *
567  * @param     IrDAMode: Specifies the IrDA mode
568  *                      This parameter can be one of the following values:
569  *                      @arg USART_IRDALP_NORMAL    : Normal
570  *                      @arg USART_IRDALP_LOWPOWER  : Low-Power
571  * @retval    None
572  *
573  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
574  */
USART_ConfigIrDA(USART_T * usart,USART_IRDALP_T IrDAMode)575 void USART_ConfigIrDA(USART_T *usart, USART_IRDALP_T IrDAMode)
576 {
577     usart->CTRL3_B.IRLPEN = IrDAMode;
578 }
579 
580 /*!
581  * @brief     Enables the USART's IrDA interface
582  *
583  * @param     usart: Select the USART or the UART peripheral
584  *
585  * @retval    None
586  *
587  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
588  */
USART_EnableIrDA(USART_T * usart)589 void USART_EnableIrDA(USART_T *usart)
590 {
591     usart->CTRL3_B.IREN = BIT_SET;
592 }
593 
594 /*!
595  * @brief     Disable the USART's IrDA interface
596  *
597  * @param     usart: Select the USART or the UART peripheral
598  *
599  * @retval    None
600  *
601  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
602  */
USART_DisableIrDA(USART_T * usart)603 void USART_DisableIrDA(USART_T *usart)
604 {
605     usart->CTRL3_B.IREN = BIT_RESET;
606 }
607 
608 /*!
609  * @brief     Enables the USART DMA interface
610  *
611  * @param     usart:   Select the USART or the UART peripheral
612  *
613  * @param     dmaReq:  Specifies the DMA request
614  *                     This parameter can be one of the following values:
615  *                     @arg USART_DMA_TX    : USART DMA receive request
616  *                     @arg USART_DMA_RX    : USART DMA transmit request
617  *                     @arg USART_DMA_TX_RX : USART DMA transmit/receive request
618  *
619  * @retval    None
620  *
621  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
622  */
USART_EnableDMA(USART_T * usart,USART_DMA_T dmaReq)623 void USART_EnableDMA(USART_T *usart, USART_DMA_T dmaReq)
624 {
625     usart->CTRL3_B.DMARXEN = dmaReq & 0x01;
626     usart->CTRL3_B.DMATXEN = dmaReq >> 1;
627 }
628 
629 /*!
630  * @brief     Disable the USART DMA interface
631  *
632  * @param     usart:   Select the USART or the UART peripheral
633  *
634  * @param     dmaReq:  Specifies the DMA request
635  *                     This parameter can be one of the following values:
636  *                     @arg USART_DMA_TX    : USART DMA receive request
637  *                     @arg USART_DMA_RX    : USART DMA transmit request
638  *                     @arg USART_DMA_TX_RX : USART DMA transmit/receive request
639  *
640  * @retval    None
641  *
642  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
643  */
USART_DisableDMA(USART_T * usart,USART_DMA_T dmaReq)644 void USART_DisableDMA(USART_T *usart, USART_DMA_T dmaReq)
645 {
646     usart->CTRL3_B.DMARXEN = !(dmaReq & 0x01);
647     usart->CTRL3_B.DMATXEN = !(dmaReq >> 1);
648 }
649 
650 /*!
651  * @brief     Enable the specified USART interrupts
652  *
653  * @param     usart: Select the USART or the UART peripheral
654  *
655  * @param     interrupt: Specifies the USART interrupts sources
656  *                       The parameter can be one of following values:
657  *                       @arg USART_INT_PE      : Parity error interrupt
658  *                       @arg USART_INT_TXBE    : Tansmit data buffer empty interrupt
659  *                       @arg USART_INT_TXC     : Transmission complete interrupt
660  *                       @arg USART_INT_RXBNE   : Receive data buffer not empty interrupt
661  *                       @arg USART_INT_IDLE    : Idle line detection interrupt
662  *                       @arg USART_INT_LBD     : LIN break detection interrupt
663  *                       @arg USART_INT_CTS     : CTS change interrupt
664  *                       @arg USART_INT_ERR     : Error interrupt(Frame error, noise error, overrun error)
665  *
666  * @retval    None
667  *
668  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
669  */
USART_EnableInterrupt(USART_T * usart,USART_INT_T interrupt)670 void USART_EnableInterrupt(USART_T *usart, USART_INT_T interrupt)
671 {
672     uint32_t temp;
673 
674     temp = (uint32_t)(interrupt & 0xffff);
675 
676     if (interrupt & 0x10000)
677     {
678         usart->CTRL1 |= temp;
679     }
680 
681     if (interrupt & 0x20000)
682     {
683         usart->CTRL2 |= temp;
684     }
685 
686     if (interrupt & 0x40000)
687     {
688         usart->CTRL3 |= temp;
689     }
690 }
691 
692 /*!
693  * @brief     Disables the specified USART interrupts
694  *
695  * @param     usart: Select the USART or the UART peripheral
696  *
697  * @param     interrupt: Specifies the USART interrupts sources
698  *                       The parameter can be one of following values:
699  *                       @arg USART_INT_PE      : Parity error interrupt
700  *                       @arg USART_INT_TXBE    : Tansmit data buffer empty interrupt
701  *                       @arg USART_INT_TXC     : Transmission complete interrupt
702  *                       @arg USART_INT_RXBNE   : Receive data buffer not empty interrupt
703  *                       @arg USART_INT_IDLE    : Idle line detection interrupt
704  *                       @arg USART_INT_LBD     : LIN break detection interrupt
705  *                       @arg USART_INT_CTS     : CTS change interrupt
706  *                       @arg USART_INT_ERR     : Error interrupt(Frame error, noise error, overrun error)
707  *
708  * @retval    None
709  *
710  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
711  */
USART_DisableInterrupt(USART_T * usart,USART_INT_T interrupt)712 void USART_DisableInterrupt(USART_T *usart, USART_INT_T interrupt)
713 {
714     uint32_t temp;
715 
716     temp = (uint32_t)~(interrupt & 0xffff);
717 
718     if (interrupt & 0x10000)
719     {
720         usart->CTRL1 &= temp;
721     }
722 
723     if (interrupt & 0x20000)
724     {
725         usart->CTRL2 &= temp;
726     }
727 
728     if (interrupt & 0x40000)
729     {
730         usart->CTRL3 &= temp;
731     }
732 }
733 
734 /*!
735  * @brief     Read the specified USART flag
736  *
737  * @param     usart: Select the USART or the UART peripheral
738  *
739  * @param     flag: Specifies the flag to check
740  *                  The parameter can be one of following values:
741  *                  @arg USART_FLAG_CTS     : CTS Change flag (not available for UART4 and UART5)
742  *                  @arg USART_FLAG_LBD     : LIN Break detection flag
743  *                  @arg USART_FLAG_TXBE    : Transmit data buffer empty flag
744  *                  @arg USART_FLAG_TXC     : Transmission Complete flag
745  *                  @arg USART_FLAG_RXBNE   : Receive data buffer not empty flag
746  *                  @arg USART_FLAG_IDLE    : Idle Line detection flag
747  *                  @arg USART_FLAG_OVRE    : OverRun Error flag
748  *                  @arg USART_FLAG_NE      : Noise Error flag
749  *                  @arg USART_FLAG_FE      : Framing Error flag
750  *                  @arg USART_FLAG_PE      : Parity Error flag
751  *
752  * @retval    The new state of flag (SET or RESET)
753  *
754  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
755  */
USART_ReadStatusFlag(USART_T * usart,USART_FLAG_T flag)756 uint8_t USART_ReadStatusFlag(USART_T *usart, USART_FLAG_T flag)
757 {
758     return (usart->STS & flag) ? SET : RESET;
759 }
760 
761 /*!
762  * @brief     Clears the USARTx's pending flags
763  *
764  * @param     usart: Select the USART or the UART peripheral
765  *
766  * @param     flag: Specifies the flag to clear
767  *                  The parameter can be one of following values:
768  *                  @arg USART_FLAG_CTS     : CTS Change flag (not available for UART4 and UART5)
769  *                  @arg USART_FLAG_LBD     : LIN Break detection flag
770  *                  @arg USART_FLAG_TXC     : Transmission Complete flag
771  *                  @arg USART_FLAG_RXBNE   : Receive data buffer not empty flag
772  *
773  * @retval    None
774  *
775  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
776  */
USART_ClearStatusFlag(USART_T * usart,USART_FLAG_T flag)777 void USART_ClearStatusFlag(USART_T *usart, USART_FLAG_T flag)
778 {
779     usart->STS &= (uint32_t)~flag;
780 }
781 
782 /*!
783  * @brief     Read the specified USART interrupt flag
784  *
785  * @param     usart: Select the USART or the UART peripheral
786  *
787  * @param     flag:  Specifies the USART interrupt source to check
788  *                        The parameter can be one of following values:
789  *                        @arg USART_INT_TXBE    : Tansmit data buffer empty interrupt
790  *                        @arg USART_INT_TXC     : Transmission complete interrupt
791  *                        @arg USART_INT_RXBNE   : Receive data buffer not empty interrupt
792  *                        @arg USART_INT_IDLE    : Idle line detection interrupt
793  *                        @arg USART_INT_LBD     : LIN break detection interrupt
794  *                        @arg USART_INT_CTS     : CTS change interrupt
795  *                        @arg USART_INT_OVRE_RX : OverRun Error interruptpt if the RXBNFLG bit is set
796  *                        @arg USART_INT_OVRE_ER : OverRun Error interruptpt if the EIE bit is set
797  *                        @arg USART_INT_NE      : Noise Error interrupt
798  *                        @arg USART_INT_FE      : Framing Error interrupt
799  *                        @arg USART_INT_PE      : Parity error interrupt
800  *
801  * @retval    The new state of flag (SET or RESET)
802  *
803  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
804  */
USART_ReadIntFlag(USART_T * usart,USART_INT_T flag)805 uint8_t USART_ReadIntFlag(USART_T *usart, USART_INT_T flag)
806 {
807     uint32_t itFlag, srFlag;
808 
809     if (flag & 0x10000)
810     {
811         itFlag = usart->CTRL1 & flag & 0xffff;
812     }
813     else if (flag & 0x20000)
814     {
815         itFlag = usart->CTRL2 & flag & 0xffff;
816     }
817     else
818     {
819         itFlag = usart->CTRL3 & flag & 0xffff;
820     }
821 
822     srFlag = flag >> 24;
823     srFlag = (uint32_t)(1 << srFlag);
824     srFlag = usart->STS & srFlag;
825 
826     if (srFlag && itFlag)
827     {
828         return SET;
829     }
830 
831     return RESET;
832 }
833 
834 /*!
835  * @brief     Clears the USART interrupt pending bits
836  *
837  * @param     usart: Select the USART or the UART peripheral
838  *
839  * @param     flag: Specifies the interrupt pending bit to clear
840  *                  The parameter can be one of following values:
841  *                  @arg USART_INT_RXBNE : Receive data buffer not empty interrupt
842  *                  @arg USART_INT_TXC   : Transmission complete interrupt
843  *                  @arg USART_INT_LBD   : LIN break detection interrupt
844  *                  @arg USART_INT_CTS   : CTS change interrupt
845  *
846  * @retval    None
847  *
848  * @note      The usart can be USART1, USART2, USART3, UART4, UART5, USART6, UART7 and UART8
849  */
USART_ClearIntFlag(USART_T * usart,USART_INT_T flag)850 void USART_ClearIntFlag(USART_T *usart, USART_INT_T flag)
851 {
852     uint32_t srFlag;
853 
854     srFlag = flag >> 24;
855     srFlag = (uint32_t)(1 << srFlag);
856 
857     usart->STS &= (uint32_t)~srFlag;
858 }
859 
860 /**@} end of group USART_Functions */
861 /**@} end of group USART_Driver */
862 /**@} end of group APM32F4xx_StdPeriphDriver */
863