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