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