1 /*!
2     \file    gd32f4xx_usart.c
3     \brief   USART driver
4 
5     \version 2016-08-15, V1.0.0, firmware for GD32F4xx
6     \version 2018-12-12, V2.0.0, firmware for GD32F4xx
7     \version 2020-09-30, V2.1.0, firmware for GD32F4xx
8     \version 2022-03-09, V3.0.0, firmware for GD32F4xx
9 */
10 
11 /*
12     Copyright (c) 2022, GigaDevice Semiconductor Inc.
13 
14     Redistribution and use in source and binary forms, with or without modification,
15 are permitted provided that the following conditions are met:
16 
17     1. Redistributions of source code must retain the above copyright notice, this
18        list of conditions and the following disclaimer.
19     2. Redistributions in binary form must reproduce the above copyright notice,
20        this list of conditions and the following disclaimer in the documentation
21        and/or other materials provided with the distribution.
22     3. Neither the name of the copyright holder nor the names of its contributors
23        may be used to endorse or promote products derived from this software without
24        specific prior written permission.
25 
26     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
35 OF SUCH DAMAGE.
36 */
37 
38 #include "gd32f4xx_usart.h"
39 
40 /* USART register bit offset */
41 #define GP_GUAT_OFFSET            ((uint32_t)8U)       /* bit offset of GUAT in USART_GP */
42 #define CTL3_SCRTNUM_OFFSET       ((uint32_t)1U)       /* bit offset of SCRTNUM in USART_CTL3 */
43 #define RT_BL_OFFSET              ((uint32_t)24U)      /* bit offset of BL in USART_RT */
44 
45 /*!
46     \brief    reset USART/UART
47     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
48     \param[out] none
49     \retval     none
50 */
usart_deinit(uint32_t usart_periph)51 void usart_deinit(uint32_t usart_periph)
52 {
53     switch(usart_periph) {
54     case USART0:
55         rcu_periph_reset_enable(RCU_USART0RST);
56         rcu_periph_reset_disable(RCU_USART0RST);
57         break;
58     case USART1:
59         rcu_periph_reset_enable(RCU_USART1RST);
60         rcu_periph_reset_disable(RCU_USART1RST);
61         break;
62     case USART2:
63         rcu_periph_reset_enable(RCU_USART2RST);
64         rcu_periph_reset_disable(RCU_USART2RST);
65         break;
66     case USART5:
67         rcu_periph_reset_enable(RCU_USART5RST);
68         rcu_periph_reset_disable(RCU_USART5RST);
69         break;
70     case UART3:
71         rcu_periph_reset_enable(RCU_UART3RST);
72         rcu_periph_reset_disable(RCU_UART3RST);
73         break;
74     case UART4:
75         rcu_periph_reset_enable(RCU_UART4RST);
76         rcu_periph_reset_disable(RCU_UART4RST);
77         break;
78     case UART6:
79         rcu_periph_reset_enable(RCU_UART6RST);
80         rcu_periph_reset_disable(RCU_UART6RST);
81         break;
82     case UART7:
83         rcu_periph_reset_enable(RCU_UART7RST);
84         rcu_periph_reset_disable(RCU_UART7RST);
85         break;
86     default:
87         break;
88     }
89 }
90 
91 /*!
92     \brief    configure USART baud rate value
93     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
94     \param[in]  baudval: baud rate value
95     \param[out] none
96     \retval     none
97 */
usart_baudrate_set(uint32_t usart_periph,uint32_t baudval)98 void usart_baudrate_set(uint32_t usart_periph, uint32_t baudval)
99 {
100     uint32_t uclk = 0U, intdiv = 0U, fradiv = 0U, udiv = 0U;
101     switch(usart_periph) {
102     /* get clock frequency */
103     case USART0:
104         uclk = rcu_clock_freq_get(CK_APB2);
105         break;
106     case USART5:
107         uclk = rcu_clock_freq_get(CK_APB2);
108         break;
109     case USART1:
110         uclk = rcu_clock_freq_get(CK_APB1);
111         break;
112     case USART2:
113         uclk = rcu_clock_freq_get(CK_APB1);
114         break;
115     case UART3:
116         uclk = rcu_clock_freq_get(CK_APB1);
117         break;
118     case UART4:
119         uclk = rcu_clock_freq_get(CK_APB1);
120         break;
121     case UART6:
122         uclk = rcu_clock_freq_get(CK_APB1);
123         break;
124     case UART7:
125         uclk = rcu_clock_freq_get(CK_APB1);
126         break;
127     default:
128         break;
129     }
130     if(USART_CTL0(usart_periph) & USART_CTL0_OVSMOD) {
131         /* when oversampling by 8, configure the value of USART_BAUD */
132         udiv = ((2U * uclk) + baudval / 2U) / baudval;
133         intdiv = udiv & 0xfff0U;
134         fradiv = (udiv >> 1U) & 0x7U;
135         USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv));
136     } else {
137         /* when oversampling by 16, configure the value of USART_BAUD */
138         udiv = (uclk + baudval / 2U) / baudval;
139         intdiv = udiv & 0xfff0U;
140         fradiv = udiv & 0xfU;
141         USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv));
142     }
143 }
144 
145 /*!
146     \brief   configure USART parity function
147     \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
148     \param[in] paritycfg: configure USART parity
149                only one parameter can be selected which is shown as below:
150       \arg       USART_PM_NONE: no parity
151       \arg       USART_PM_EVEN: even parity
152       \arg       USART_PM_ODD:  odd parity
153     \param[out] none
154     \retval     none
155 */
usart_parity_config(uint32_t usart_periph,uint32_t paritycfg)156 void usart_parity_config(uint32_t usart_periph, uint32_t paritycfg)
157 {
158     /* clear USART_CTL0 PM,PCEN Bits */
159     USART_CTL0(usart_periph) &= ~(USART_CTL0_PM | USART_CTL0_PCEN);
160     /* configure USART parity mode */
161     USART_CTL0(usart_periph) |= paritycfg ;
162 }
163 
164 /*!
165     \brief   configure USART word length
166     \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
167     \param[in] wlen: USART word length configure
168                only one parameter can be selected which is shown as below:
169       \arg       USART_WL_8BIT: 8 bits
170       \arg       USART_WL_9BIT: 9 bits
171     \param[out] none
172     \retval     none
173 */
usart_word_length_set(uint32_t usart_periph,uint32_t wlen)174 void usart_word_length_set(uint32_t usart_periph, uint32_t wlen)
175 {
176     /* clear USART_CTL0 WL bit */
177     USART_CTL0(usart_periph) &= ~USART_CTL0_WL;
178     /* configure USART word length */
179     USART_CTL0(usart_periph) |= wlen;
180 }
181 
182 /*!
183     \brief   configure USART stop bit length
184     \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
185     \param[in] stblen: USART stop bit configure
186                only one parameter can be selected which is shown as below:
187       \arg       USART_STB_1BIT:   1 bit
188       \arg       USART_STB_0_5BIT: 0.5 bit(not available for UARTx(x=3,4,6,7))
189       \arg       USART_STB_2BIT:   2 bits
190       \arg       USART_STB_1_5BIT: 1.5 bits(not available for UARTx(x=3,4,6,7))
191     \param[out] none
192     \retval     none
193 */
usart_stop_bit_set(uint32_t usart_periph,uint32_t stblen)194 void usart_stop_bit_set(uint32_t usart_periph, uint32_t stblen)
195 {
196     /* clear USART_CTL1 STB bits */
197     USART_CTL1(usart_periph) &= ~USART_CTL1_STB;
198     /* configure USART stop bits */
199     USART_CTL1(usart_periph) |= stblen;
200 }
201 /*!
202     \brief    enable USART
203     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
204     \param[out] none
205     \retval     none
206 */
usart_enable(uint32_t usart_periph)207 void usart_enable(uint32_t usart_periph)
208 {
209     USART_CTL0(usart_periph) |= USART_CTL0_UEN;
210 }
211 
212 /*!
213     \brief   disable USART
214     \param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
215     \param[out] none
216     \retval     none
217 */
usart_disable(uint32_t usart_periph)218 void usart_disable(uint32_t usart_periph)
219 {
220     USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
221 }
222 
223 /*!
224     \brief    configure USART transmitter
225     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
226     \param[in]  txconfig: enable or disable USART transmitter
227                 only one parameter can be selected which is shown as below:
228       \arg        USART_TRANSMIT_ENABLE: enable USART transmission
229       \arg        USART_TRANSMIT_DISABLE: enable USART transmission
230     \param[out] none
231     \retval     none
232 */
usart_transmit_config(uint32_t usart_periph,uint32_t txconfig)233 void usart_transmit_config(uint32_t usart_periph, uint32_t txconfig)
234 {
235     uint32_t ctl = 0U;
236 
237     ctl = USART_CTL0(usart_periph);
238     ctl &= ~USART_CTL0_TEN;
239     ctl |= txconfig;
240     /* configure transfer mode */
241     USART_CTL0(usart_periph) = ctl;
242 }
243 
244 /*!
245     \brief    configure USART receiver
246     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
247     \param[in]  rxconfig: enable or disable USART receiver
248                 only one parameter can be selected which is shown as below:
249       \arg        USART_RECEIVE_ENABLE: enable USART reception
250       \arg        USART_RECEIVE_DISABLE: disable USART reception
251     \param[out] none
252     \retval     none
253 */
usart_receive_config(uint32_t usart_periph,uint32_t rxconfig)254 void usart_receive_config(uint32_t usart_periph, uint32_t rxconfig)
255 {
256     uint32_t ctl = 0U;
257 
258     ctl = USART_CTL0(usart_periph);
259     ctl &= ~USART_CTL0_REN;
260     ctl |= rxconfig;
261     /* configure transfer mode */
262     USART_CTL0(usart_periph) = ctl;
263 }
264 
265 /*!
266     \brief    data is transmitted/received with the LSB/MSB first
267     \param[in]  usart_periph: USARTx(x=0,1,2,5)
268     \param[in]  msbf: LSB/MSB
269                 only one parameter can be selected which is shown as below:
270       \arg        USART_MSBF_LSB: LSB first
271       \arg        USART_MSBF_MSB: MSB first
272     \param[out] none
273     \retval     none
274 */
usart_data_first_config(uint32_t usart_periph,uint32_t msbf)275 void usart_data_first_config(uint32_t usart_periph, uint32_t msbf)
276 {
277     uint32_t ctl = 0U;
278 
279     ctl = USART_CTL3(usart_periph);
280     ctl &= ~(USART_CTL3_MSBF);
281     ctl |= msbf;
282     /* configure data transmitted/received mode */
283     USART_CTL3(usart_periph) = ctl;
284 }
285 
286 /*!
287     \brief    configure USART inversion
288     \param[in]  usart_periph: USARTx(x=0,1,2,5)
289     \param[in]  invertpara: refer to enum USART_INVERT_CONFIG
290                 only one parameter can be selected which is shown as below:
291       \arg        USART_DINV_ENABLE: data bit level inversion
292       \arg        USART_DINV_DISABLE: data bit level not inversion
293       \arg        USART_TXPIN_ENABLE: TX pin level inversion
294       \arg        USART_TXPIN_DISABLE: TX pin level not inversion
295       \arg        USART_RXPIN_ENABLE: RX pin level inversion
296       \arg        USART_RXPIN_DISABLE: RX pin level not inversion
297     \param[out] none
298     \retval     none
299 */
usart_invert_config(uint32_t usart_periph,usart_invert_enum invertpara)300 void usart_invert_config(uint32_t usart_periph, usart_invert_enum invertpara)
301 {
302     /* inverted or not the specified siginal */
303     switch(invertpara) {
304     case USART_DINV_ENABLE:
305         USART_CTL3(usart_periph) |= USART_CTL3_DINV;
306         break;
307     case USART_TXPIN_ENABLE:
308         USART_CTL3(usart_periph) |= USART_CTL3_TINV;
309         break;
310     case USART_RXPIN_ENABLE:
311         USART_CTL3(usart_periph) |= USART_CTL3_RINV;
312         break;
313     case USART_DINV_DISABLE:
314         USART_CTL3(usart_periph) &= ~(USART_CTL3_DINV);
315         break;
316     case USART_TXPIN_DISABLE:
317         USART_CTL3(usart_periph) &= ~(USART_CTL3_TINV);
318         break;
319     case USART_RXPIN_DISABLE:
320         USART_CTL3(usart_periph) &= ~(USART_CTL3_RINV);
321         break;
322     default:
323         break;
324     }
325 }
326 
327 /*!
328     \brief    configure the USART oversample mode
329     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
330     \param[in]  oversamp: oversample value
331                 only one parameter can be selected which is shown as below:
332       \arg        USART_OVSMOD_8: 8 bits
333       \arg        USART_OVSMOD_16: 16 bits
334     \param[out] none
335     \retval     none
336 */
usart_oversample_config(uint32_t usart_periph,uint32_t oversamp)337 void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp)
338 {
339     /*  clear OVSMOD bit */
340     USART_CTL0(usart_periph) &= ~(USART_CTL0_OVSMOD);
341     USART_CTL0(usart_periph) |= oversamp;
342 }
343 
344 /*!
345     \brief    configure sample bit method
346     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
347     \param[in]  obsm: sample bit
348                 only one parameter can be selected which is shown as below:
349       \arg        USART_OSB_1bit: 1 bit
350       \arg        USART_OSB_3bit: 3 bits
351     \param[out] none
352     \retval     none
353 */
usart_sample_bit_config(uint32_t usart_periph,uint32_t obsm)354 void usart_sample_bit_config(uint32_t usart_periph, uint32_t obsm)
355 {
356     USART_CTL2(usart_periph) &= ~(USART_CTL2_OSB);
357     USART_CTL2(usart_periph) |= obsm;
358 }
359 
360 /*!
361     \brief    enable receiver timeout of USART
362     \param[in]  usart_periph: USARTx(x=0,1,2,5)
363     \param[out] none
364     \retval     none
365 */
usart_receiver_timeout_enable(uint32_t usart_periph)366 void usart_receiver_timeout_enable(uint32_t usart_periph)
367 {
368     USART_CTL3(usart_periph) |= USART_CTL3_RTEN;
369 }
370 
371 /*!
372     \brief    disable receiver timeout of USART
373     \param[in]  usart_periph: USARTx(x=0,1,2,5)
374     \param[out] none
375     \retval     none
376 */
usart_receiver_timeout_disable(uint32_t usart_periph)377 void usart_receiver_timeout_disable(uint32_t usart_periph)
378 {
379     USART_CTL3(usart_periph) &= ~(USART_CTL3_RTEN);
380 }
381 
382 /*!
383     \brief    set the receiver timeout threshold of USART
384     \param[in]  usart_periph: USARTx(x=0,1,2,5)
385     \param[in]  rtimeout: 0-0x00FFFFFF
386     \param[out] none
387     \retval     none
388 */
usart_receiver_timeout_threshold_config(uint32_t usart_periph,uint32_t rtimeout)389 void usart_receiver_timeout_threshold_config(uint32_t usart_periph, uint32_t rtimeout)
390 {
391     USART_RT(usart_periph) &= ~(USART_RT_RT);
392     USART_RT(usart_periph) |= rtimeout;
393 }
394 
395 /*!
396     \brief    USART transmit data function
397     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
398     \param[in]  data: data of transmission
399     \param[out] none
400     \retval     none
401 */
usart_data_transmit(uint32_t usart_periph,uint32_t data)402 void usart_data_transmit(uint32_t usart_periph, uint32_t data)
403 {
404     USART_DATA(usart_periph) = ((uint16_t)USART_DATA_DATA & data);
405 }
406 
407 /*!
408     \brief    USART receive data function
409     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
410     \param[out] none
411     \retval     data of received
412 */
usart_data_receive(uint32_t usart_periph)413 uint16_t usart_data_receive(uint32_t usart_periph)
414 {
415     return (uint16_t)(GET_BITS(USART_DATA(usart_periph), 0U, 8U));
416 }
417 
418 /*!
419     \brief    configure the address of the USART in wake up by address match mode
420     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
421     \param[in]  addr: address of USART/UART
422     \param[out] none
423     \retval     none
424 */
usart_address_config(uint32_t usart_periph,uint8_t addr)425 void usart_address_config(uint32_t usart_periph, uint8_t addr)
426 {
427     USART_CTL1(usart_periph) &= ~(USART_CTL1_ADDR);
428     USART_CTL1(usart_periph) |= (USART_CTL1_ADDR & addr);
429 }
430 
431 /*!
432     \brief    enable mute mode
433     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
434     \param[out] none
435     \retval     none
436 */
usart_mute_mode_enable(uint32_t usart_periph)437 void usart_mute_mode_enable(uint32_t usart_periph)
438 {
439     USART_CTL0(usart_periph) |= USART_CTL0_RWU;
440 }
441 
442 /*!
443     \brief    disable mute mode
444     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
445     \param[out] none
446     \retval     none
447 */
usart_mute_mode_disable(uint32_t usart_periph)448 void usart_mute_mode_disable(uint32_t usart_periph)
449 {
450     USART_CTL0(usart_periph) &= ~(USART_CTL0_RWU);
451 }
452 
453 /*!
454     \brief    configure wakeup method in mute mode
455     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
456     \param[in]  wmehtod: two method be used to enter or exit the mute mode
457                 only one parameter can be selected which is shown as below:
458       \arg        USART_WM_IDLE: idle line
459       \arg        USART_WM_ADDR: address mask
460     \param[out] none
461     \retval     none
462 */
usart_mute_mode_wakeup_config(uint32_t usart_periph,uint32_t wmehtod)463 void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmehtod)
464 {
465     USART_CTL0(usart_periph) &= ~(USART_CTL0_WM);
466     USART_CTL0(usart_periph) |= wmehtod;
467 }
468 
469 /*!
470     \brief    enable LIN mode
471     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
472     \param[out] none
473     \retval     none
474 */
usart_lin_mode_enable(uint32_t usart_periph)475 void usart_lin_mode_enable(uint32_t usart_periph)
476 {
477     USART_CTL1(usart_periph) |= USART_CTL1_LMEN;
478 }
479 
480 /*!
481     \brief    disable LIN mode
482     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
483     \param[out] none
484     \retval     none
485 */
usart_lin_mode_disable(uint32_t usart_periph)486 void usart_lin_mode_disable(uint32_t usart_periph)
487 {
488     USART_CTL1(usart_periph) &= ~(USART_CTL1_LMEN);
489 }
490 
491 /*!
492     \brief    configure lin break frame length
493     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
494     \param[in]  lblen: lin break frame length
495                 only one parameter can be selected which is shown as below:
496       \arg        USART_LBLEN_10B: 10 bits
497       \arg        USART_LBLEN_11B: 11 bits
498     \param[out] none
499     \retval     none
500 */
usart_lin_break_detection_length_config(uint32_t usart_periph,uint32_t lblen)501 void usart_lin_break_detection_length_config(uint32_t usart_periph, uint32_t lblen)
502 {
503     USART_CTL1(usart_periph) &= ~(USART_CTL1_LBLEN);
504     USART_CTL1(usart_periph) |= (USART_CTL1_LBLEN & lblen);
505 }
506 
507 /*!
508     \brief    send break frame
509     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
510     \param[out] none
511     \retval     none
512 */
usart_send_break(uint32_t usart_periph)513 void usart_send_break(uint32_t usart_periph)
514 {
515     USART_CTL0(usart_periph) |= USART_CTL0_SBKCMD;
516 }
517 
518 /*!
519     \brief    enable half duplex mode
520     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
521     \param[out] none
522     \retval     none
523 */
usart_halfduplex_enable(uint32_t usart_periph)524 void usart_halfduplex_enable(uint32_t usart_periph)
525 {
526     USART_CTL2(usart_periph) |= USART_CTL2_HDEN;
527 }
528 
529 /*!
530     \brief    disable half duplex mode
531     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
532     \param[out] none
533     \retval     none
534 */
usart_halfduplex_disable(uint32_t usart_periph)535 void usart_halfduplex_disable(uint32_t usart_periph)
536 {
537     USART_CTL2(usart_periph) &= ~(USART_CTL2_HDEN);
538 }
539 
540 /*!
541     \brief    enable CK pin in synchronous mode
542     \param[in]  usart_periph: USARTx(x=0,1,2,5)
543     \param[out] none
544     \retval     none
545 */
usart_synchronous_clock_enable(uint32_t usart_periph)546 void usart_synchronous_clock_enable(uint32_t usart_periph)
547 {
548     USART_CTL1(usart_periph) |= USART_CTL1_CKEN;
549 }
550 
551 /*!
552     \brief    disable CK pin in synchronous mode
553     \param[in]  usart_periph: USARTx(x=0,1,2,5)
554     \param[out] none
555     \retval     none
556 */
usart_synchronous_clock_disable(uint32_t usart_periph)557 void usart_synchronous_clock_disable(uint32_t usart_periph)
558 {
559     USART_CTL1(usart_periph) &= ~(USART_CTL1_CKEN);
560 }
561 
562 /*!
563     \brief    configure USART synchronous mode parameters
564     \param[in]  usart_periph: USARTx(x=0,1,2,5)
565     \param[in]  clen: CK length
566                 only one parameter can be selected which is shown as below:
567       \arg        USART_CLEN_NONE: there are 7 CK pulses for an 8 bit frame and 8 CK pulses for a 9 bit frame
568       \arg        USART_CLEN_EN:   there are 8 CK pulses for an 8 bit frame and 9 CK pulses for a 9 bit frame
569     \param[in]  cph: clock phase
570                 only one parameter can be selected which is shown as below:
571       \arg        USART_CPH_1CK: first clock transition is the first data capture edge
572       \arg        USART_CPH_2CK: second clock transition is the first data capture edge
573     \param[in]  cpl: clock polarity
574                 only one parameter can be selected which is shown as below:
575       \arg        USART_CPL_LOW:  steady low value on CK pin
576       \arg        USART_CPL_HIGH: steady high value on CK pin
577     \param[out] none
578     \retval     none
579 */
usart_synchronous_clock_config(uint32_t usart_periph,uint32_t clen,uint32_t cph,uint32_t cpl)580 void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32_t cph, uint32_t cpl)
581 {
582     uint32_t ctl = 0U;
583 
584     /* read USART_CTL1 register */
585     ctl = USART_CTL1(usart_periph);
586     ctl &= ~(USART_CTL1_CLEN | USART_CTL1_CPH | USART_CTL1_CPL);
587     /* set CK length, CK phase, CK polarity */
588     ctl |= (USART_CTL1_CLEN & clen) | (USART_CTL1_CPH & cph) | (USART_CTL1_CPL & cpl);
589 
590     USART_CTL1(usart_periph) = ctl;
591 }
592 
593 /*!
594     \brief    configure guard time value in smartcard mode
595     \param[in]  usart_periph: USARTx(x=0,1,2,5)
596     \param[in]  guat: guard time value, 0-0xFF
597     \param[out] none
598     \retval     none
599 */
usart_guard_time_config(uint32_t usart_periph,uint32_t guat)600 void usart_guard_time_config(uint32_t usart_periph, uint32_t guat)
601 {
602     USART_GP(usart_periph) &= ~(USART_GP_GUAT);
603     USART_GP(usart_periph) |= (USART_GP_GUAT & ((guat) << GP_GUAT_OFFSET));
604 }
605 
606 /*!
607     \brief    enable smartcard mode
608     \param[in]  usart_periph: USARTx(x=0,1,2,5)
609     \param[out] none
610     \retval     none
611 */
usart_smartcard_mode_enable(uint32_t usart_periph)612 void usart_smartcard_mode_enable(uint32_t usart_periph)
613 {
614     USART_CTL2(usart_periph) |= USART_CTL2_SCEN;
615 }
616 
617 /*!
618     \brief    disable smartcard mode
619     \param[in]  usart_periph: USARTx(x=0,1,2,5)
620     \param[out] none
621     \retval     none
622 */
usart_smartcard_mode_disable(uint32_t usart_periph)623 void usart_smartcard_mode_disable(uint32_t usart_periph)
624 {
625     USART_CTL2(usart_periph) &= ~(USART_CTL2_SCEN);
626 }
627 
628 /*!
629     \brief    enable NACK in smartcard mode
630     \param[in]  usart_periph: USARTx(x=0,1,2,5)
631     \param[out] none
632     \retval     none
633 */
usart_smartcard_mode_nack_enable(uint32_t usart_periph)634 void usart_smartcard_mode_nack_enable(uint32_t usart_periph)
635 {
636     USART_CTL2(usart_periph) |= USART_CTL2_NKEN;
637 }
638 
639 /*!
640     \brief    disable NACK in smartcard mode
641     \param[in]  usart_periph: USARTx(x=0,1,2,5)
642     \param[out] none
643     \retval     none
644 */
usart_smartcard_mode_nack_disable(uint32_t usart_periph)645 void usart_smartcard_mode_nack_disable(uint32_t usart_periph)
646 {
647     USART_CTL2(usart_periph) &= ~(USART_CTL2_NKEN);
648 }
649 
650 /*!
651     \brief    configure smartcard auto-retry number
652     \param[in]  usart_periph: USARTx(x=0,1,2,5)
653     \param[in]  scrtnum: smartcard auto-retry number
654     \param[out] none
655     \retval     none
656 */
usart_smartcard_autoretry_config(uint32_t usart_periph,uint32_t scrtnum)657 void usart_smartcard_autoretry_config(uint32_t usart_periph, uint32_t scrtnum)
658 {
659     USART_CTL3(usart_periph) &= ~(USART_CTL3_SCRTNUM);
660     USART_CTL3(usart_periph) |= (USART_CTL3_SCRTNUM & ((scrtnum) << CTL3_SCRTNUM_OFFSET));
661 }
662 
663 /*!
664     \brief    configure block length in Smartcard T=1 reception
665     \param[in]  usart_periph: USARTx(x=0,1,2,5)
666     \param[in]  bl: block length
667     \param[out] none
668     \retval     none
669 */
usart_block_length_config(uint32_t usart_periph,uint32_t bl)670 void usart_block_length_config(uint32_t usart_periph, uint32_t bl)
671 {
672     USART_RT(usart_periph) &= ~(USART_RT_BL);
673     USART_RT(usart_periph) |= (USART_RT_BL & ((bl) << RT_BL_OFFSET));
674 }
675 
676 /*!
677     \brief    enable IrDA mode
678     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
679     \param[out] none
680     \retval     none
681 */
usart_irda_mode_enable(uint32_t usart_periph)682 void usart_irda_mode_enable(uint32_t usart_periph)
683 {
684     USART_CTL2(usart_periph) |= USART_CTL2_IREN;
685 }
686 
687 /*!
688     \brief    disable IrDA mode
689     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
690     \param[out] none
691     \retval     none
692 */
usart_irda_mode_disable(uint32_t usart_periph)693 void usart_irda_mode_disable(uint32_t usart_periph)
694 {
695     USART_CTL2(usart_periph) &= ~(USART_CTL2_IREN);
696 }
697 
698 /*!
699     \brief    configure the peripheral clock prescaler in USART IrDA low-power mode
700     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
701     \param[in]  psc: 0-0xFF
702     \param[out] none
703     \retval     none
704 */
usart_prescaler_config(uint32_t usart_periph,uint8_t psc)705 void usart_prescaler_config(uint32_t usart_periph, uint8_t psc)
706 {
707     USART_GP(usart_periph) &= ~(USART_GP_PSC);
708     USART_GP(usart_periph) |= psc;
709 }
710 
711 /*!
712     \brief    configure IrDA low-power
713     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
714     \param[in]  irlp: IrDA low-power or normal
715                 only one parameter can be selected which is shown as below:
716       \arg        USART_IRLP_LOW: low-power
717       \arg        USART_IRLP_NORMAL: normal
718     \param[out] none
719     \retval     none
720 */
usart_irda_lowpower_config(uint32_t usart_periph,uint32_t irlp)721 void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp)
722 {
723     USART_CTL2(usart_periph) &= ~(USART_CTL2_IRLP);
724     USART_CTL2(usart_periph) |= (USART_CTL2_IRLP & irlp);
725 }
726 
727 /*!
728     \brief    configure hardware flow control RTS
729     \param[in]  usart_periph: USARTx(x=0,1,2,5)
730     \param[in]  rtsconfig: enable or disable RTS
731                 only one parameter can be selected which is shown as below:
732       \arg        USART_RTS_ENABLE:  enable RTS
733       \arg        USART_RTS_DISABLE: disable RTS
734     \param[out] none
735     \retval     none
736 */
usart_hardware_flow_rts_config(uint32_t usart_periph,uint32_t rtsconfig)737 void usart_hardware_flow_rts_config(uint32_t usart_periph, uint32_t rtsconfig)
738 {
739     uint32_t ctl = 0U;
740 
741     ctl = USART_CTL2(usart_periph);
742     ctl &= ~USART_CTL2_RTSEN;
743     ctl |= rtsconfig;
744     /* configure RTS */
745     USART_CTL2(usart_periph) = ctl;
746 }
747 
748 /*!
749     \brief    configure hardware flow control CTS
750     \param[in]  usart_periph: USARTx(x=0,1,2,5)
751     \param[in]  ctsconfig: enable or disable CTS
752                 only one parameter can be selected which is shown as below:
753       \arg        USART_CTS_ENABLE:  enable CTS
754       \arg        USART_CTS_DISABLE: disable CTS
755     \param[out] none
756     \retval     none
757 */
usart_hardware_flow_cts_config(uint32_t usart_periph,uint32_t ctsconfig)758 void usart_hardware_flow_cts_config(uint32_t usart_periph, uint32_t ctsconfig)
759 {
760     uint32_t ctl = 0U;
761 
762     ctl = USART_CTL2(usart_periph);
763     ctl &= ~USART_CTL2_CTSEN;
764     ctl |= ctsconfig;
765     /* configure CTS */
766     USART_CTL2(usart_periph) = ctl;
767 }
768 
769 /*!
770     \brief    configure break frame coherence mode
771     \param[in]  usart_periph: USARTx(x=0,1,2,5)
772     \param[in]  bcm:
773                 only one parameter can be selected which is shown as below:
774       \arg        USART_BCM_NONE: no parity error is detected
775       \arg        USART_BCM_EN:   parity error is detected
776     \param[out] none
777     \retval     none
778 */
usart_break_frame_coherence_config(uint32_t usart_periph,uint32_t bcm)779 void usart_break_frame_coherence_config(uint32_t usart_periph, uint32_t bcm)
780 {
781     USART_CHC(usart_periph) &= ~(USART_CHC_BCM);
782     USART_CHC(usart_periph) |= (USART_CHC_BCM & bcm);
783 }
784 
785 /*!
786     \brief    configure parity check coherence mode
787     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
788     \param[in]  pcm:
789                 only one parameter can be selected which is shown as below:
790       \arg        USART_PCM_NONE: not check parity
791       \arg        USART_PCM_EN:   check the parity
792     \param[out] none
793     \retval     none
794 */
usart_parity_check_coherence_config(uint32_t usart_periph,uint32_t pcm)795 void usart_parity_check_coherence_config(uint32_t usart_periph, uint32_t pcm)
796 {
797     USART_CHC(usart_periph) &= ~(USART_CHC_PCM);
798     USART_CHC(usart_periph) |= (USART_CHC_PCM & pcm);
799 }
800 
801 /*!
802     \brief    configure hardware flow control coherence mode
803     \param[in]  usart_periph: USARTx(x=0,1,2,5)
804     \param[in]  hcm:
805                 only one parameter can be selected which is shown as below:
806       \arg        USART_HCM_NONE: nRTS signal equals to the rxne status register
807       \arg        USART_HCM_EN:   nRTS signal is set when the last data bit has been sampled
808     \param[out] none
809     \retval     none
810 */
usart_hardware_flow_coherence_config(uint32_t usart_periph,uint32_t hcm)811 void usart_hardware_flow_coherence_config(uint32_t usart_periph, uint32_t hcm)
812 {
813     USART_CHC(usart_periph) &= ~(USART_CHC_HCM);
814     USART_CHC(usart_periph) |= (USART_CHC_HCM & hcm);
815 }
816 
817 /*!
818     \brief    configure USART DMA reception
819     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
820     \param[in]  dmacmd: enable or disable DMA for reception
821                 only one parameter can be selected which is shown as below:
822       \arg        USART_DENR_ENABLE:  DMA enable for reception
823       \arg        USART_DENR_DISABLE: DMA disable for reception
824     \param[out] none
825     \retval     none
826 */
usart_dma_receive_config(uint32_t usart_periph,uint32_t dmacmd)827 void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd)
828 {
829     uint32_t ctl = 0U;
830 
831     ctl = USART_CTL2(usart_periph);
832     ctl &= ~USART_CTL2_DENR;
833     ctl |= dmacmd;
834     /* configure DMA reception */
835     USART_CTL2(usart_periph) = ctl;
836 }
837 
838 /*!
839     \brief    configure USART DMA transmission
840     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
841     \param[in]  dmacmd: enable or disable DMA for transmission
842                 only one parameter can be selected which is shown as below:
843       \arg        USART_DENT_ENABLE:  DMA enable for transmission
844       \arg        USART_DENT_DISABLE: DMA disable for transmission
845     \param[out] none
846     \retval     none
847 */
usart_dma_transmit_config(uint32_t usart_periph,uint32_t dmacmd)848 void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd)
849 {
850     uint32_t ctl = 0U;
851 
852     ctl = USART_CTL2(usart_periph);
853     ctl &= ~USART_CTL2_DENT;
854     ctl |= dmacmd;
855     /* configure DMA transmission */
856     USART_CTL2(usart_periph) = ctl;
857 }
858 
859 /*!
860     \brief    get flag in STAT0/STAT1/CHC register
861     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
862     \param[in]  flag: USART flags, refer to usart_flag_enum
863                 only one parameter can be selected which is shown as below:
864       \arg        USART_FLAG_CTS: CTS change flag
865       \arg        USART_FLAG_LBD: LIN break detected flag
866       \arg        USART_FLAG_TBE: transmit data buffer empty
867       \arg        USART_FLAG_TC: transmission complete
868       \arg        USART_FLAG_RBNE: read data buffer not empty
869       \arg        USART_FLAG_IDLE: IDLE frame detected flag
870       \arg        USART_FLAG_ORERR: overrun error
871       \arg        USART_FLAG_NERR: noise error flag
872       \arg        USART_FLAG_FERR: frame error flag
873       \arg        USART_FLAG_PERR: parity error flag
874       \arg        USART_FLAG_BSY: busy flag
875       \arg        USART_FLAG_EB: end of block flag
876       \arg        USART_FLAG_RT: receiver timeout flag
877       \arg        USART_FLAG_EPERR: early parity error flag
878     \param[out] none
879     \retval     FlagStatus: SET or RESET
880 */
usart_flag_get(uint32_t usart_periph,usart_flag_enum flag)881 FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag)
882 {
883     if(RESET != (USART_REG_VAL(usart_periph, flag) & BIT(USART_BIT_POS(flag)))) {
884         return SET;
885     } else {
886         return RESET;
887     }
888 }
889 
890 /*!
891     \brief    clear flag in STAT0/STAT1/CHC register
892     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
893     \param[in]  flag: USART flags, refer to usart_flag_enum
894                 only one parameter can be selected which is shown as below:
895       \arg        USART_FLAG_CTS: CTS change flag
896       \arg        USART_FLAG_LBD: LIN break detected flag
897       \arg        USART_FLAG_TC: transmission complete
898       \arg        USART_FLAG_RBNE: read data buffer not empty
899       \arg        USART_FLAG_EB: end of block flag
900       \arg        USART_FLAG_RT: receiver timeout flag
901       \arg        USART_FLAG_EPERR: early parity error flag
902     \param[out] none
903     \retval     none
904 */
usart_flag_clear(uint32_t usart_periph,usart_flag_enum flag)905 void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag)
906 {
907     USART_REG_VAL(usart_periph, flag) &= ~BIT(USART_BIT_POS(flag));
908 }
909 
910 /*!
911     \brief    enable USART interrupt
912     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
913     \param[in]  interrupt: USART interrupts, refer to usart_interrupt_enum
914                 only one parameter can be selected which is shown as below:
915       \arg        USART_INT_PERR: parity error interrupt
916       \arg        USART_INT_TBE: transmitter buffer empty interrupt
917       \arg        USART_INT_TC: transmission complete interrupt
918       \arg        USART_INT_RBNE: read data buffer not empty interrupt and overrun error interrupt
919       \arg        USART_INT_IDLE: IDLE line detected interrupt
920       \arg        USART_INT_LBD: LIN break detected interrupt
921       \arg        USART_INT_ERR: error interrupt
922       \arg        USART_INT_CTS: CTS interrupt
923       \arg        USART_INT_RT: interrupt enable bit of receive timeout event
924       \arg        USART_INT_EB: interrupt enable bit of end of block event
925     \param[out] none
926     \retval     none
927 */
usart_interrupt_enable(uint32_t usart_periph,usart_interrupt_enum interrupt)928 void usart_interrupt_enable(uint32_t usart_periph, usart_interrupt_enum interrupt)
929 {
930     USART_REG_VAL(usart_periph, interrupt) |= BIT(USART_BIT_POS(interrupt));
931 }
932 
933 /*!
934     \brief    disable USART interrupt
935     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
936     \param[in]  interrupt: USART interrupts, refer to usart_interrupt_enum
937                 only one parameter can be selected which is shown as below:
938       \arg        USART_INT_PERR: parity error interrupt
939       \arg        USART_INT_TBE: transmitter buffer empty interrupt
940       \arg        USART_INT_TC: transmission complete interrupt
941       \arg        USART_INT_RBNE: read data buffer not empty interrupt and overrun error interrupt
942       \arg        USART_INT_IDLE: IDLE line detected interrupt
943       \arg        USART_INT_LBD: LIN break detected interrupt
944       \arg        USART_INT_ERR: error interrupt
945       \arg        USART_INT_CTS: CTS interrupt
946       \arg        USART_INT_RT: interrupt enable bit of receive timeout event
947       \arg        USART_INT_EB: interrupt enable bit of end of block event
948     \param[out] none
949     \retval     none
950 */
usart_interrupt_disable(uint32_t usart_periph,usart_interrupt_enum interrupt)951 void usart_interrupt_disable(uint32_t usart_periph, usart_interrupt_enum interrupt)
952 {
953     USART_REG_VAL(usart_periph, interrupt) &= ~BIT(USART_BIT_POS(interrupt));
954 }
955 
956 /*!
957     \brief    get USART interrupt and flag status
958     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
959     \param[in]  int_flag: USART interrupt flags, refer to usart_interrupt_flag_enum
960                 only one parameter can be selected which is shown as below:
961       \arg        USART_INT_FLAG_PERR: parity error interrupt and flag
962       \arg        USART_INT_FLAG_TBE: transmitter buffer empty interrupt and flag
963       \arg        USART_INT_FLAG_TC: transmission complete interrupt and flag
964       \arg        USART_INT_FLAG_RBNE: read data buffer not empty interrupt and flag
965       \arg        USART_INT_FLAG_RBNE_ORERR: read data buffer not empty interrupt and overrun error flag
966       \arg        USART_INT_FLAG_IDLE: IDLE line detected interrupt and flag
967       \arg        USART_INT_FLAG_LBD: LIN break detected interrupt and flag
968       \arg        USART_INT_FLAG_CTS: CTS interrupt and flag
969       \arg        USART_INT_FLAG_ERR_ORERR: error interrupt and overrun error
970       \arg        USART_INT_FLAG_ERR_NERR: error interrupt and noise error flag
971       \arg        USART_INT_FLAG_ERR_FERR: error interrupt and frame error flag
972       \arg        USART_INT_FLAG_EB: interrupt enable bit of end of block event and flag
973       \arg        USART_INT_FLAG_RT: interrupt enable bit of receive timeout event and flag
974     \param[out] none
975     \retval     FlagStatus: SET or RESET
976 */
usart_interrupt_flag_get(uint32_t usart_periph,usart_interrupt_flag_enum int_flag)977 FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, usart_interrupt_flag_enum int_flag)
978 {
979     uint32_t intenable = 0U, flagstatus = 0U;
980     /* get the interrupt enable bit status */
981     intenable = (USART_REG_VAL(usart_periph, int_flag) & BIT(USART_BIT_POS(int_flag)));
982     /* get the corresponding flag bit status */
983     flagstatus = (USART_REG_VAL2(usart_periph, int_flag) & BIT(USART_BIT_POS2(int_flag)));
984 
985     if((0U != flagstatus) && (0U != intenable)) {
986         return SET;
987     } else {
988         return RESET;
989     }
990 }
991 
992 /*!
993     \brief    clear USART interrupt flag in STAT0/STAT1 register
994     \param[in]  usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
995     \param[in]  int_flag: USART interrupt flags, refer to usart_interrupt_flag_enum
996                 only one parameter can be selected which is shown as below:
997       \arg        USART_INT_FLAG_CTS: CTS change flag
998       \arg        USART_INT_FLAG_LBD: LIN break detected flag
999       \arg        USART_INT_FLAG_TC: transmission complete
1000       \arg        USART_INT_FLAG_RBNE: read data buffer not empty
1001       \arg        USART_INT_FLAG_EB: end of block flag
1002       \arg        USART_INT_FLAG_RT: receiver timeout flag
1003     \param[out] none
1004     \retval     none
1005 */
usart_interrupt_flag_clear(uint32_t usart_periph,usart_interrupt_flag_enum int_flag)1006 void usart_interrupt_flag_clear(uint32_t usart_periph, usart_interrupt_flag_enum int_flag)
1007 {
1008     USART_REG_VAL2(usart_periph, int_flag) &= ~BIT(USART_BIT_POS2(int_flag));
1009 }
1010