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