1 /*!
2     \file    gd32vf103_usart.c
3     \brief   USART driver
4 
5     \version 2019-06-05, V1.0.0, firmware for GD32VF103
6     \version 2019-09-18, V1.0.1, firmware for GD32VF103
7     \version 2020-08-04, V1.1.0, firmware for GD32VF103
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 "gd32vf103_usart.h"
38 
39 /*!
40     \brief      reset USART/UART
41     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
42     \param[out] none
43     \retval     none
44 */
usart_deinit(uint32_t usart_periph)45 void usart_deinit(uint32_t usart_periph)
46 {
47     switch(usart_periph){
48     case USART0:
49         /* reset USART0 */
50         rcu_periph_reset_enable(RCU_USART0RST);
51         rcu_periph_reset_disable(RCU_USART0RST);
52         break;
53     case USART1:
54         /* reset USART1 */
55         rcu_periph_reset_enable(RCU_USART1RST);
56         rcu_periph_reset_disable(RCU_USART1RST);
57         break;
58     case USART2:
59         /* reset USART2 */
60         rcu_periph_reset_enable(RCU_USART2RST);
61         rcu_periph_reset_disable(RCU_USART2RST);
62         break;
63     case UART3:
64         /* reset UART3 */
65         rcu_periph_reset_enable(RCU_UART3RST);
66         rcu_periph_reset_disable(RCU_UART3RST);
67         break;
68     case UART4:
69         /* reset UART4 */
70         rcu_periph_reset_enable(RCU_UART4RST);
71         rcu_periph_reset_disable(RCU_UART4RST);
72         break;
73     default:
74         break;
75     }
76 }
77 
78 /*!
79     \brief      configure USART baud rate value
80     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
81     \param[in]  baudval: baud rate value
82     \param[out] none
83     \retval     none
84 */
usart_baudrate_set(uint32_t usart_periph,uint32_t baudval)85 void usart_baudrate_set(uint32_t usart_periph, uint32_t baudval)
86 {
87     uint32_t uclk=0U, intdiv=0U, fradiv=0U, udiv=0U;
88     switch(usart_periph){
89          /* get clock frequency */
90     case USART0:
91          /* get USART0 clock */
92          uclk=rcu_clock_freq_get(CK_APB2);
93          break;
94     case USART1:
95          /* get USART1 clock */
96          uclk=rcu_clock_freq_get(CK_APB1);
97          break;
98     case USART2:
99          /* get USART2 clock */
100          uclk=rcu_clock_freq_get(CK_APB1);
101          break;
102     case UART3:
103          /* get UART3 clock */
104          uclk=rcu_clock_freq_get(CK_APB1);
105          break;
106     case UART4:
107          /* get UART4 clock */
108          uclk=rcu_clock_freq_get(CK_APB1);
109          break;
110     default:
111          break;
112     }
113     /* oversampling by 16, configure the value of USART_BAUD */
114     udiv = (uclk+baudval/2U)/baudval;
115     intdiv = udiv & (0x0000fff0U);
116     fradiv = udiv & (0x0000000fU);
117     USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv));
118 }
119 
120 /*!
121     \brief     configure USART parity
122     \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
123     \param[in] paritycfg: configure USART parity
124                only one parameter can be selected which is shown as below:
125       \arg       USART_PM_NONE: no parity
126       \arg       USART_PM_ODD:  odd parity
127       \arg       USART_PM_EVEN: even parity
128     \param[out] none
129     \retval     none
130 */
usart_parity_config(uint32_t usart_periph,uint32_t paritycfg)131 void usart_parity_config(uint32_t usart_periph, uint32_t paritycfg)
132 {
133     /* clear USART_CTL0 PM,PCEN bits */
134     USART_CTL0(usart_periph) &= ~(USART_CTL0_PM | USART_CTL0_PCEN);
135     /* configure USART parity mode */
136     USART_CTL0(usart_periph) |= paritycfg ;
137 }
138 
139 /*!
140     \brief     configure USART word length
141     \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
142     \param[in] wlen: USART word length configure
143                only one parameter can be selected which is shown as below:
144       \arg       USART_WL_8BIT: 8 bits
145       \arg       USART_WL_9BIT: 9 bits
146     \param[out] none
147     \retval     none
148 */
usart_word_length_set(uint32_t usart_periph,uint32_t wlen)149 void usart_word_length_set(uint32_t usart_periph, uint32_t wlen)
150 {
151     /* clear USART_CTL0 WL bit */
152     USART_CTL0(usart_periph) &= ~USART_CTL0_WL;
153     /* configure USART word length */
154     USART_CTL0(usart_periph) |= wlen;
155 }
156 
157 /*!
158     \brief     configure USART stop bit length
159     \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
160     \param[in] stblen: USART stop bit configure
161                only one parameter can be selected which is shown as below:
162       \arg       USART_STB_1BIT:   1 bit
163       \arg       USART_STB_0_5BIT: 0.5 bit, not available for UARTx(x=3,4)
164       \arg       USART_STB_2BIT:   2 bits
165       \arg       USART_STB_1_5BIT: 1.5 bits, not available for UARTx(x=3,4)
166     \param[out] none
167     \retval     none
168 */
usart_stop_bit_set(uint32_t usart_periph,uint32_t stblen)169 void usart_stop_bit_set(uint32_t usart_periph, uint32_t stblen)
170 {
171     /* clear USART_CTL1 STB bits */
172     USART_CTL1(usart_periph) &= ~USART_CTL1_STB;
173     /* configure USART stop bits */
174     USART_CTL1(usart_periph) |= stblen;
175 }
176 
177 /*!
178     \brief      enable USART
179     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
180     \param[out] none
181     \retval     none
182 */
usart_enable(uint32_t usart_periph)183 void usart_enable(uint32_t usart_periph)
184 {
185     USART_CTL0(usart_periph) |= USART_CTL0_UEN;
186 }
187 
188 /*!
189     \brief     disable USART
190     \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
191     \param[out] none
192     \retval     none
193 */
usart_disable(uint32_t usart_periph)194 void usart_disable(uint32_t usart_periph)
195 {
196     USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
197 }
198 
199 /*!
200     \brief      configure USART transmitter
201     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
202     \param[in]  txconfig: enable or disable USART transmitter
203                 only one parameter can be selected which is shown as below:
204       \arg        USART_TRANSMIT_ENABLE: enable USART transmission
205       \arg        USART_TRANSMIT_DISABLE: disable USART transmission
206     \param[out] none
207     \retval     none
208 */
usart_transmit_config(uint32_t usart_periph,uint32_t txconfig)209 void usart_transmit_config(uint32_t usart_periph, uint32_t txconfig)
210 {
211     uint32_t ctl = 0U;
212 
213     ctl = USART_CTL0(usart_periph);
214     ctl &= ~USART_CTL0_TEN;
215     ctl |= txconfig;
216     /* configure transfer mode */
217     USART_CTL0(usart_periph) = ctl;
218 }
219 
220 /*!
221     \brief      configure USART receiver
222     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
223     \param[in]  rxconfig: enable or disable USART receiver
224                 only one parameter can be selected which is shown as below:
225       \arg        USART_RECEIVE_ENABLE: enable USART reception
226       \arg        USART_RECEIVE_DISABLE: disable USART reception
227     \param[out] none
228     \retval     none
229 */
usart_receive_config(uint32_t usart_periph,uint32_t rxconfig)230 void usart_receive_config(uint32_t usart_periph, uint32_t rxconfig)
231 {
232     uint32_t ctl = 0U;
233 
234     ctl = USART_CTL0(usart_periph);
235     ctl &= ~USART_CTL0_REN;
236     ctl |= rxconfig;
237     /* configure receiver mode */
238     USART_CTL0(usart_periph) = ctl;
239 }
240 
241 /*!
242     \brief      USART transmit data function
243     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
244     \param[in]  data: data of transmission
245     \param[out] none
246     \retval     none
247 */
usart_data_transmit(uint32_t usart_periph,uint32_t data)248 void usart_data_transmit(uint32_t usart_periph, uint32_t data)
249 {
250     USART_DATA(usart_periph) = USART_DATA_DATA & data;
251 }
252 
253 /*!
254     \brief      USART receive data function
255     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
256     \param[out] none
257     \retval     data of received
258 */
usart_data_receive(uint32_t usart_periph)259 uint16_t usart_data_receive(uint32_t usart_periph)
260 {
261     return (uint16_t)(GET_BITS(USART_DATA(usart_periph), 0U, 8U));
262 }
263 
264 /*!
265     \brief      configure the address of the USART in wake up by address match mode
266     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
267     \param[in]  addr: address of USART/UART
268     \param[out] none
269     \retval     none
270 */
usart_address_config(uint32_t usart_periph,uint8_t addr)271 void usart_address_config(uint32_t usart_periph, uint8_t addr)
272 {
273     USART_CTL1(usart_periph) &= ~(USART_CTL1_ADDR);
274     USART_CTL1(usart_periph) |= (USART_CTL1_ADDR & addr);
275 }
276 
277 /*!
278     \brief      receiver in mute mode
279     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
280     \param[out] none
281     \retval     none
282 */
usart_mute_mode_enable(uint32_t usart_periph)283 void usart_mute_mode_enable(uint32_t usart_periph)
284 {
285     USART_CTL0(usart_periph) |= USART_CTL0_RWU;
286 }
287 
288 /*!
289     \brief      receiver in active mode
290     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
291     \param[out] none
292     \retval     none
293 */
usart_mute_mode_disable(uint32_t usart_periph)294 void usart_mute_mode_disable(uint32_t usart_periph)
295 {
296     USART_CTL0(usart_periph) &= ~(USART_CTL0_RWU);
297 }
298 
299 /*!
300     \brief      configure wakeup method in mute mode
301     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
302     \param[in]  wmethod: two methods be used to enter or exit the mute mode
303                 only one parameter can be selected which is shown as below:
304       \arg        USART_WM_IDLE: idle line
305       \arg        USART_WM_ADDR: address mask
306     \param[out] none
307     \retval     none
308 */
usart_mute_mode_wakeup_config(uint32_t usart_periph,uint32_t wmethod)309 void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmethod)
310 {
311     USART_CTL0(usart_periph) &= ~(USART_CTL0_WM);
312     USART_CTL0(usart_periph) |= wmethod;
313 }
314 
315 /*!
316     \brief      enable LIN mode
317     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
318     \param[out] none
319     \retval     none
320 */
usart_lin_mode_enable(uint32_t usart_periph)321 void usart_lin_mode_enable(uint32_t usart_periph)
322 {
323     USART_CTL1(usart_periph) |= USART_CTL1_LMEN;
324 }
325 
326 /*!
327     \brief      disable LIN mode
328     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
329     \param[out] none
330     \retval     none
331 */
usart_lin_mode_disable(uint32_t usart_periph)332 void usart_lin_mode_disable(uint32_t usart_periph)
333 {
334     USART_CTL1(usart_periph) &= ~(USART_CTL1_LMEN);
335 }
336 
337 /*!
338     \brief      configure lin break frame length
339     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
340     \param[in]  lblen: lin break frame length
341                 only one parameter can be selected which is shown as below:
342       \arg        USART_LBLEN_10B: 10 bits
343       \arg        USART_LBLEN_11B: 11 bits
344     \param[out] none
345     \retval     none
346 */
usart_lin_break_detection_length_config(uint32_t usart_periph,uint32_t lblen)347 void usart_lin_break_detection_length_config(uint32_t usart_periph, uint32_t lblen)
348 {
349     USART_CTL1(usart_periph) &= ~(USART_CTL1_LBLEN);
350     USART_CTL1(usart_periph) |= (USART_CTL1_LBLEN & lblen);
351 }
352 
353 /*!
354     \brief      send break frame
355     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
356     \param[out] none
357     \retval     none
358 */
usart_send_break(uint32_t usart_periph)359 void usart_send_break(uint32_t usart_periph)
360 {
361     USART_CTL0(usart_periph) |= USART_CTL0_SBKCMD;
362 }
363 
364 /*!
365     \brief      enable half duplex mode
366     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
367     \param[out] none
368     \retval     none
369 */
usart_halfduplex_enable(uint32_t usart_periph)370 void usart_halfduplex_enable(uint32_t usart_periph)
371 {
372     USART_CTL2(usart_periph) |= USART_CTL2_HDEN;
373 }
374 
375 /*!
376     \brief      disable half duplex mode
377     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
378     \param[out] none
379     \retval     none
380 */
usart_halfduplex_disable(uint32_t usart_periph)381 void usart_halfduplex_disable(uint32_t usart_periph)
382 {
383     USART_CTL2(usart_periph) &= ~(USART_CTL2_HDEN);
384 }
385 
386 /*!
387     \brief      enable CK pin in synchronous mode
388     \param[in]  usart_periph: USARTx(x=0,1,2)
389     \param[out] none
390     \retval     none
391 */
usart_synchronous_clock_enable(uint32_t usart_periph)392 void usart_synchronous_clock_enable(uint32_t usart_periph)
393 {
394     USART_CTL1(usart_periph) |= USART_CTL1_CKEN;
395 }
396 
397 /*!
398     \brief      disable CK pin in synchronous mode
399     \param[in]  usart_periph: USARTx(x=0,1,2)
400     \param[out] none
401     \retval     none
402 */
usart_synchronous_clock_disable(uint32_t usart_periph)403 void usart_synchronous_clock_disable(uint32_t usart_periph)
404 {
405     USART_CTL1(usart_periph) &= ~(USART_CTL1_CKEN);
406 }
407 
408 /*!
409     \brief      configure USART synchronous mode parameters
410     \param[in]  usart_periph: USARTx(x=0,1,2)
411     \param[in]  clen: CK length
412                 only one parameter can be selected which is shown as below:
413       \arg        USART_CLEN_NONE: there are 7 CK pulses for an 8 bit frame and 8 CK pulses for a 9 bit frame
414       \arg        USART_CLEN_EN:   there are 8 CK pulses for an 8 bit frame and 9 CK pulses for a 9 bit frame
415     \param[in]  cph: clock phase
416                 only one parameter can be selected which is shown as below:
417       \arg        USART_CPH_1CK: first clock transition is the first data capture edge
418       \arg        USART_CPH_2CK: second clock transition is the first data capture edge
419     \param[in]  cpl: clock polarity
420                 only one parameter can be selected which is shown as below:
421       \arg        USART_CPL_LOW:  steady low value on CK pin
422       \arg        USART_CPL_HIGH: steady high value on CK pin
423     \param[out] none
424     \retval     none
425 */
usart_synchronous_clock_config(uint32_t usart_periph,uint32_t clen,uint32_t cph,uint32_t cpl)426 void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32_t cph, uint32_t cpl)
427 {
428     uint32_t ctl = 0U;
429 
430     /* read USART_CTL1 register */
431     ctl = USART_CTL1(usart_periph);
432     ctl &= ~(USART_CTL1_CLEN | USART_CTL1_CPH | USART_CTL1_CPL);
433     /* set CK length, CK phase, CK polarity */
434     ctl |= (USART_CTL1_CLEN & clen) | (USART_CTL1_CPH & cph) | (USART_CTL1_CPL & cpl);
435 
436     USART_CTL1(usart_periph) = ctl;
437 }
438 
439 /*!
440     \brief      configure guard time value in smartcard mode
441     \param[in]  usart_periph: USARTx(x=0,1,2)
442     \param[in]  gaut: guard time value
443     \param[out] none
444     \retval     none
445 */
usart_guard_time_config(uint32_t usart_periph,uint32_t gaut)446 void usart_guard_time_config(uint32_t usart_periph,uint32_t gaut)
447 {
448     USART_GP(usart_periph) &= ~(USART_GP_GUAT);
449     USART_GP(usart_periph) |= (USART_GP_GUAT & ((gaut)<<8));
450 }
451 
452 /*!
453     \brief      enable smartcard mode
454     \param[in]  usart_periph: USARTx(x=0,1,2)
455     \param[out] none
456     \retval     none
457 */
usart_smartcard_mode_enable(uint32_t usart_periph)458 void usart_smartcard_mode_enable(uint32_t usart_periph)
459 {
460     USART_CTL2(usart_periph) |= USART_CTL2_SCEN;
461 }
462 
463 /*!
464     \brief      disable smartcard mode
465     \param[in]  usart_periph: USARTx(x=0,1,2)
466     \param[out] none
467     \retval     none
468 */
usart_smartcard_mode_disable(uint32_t usart_periph)469 void usart_smartcard_mode_disable(uint32_t usart_periph)
470 {
471     USART_CTL2(usart_periph) &= ~(USART_CTL2_SCEN);
472 }
473 
474 /*!
475     \brief      enable NACK in smartcard mode
476     \param[in]  usart_periph: USARTx(x=0,1,2)
477     \param[out] none
478     \retval     none
479 */
usart_smartcard_mode_nack_enable(uint32_t usart_periph)480 void usart_smartcard_mode_nack_enable(uint32_t usart_periph)
481 {
482     USART_CTL2(usart_periph) |= USART_CTL2_NKEN;
483 }
484 
485 /*!
486     \brief      disable NACK in smartcard mode
487     \param[in]  usart_periph: USARTx(x=0,1,2)
488     \param[out] none
489     \retval     none
490 */
usart_smartcard_mode_nack_disable(uint32_t usart_periph)491 void usart_smartcard_mode_nack_disable(uint32_t usart_periph)
492 {
493     USART_CTL2(usart_periph) &= ~(USART_CTL2_NKEN);
494 }
495 
496 /*!
497     \brief      enable IrDA mode
498     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
499     \param[out] none
500     \retval     none
501 */
usart_irda_mode_enable(uint32_t usart_periph)502 void usart_irda_mode_enable(uint32_t usart_periph)
503 {
504     USART_CTL2(usart_periph) |= USART_CTL2_IREN;
505 }
506 
507 /*!
508     \brief      disable IrDA mode
509     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
510     \param[out] none
511     \retval     none
512 */
usart_irda_mode_disable(uint32_t usart_periph)513 void usart_irda_mode_disable(uint32_t usart_periph)
514 {
515     USART_CTL2(usart_periph) &= ~(USART_CTL2_IREN);
516 }
517 
518 /*!
519     \brief      configure the peripheral clock prescaler in USART IrDA low-power mode
520     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
521     \param[in]  psc: 0x00-0xFF
522     \param[out] none
523     \retval     none
524 */
usart_prescaler_config(uint32_t usart_periph,uint8_t psc)525 void usart_prescaler_config(uint32_t usart_periph, uint8_t psc)
526 {
527     USART_GP(usart_periph) &= ~(USART_GP_PSC);
528     USART_GP(usart_periph) |= psc;
529 }
530 
531 /*!
532     \brief      configure IrDA low-power
533     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
534     \param[in]  irlp: IrDA low-power or normal
535                 only one parameter can be selected which is shown as below:
536       \arg        USART_IRLP_LOW: low-power
537       \arg        USART_IRLP_NORMAL: normal
538     \param[out] none
539     \retval     none
540 */
usart_irda_lowpower_config(uint32_t usart_periph,uint32_t irlp)541 void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp)
542 {
543     USART_CTL2(usart_periph) &= ~(USART_CTL2_IRLP);
544     USART_CTL2(usart_periph) |= (USART_CTL2_IRLP & irlp);
545 }
546 
547 /*!
548     \brief      configure hardware flow control RTS
549     \param[in]  usart_periph: USARTx(x=0,1,2)
550     \param[in]  rtsconfig: enable or disable RTS
551                 only one parameter can be selected which is shown as below:
552       \arg        USART_RTS_ENABLE:  enable RTS
553       \arg        USART_RTS_DISABLE: disable RTS
554     \param[out] none
555     \retval     none
556 */
usart_hardware_flow_rts_config(uint32_t usart_periph,uint32_t rtsconfig)557 void usart_hardware_flow_rts_config(uint32_t usart_periph, uint32_t rtsconfig)
558 {
559     uint32_t ctl = 0U;
560 
561     ctl = USART_CTL2(usart_periph);
562     ctl &= ~USART_CTL2_RTSEN;
563     ctl |= rtsconfig;
564     /* configure RTS */
565     USART_CTL2(usart_periph) = ctl;
566 }
567 
568 /*!
569     \brief      configure hardware flow control CTS
570     \param[in]  usart_periph: USARTx(x=0,1,2)
571     \param[in]  ctsconfig: enable or disable CTS
572                 only one parameter can be selected which is shown as below:
573       \arg        USART_CTS_ENABLE:  enable CTS
574       \arg        USART_CTS_DISABLE: disable CTS
575     \param[out] none
576     \retval     none
577 */
usart_hardware_flow_cts_config(uint32_t usart_periph,uint32_t ctsconfig)578 void usart_hardware_flow_cts_config(uint32_t usart_periph, uint32_t ctsconfig)
579 {
580     uint32_t ctl = 0U;
581 
582     ctl = USART_CTL2(usart_periph);
583     ctl &= ~USART_CTL2_CTSEN;
584     ctl |= ctsconfig;
585     /* configure CTS */
586     USART_CTL2(usart_periph) = ctl;
587 }
588 
589 /*!
590     \brief      configure USART DMA reception
591     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3)
592     \param[in]  dmacmd: enable or disable DMA for reception
593                 only one parameter can be selected which is shown as below:
594       \arg        USART_DENR_ENABLE:  DMA enable for reception
595       \arg        USART_DENR_DISABLE: DMA disable for reception
596     \param[out] none
597     \retval     none
598 */
usart_dma_receive_config(uint32_t usart_periph,uint32_t dmacmd)599 void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd)
600 {
601     uint32_t ctl = 0U;
602 
603     ctl = USART_CTL2(usart_periph);
604     ctl &= ~USART_CTL2_DENR;
605     ctl |= dmacmd;
606     /* configure DMA reception */
607     USART_CTL2(usart_periph) = ctl;
608 }
609 
610 /*!
611     \brief      configure USART DMA transmission
612     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3)
613     \param[in]  dmacmd: enable or disable DMA for transmission
614                 only one parameter can be selected which is shown as below:
615       \arg        USART_DENT_ENABLE:  DMA enable for transmission
616       \arg        USART_DENT_DISABLE: DMA disable for transmission
617     \param[out] none
618     \retval     none
619 */
usart_dma_transmit_config(uint32_t usart_periph,uint32_t dmacmd)620 void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd)
621 {
622     uint32_t ctl = 0U;
623 
624     ctl = USART_CTL2(usart_periph);
625     ctl &= ~USART_CTL2_DENT;
626     ctl |= dmacmd;
627     /* configure DMA transmission */
628     USART_CTL2(usart_periph) = ctl;
629 }
630 
631 /*!
632     \brief      get flag in STAT register
633     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
634     \param[in]  flag: USART flags, refer to usart_flag_enum
635                 only one parameter can be selected which is shown as below:
636       \arg        USART_FLAG_CTS: CTS change flag
637       \arg        USART_FLAG_LBD: LIN break detected flag
638       \arg        USART_FLAG_TBE: transmit data buffer empty
639       \arg        USART_FLAG_TC: transmission complete
640       \arg        USART_FLAG_RBNE: read data buffer not empty
641       \arg        USART_FLAG_IDLE: IDLE frame detected flag
642       \arg        USART_FLAG_ORERR: overrun error
643       \arg        USART_FLAG_NERR: noise error flag
644       \arg        USART_FLAG_FERR: frame error flag
645       \arg        USART_FLAG_PERR: parity error flag
646     \param[out] none
647     \retval     FlagStatus: SET or RESET
648 */
usart_flag_get(uint32_t usart_periph,usart_flag_enum flag)649 FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag)
650 {
651     if(RESET != (USART_REG_VAL(usart_periph, flag) & BIT(USART_BIT_POS(flag)))){
652         return SET;
653     }else{
654         return RESET;
655     }
656 }
657 
658 /*!
659     \brief      clear flag in STAT register
660     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
661     \param[in]  flag: USART flags, refer to usart_flag_enum
662                 only one parameter can be selected which is shown as below:
663       \arg        USART_FLAG_CTS: CTS change flag
664       \arg        USART_FLAG_LBD: LIN break detected flag
665       \arg        USART_FLAG_TC: transmission complete
666       \arg        USART_FLAG_RBNE: read data buffer not empty
667     \param[out] none
668     \retval     none
669 */
usart_flag_clear(uint32_t usart_periph,usart_flag_enum flag)670 void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag)
671 {
672     USART_REG_VAL(usart_periph, flag) &= ~BIT(USART_BIT_POS(flag));
673 }
674 
675 /*!
676     \brief      enable USART interrupt
677      \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
678     \param[in]  interrupt
679                 only one parameter can be selected which is shown as below:
680       \arg        USART_INT_PERR: parity error interrupt
681       \arg        USART_INT_TBE: transmitter buffer empty interrupt
682       \arg        USART_INT_TC: transmission complete interrupt
683       \arg        USART_INT_RBNE: read data buffer not empty interrupt and overrun error interrupt
684       \arg        USART_INT_IDLE: IDLE line detected interrupt
685       \arg        USART_INT_LBD: LIN break detected interrupt
686       \arg        USART_INT_ERR: error interrupt
687       \arg        USART_INT_CTS: CTS interrupt
688     \param[out] none
689     \retval     none
690 */
usart_interrupt_enable(uint32_t usart_periph,uint32_t interrupt)691 void usart_interrupt_enable(uint32_t usart_periph, uint32_t interrupt)
692 {
693     USART_REG_VAL(usart_periph, interrupt) |= BIT(USART_BIT_POS(interrupt));
694 }
695 
696 /*!
697     \brief      disable USART interrupt
698      \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
699     \param[in]  interrupt
700                 only one parameter can be selected which is shown as below:
701       \arg        USART_INT_PERR: parity error interrupt
702       \arg        USART_INT_TBE: transmitter buffer empty interrupt
703       \arg        USART_INT_TC: transmission complete interrupt
704       \arg        USART_INT_RBNE: read data buffer not empty interrupt and overrun error interrupt
705       \arg        USART_INT_IDLE: IDLE line detected interrupt
706       \arg        USART_INT_LBD: LIN break detected interrupt
707       \arg        USART_INT_ERR: error interrupt
708       \arg        USART_INT_CTS: CTS interrupt
709     \param[out] none
710     \retval     none
711 */
usart_interrupt_disable(uint32_t usart_periph,uint32_t interrupt)712 void usart_interrupt_disable(uint32_t usart_periph, uint32_t interrupt)
713 {
714     USART_REG_VAL(usart_periph, interrupt) &= ~BIT(USART_BIT_POS(interrupt));
715 }
716 
717 /*!
718     \brief      get USART interrupt and flag status
719      \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
720     \param[in]  int_flag
721                 only one parameter can be selected which is shown as below:
722       \arg        USART_INT_FLAG_PERR: parity error interrupt and flag
723       \arg        USART_INT_FLAG_TBE: transmitter buffer empty interrupt and flag
724       \arg        USART_INT_FLAG_TC: transmission complete interrupt and flag
725       \arg        USART_INT_FLAG_RBNE: read data buffer not empty interrupt and flag
726       \arg        USART_INT_FLAG_RBNE_ORERR: read data buffer not empty interrupt and overrun error flag
727       \arg        USART_INT_FLAG_IDLE: IDLE line detected interrupt and flag
728       \arg        USART_INT_FLAG_LBD: LIN break detected interrupt and flag
729       \arg        USART_INT_FLAG_CTS: CTS interrupt and flag
730       \arg        USART_INT_FLAG_ERR_ORERR: error interrupt and overrun error
731       \arg        USART_INT_FLAG_ERR_NERR: error interrupt and noise error flag
732       \arg        USART_INT_FLAG_ERR_FERR: error interrupt and frame error flag
733     \param[out] none
734     \retval     FlagStatus: SET or RESET
735 */
usart_interrupt_flag_get(uint32_t usart_periph,uint32_t int_flag)736 FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, uint32_t int_flag)
737 {
738     uint32_t intenable = 0U, flagstatus = 0U;
739     /* get the interrupt enable bit status */
740     intenable = (USART_REG_VAL(usart_periph, int_flag) & BIT(USART_BIT_POS(int_flag)));
741     /* get the corresponding flag bit status */
742     flagstatus = (USART_REG_VAL2(usart_periph, int_flag) & BIT(USART_BIT_POS2(int_flag)));
743 
744     if(flagstatus && intenable){
745         return SET;
746     }else{
747         return RESET;
748     }
749 }
750 
751 /*!
752     \brief      clear USART interrupt flag in STAT register
753     \param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
754     \param[in]  int_flag: USART interrupt flag
755                 only one parameter can be selected which is shown as below:
756       \arg        USART_INT_FLAG_CTS: CTS change flag
757       \arg        USART_INT_FLAG_LBD: LIN break detected flag
758       \arg        USART_INT_FLAG_TC: transmission complete
759       \arg        USART_INT_FLAG_RBNE: read data buffer not empty
760     \param[out] none
761     \retval     none
762 */
usart_interrupt_flag_clear(uint32_t usart_periph,uint32_t int_flag)763 void usart_interrupt_flag_clear(uint32_t usart_periph, uint32_t int_flag)
764 {
765     USART_REG_VAL2(usart_periph, int_flag) &= ~BIT(USART_BIT_POS2(int_flag));
766 }
767