1 /******************************************************************************
2 * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3 * All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************/
18 #include "uart.h"
19
20 /**********************************************************************************************************************
21 * local constants *
22 *********************************************************************************************************************/
23
24 /**********************************************************************************************************************
25 * local macro *
26 *********************************************************************************************************************/
27
28 /**********************************************************************************************************************
29 * local data type *
30 *********************************************************************************************************************/
31
32 /**********************************************************************************************************************
33 * global variable *
34 *********************************************************************************************************************/
35 dma_config_t uart_tx_dma_config[2] = {{
36 .dst_req_sel = DMA_REQ_UART0_TX, // tx req
37 .src_req_sel = 0,
38 .dst_addr_ctrl = DMA_ADDR_FIX,
39 .src_addr_ctrl = DMA_ADDR_INCREMENT, // increment
40 .dstmode = DMA_HANDSHAKE_MODE, // handshake
41 .srcmode = DMA_NORMAL_MODE,
42 .dstwidth = DMA_CTR_WORD_WIDTH, // must be word
43 .srcwidth = DMA_CTR_WORD_WIDTH, // must be word
44 .src_burst_size = 0, // must be 0
45 .read_num_en = 0,
46 .priority = 0,
47 .write_num_en = 0,
48 .auto_en = 0, // must be 0
49 },
50 {
51 .dst_req_sel = DMA_REQ_UART1_TX, // tx req
52 .src_req_sel = 0,
53 .dst_addr_ctrl = DMA_ADDR_FIX,
54 .src_addr_ctrl = DMA_ADDR_INCREMENT, // increment
55 .dstmode = DMA_HANDSHAKE_MODE, // handshake
56 .srcmode = DMA_NORMAL_MODE,
57 .dstwidth = DMA_CTR_WORD_WIDTH, // must be word
58 .srcwidth = DMA_CTR_WORD_WIDTH, // must be word
59 .src_burst_size = 0, // must be 0
60 .read_num_en = 0,
61 .priority = 0,
62 .write_num_en = 0,
63 .auto_en = 0, // must be 0
64 }};
65 dma_config_t uart_rx_dma_config[2] = {{
66 .dst_req_sel = 0, // tx req
67 .src_req_sel = DMA_REQ_UART0_RX,
68 .dst_addr_ctrl = DMA_ADDR_INCREMENT,
69 .src_addr_ctrl = DMA_ADDR_FIX,
70 .dstmode = DMA_NORMAL_MODE,
71 .srcmode = DMA_HANDSHAKE_MODE,
72 .dstwidth = DMA_CTR_WORD_WIDTH, // must be word
73 .srcwidth = DMA_CTR_WORD_WIDTH, // must be word
74 .src_burst_size = 0,
75 .read_num_en = 0,
76 .priority = 0,
77 .write_num_en = 0,
78 .auto_en = 0, // must be 0
79 },
80 {
81 .dst_req_sel = 0, // tx req
82 .src_req_sel = DMA_REQ_UART1_RX,
83 .dst_addr_ctrl = DMA_ADDR_INCREMENT,
84 .src_addr_ctrl = DMA_ADDR_FIX,
85 .dstmode = DMA_NORMAL_MODE,
86 .srcmode = DMA_HANDSHAKE_MODE,
87 .dstwidth = DMA_CTR_WORD_WIDTH, // must be word
88 .srcwidth = DMA_CTR_WORD_WIDTH, // must be word
89 .src_burst_size = 0,
90 .read_num_en = 0,
91 .priority = 0,
92 .write_num_en = 0,
93 .auto_en = 0, // must be 0
94 }};
95 /**********************************************************************************************************************
96 * local variable *
97 *********************************************************************************************************************/
98 static unsigned char uart_dma_tx_chn[2];
99 static unsigned char uart_dma_rx_chn[2];
100 /**********************************************************************************************************************
101 * local function prototype *
102 *********************************************************************************************************************/
103 /**
104 * @brief This function is used to look for the prime.if the prime is finded,it will return 1, or return 0.
105 * @param[in] n - the calue to judge.
106 * @return 0 or 1
107 */
108 static unsigned char uart_is_prime(unsigned int n);
109
110 /**
111 * @brief This function serves to set pin for UART fuction.
112 * @param tx_pin - To set TX pin.
113 * @param rx_pin - To set RX pin.
114 * @return none
115 */
116 static void uart_set_fuc_pin(uart_tx_pin_e tx_pin, uart_rx_pin_e rx_pin);
117
118 /**********************************************************************************************************************
119 * global function implementation *
120 *********************************************************************************************************************/
121
122 /**
123 * @brief This function initializes the UART module.
124 * @param[in] uart_num - UART0 or UART1.
125 * @param[in] div - uart clock divider.
126 * @param[in] bwpc - bitwidth, should be set to larger than 2.
127 * @param[in] parity - selected parity type for UART interface.
128 * @param[in] stop_bit - selected length of stop bit for UART interface.
129 * @return none
130 * @note sys_clk baudrate g_uart_div g_bwpc
131 *
132 * 16Mhz 9600 118 13
133 * 19200 118 6
134 * 115200 9 13
135 *
136 * 24Mhz 9600 249 9
137 * 19200 124 9
138 * 115200 12 15
139 *
140 * 32Mhz 9600 235 13
141 * 19200 235 6
142 * 115200 17 13
143 *
144 * 48Mhz 9600 499 9
145 * 19200 249 9
146 * 115200 25 15
147 */
uart_init(uart_num_e uart_num,unsigned short div,unsigned char bwpc,uart_parity_e parity,uart_stop_bit_e stop_bit)148 void uart_init(uart_num_e uart_num, unsigned short div, unsigned char bwpc, uart_parity_e parity,
149 uart_stop_bit_e stop_bit)
150 {
151 reg_uart_ctrl0(uart_num) &= ~(FLD_UART_BPWC_O);
152 reg_uart_ctrl0(uart_num) |= bwpc; // set bwpc
153 reg_uart_clk_div(uart_num) = (div | FLD_UART_CLK_DIV_EN); // set div_clock
154
155 // parity config
156 if (parity) {
157 reg_uart_ctrl1(uart_num) |= FLD_UART_PARITY_ENABLE; // enable parity function
158 if (UART_PARITY_EVEN == parity) {
159 reg_uart_ctrl1(uart_num) &= (~FLD_UART_PARITY_POLARITY); // enable even parity
160 } else if (UART_PARITY_ODD == parity) {
161 reg_uart_ctrl1(uart_num) |= FLD_UART_PARITY_POLARITY; // enable odd parity
162 }
163 } else {
164 reg_uart_ctrl1(uart_num) &= (~FLD_UART_PARITY_ENABLE); // disable parity function
165 }
166
167 // stop bit config
168 reg_uart_ctrl1(uart_num) &= (~FLD_UART_STOP_SEL);
169 reg_uart_ctrl1(uart_num) |= stop_bit;
170 }
171
172 /***********************************************************
173 * @brief This function serves to calculate the best bwpc(bit width) .i.e reg0x96.
174 * @param[in] baudrate - baut rate of UART.
175 * @param[in] pclk - system clock.
176 * @param[out] div - uart clock divider.
177 * @param[out] bwpc - bitwidth, should be set to larger than 2.
178 * @return none
179 * @note BaudRate*(div+1)*(bwpc+1) = system clock
180 * simplify the expression: div*bwpc = constant(z)
181 * bwpc range from 3 to 15.so loop and get the minimum one decimal point
182 */
uart_cal_div_and_bwpc(unsigned int baudrate,unsigned int pclk,unsigned short * div,unsigned char * bwpc)183 void uart_cal_div_and_bwpc(unsigned int baudrate, unsigned int pclk, unsigned short *div, unsigned char *bwpc)
184 {
185 unsigned char i = 0, j = 0;
186 unsigned int primeInt = 0;
187 unsigned char primeDec = 0;
188 unsigned int D_intdec[13], D_int[13];
189 unsigned char D_dec[13];
190
191 primeInt = pclk / baudrate;
192 primeDec = 10 * pclk / baudrate - 10 * primeInt;
193
194 if (uart_is_prime(primeInt)) { // primeInt is prime
195 primeInt += 1; // +1 must be not prime. and primeInt must be larger than 2.
196 } else {
197 if (primeDec > 5) { // >5
198 primeInt += 1;
199 if (uart_is_prime(primeInt)) {
200 primeInt -= 1;
201 }
202 }
203 }
204
205 for (i = 3; i <= 15; i++) {
206 D_intdec[i - 3] = (10 * primeInt) / (i + 1); // get the LSB
207 D_dec[i - 3] = D_intdec[i - 3] - 10 * (D_intdec[i - 3] / 10); // get the decimal section
208 D_int[i - 3] = D_intdec[i - 3] / 10; // get the integer section
209 }
210
211 // find the max and min one decimation point
212 unsigned char position_min = 0, position_max = 0;
213 unsigned int min = 0xffffffff, max = 0x00;
214 for (j = 0; j < 13; j++) {
215 if ((D_dec[j] <= min) && (D_int[j] != 0x01)) {
216 min = D_dec[j];
217 position_min = j;
218 }
219 if (D_dec[j] >= max) {
220 max = D_dec[j];
221 position_max = j;
222 }
223 }
224
225 if ((D_dec[position_min] < 5) && (D_dec[position_max] >= 5)) {
226 if (D_dec[position_min] < (10 - D_dec[position_max])) {
227 *bwpc = position_min + 3;
228 *div = D_int[position_min] - 1;
229 } else {
230 *bwpc = position_max + 3;
231 *div = D_int[position_max];
232 }
233 } else if ((D_dec[position_min] < 5) && (D_dec[position_max] < 5)) {
234 *bwpc = position_min + 3;
235 *div = D_int[position_min] - 1;
236 } else {
237 *bwpc = position_max + 3;
238 *div = D_int[position_max];
239 }
240 }
241
242 /**
243 * @brief This funtion serves to set r_rxtimeout. This setting is transfer one bytes need cycles base on uart_clk
244 * For example, if transfer one bytes (1start bit+8bits data+1 priority bit+2stop bits) total 12 bits,
245 * this register setting should be (bpwc+1)*12.
246 * @param[in] uart_num - UART0 or UART1.
247 * @param[in] bwpc - bitwidth, should be set to larger than 2.
248 * @param[in] bit_cnt - bit number.
249 * @param[in] mul - mul.
250 * @return none
251 */
uart_set_dma_rx_timeout(uart_num_e uart_num,unsigned char bwpc,unsigned char bit_cnt,uart_timeout_mul_e mul)252 void uart_set_dma_rx_timeout(uart_num_e uart_num, unsigned char bwpc, unsigned char bit_cnt, uart_timeout_mul_e mul)
253 {
254 reg_uart_rx_timeout0(uart_num) = (bwpc + 1) * bit_cnt; // one byte includes 12 bits at most
255 reg_uart_rx_timeout1(uart_num) &= (~FLD_UART_TIMEOUT_MUL);
256 reg_uart_rx_timeout1(uart_num) |= mul; // if over 2*(tmp_bwpc+1),one transaction end.
257 }
258
259 unsigned char uart_tx_byte_index[2] = {0};
260 /**
261 * @brief This function serves to send data by byte with not DMA method.
262 * @param[in] uart_num - UART0 or UART1.
263 * @param[in] tx_data - the data to be send.
264 * @return none
265 */
uart_send_byte(uart_num_e uart_num,unsigned char tx_data)266 void uart_send_byte(uart_num_e uart_num, unsigned char tx_data)
267 {
268 while (uart_get_txfifo_num(uart_num) > 7) {
269 }
270
271 reg_uart_data_buf(uart_num, uart_tx_byte_index[uart_num]) = tx_data;
272 uart_tx_byte_index[uart_num]++;
273 (uart_tx_byte_index[uart_num]) &= 0x03;
274 }
275
276 unsigned char uart_rx_byte_index[2] = {0};
277 /**
278 * @brief This function serves to receive uart data by byte with not DMA method.
279 * @param[in] uart_num - UART0 or UART1.
280 * @return none
281 */
uart_read_byte(uart_num_e uart_num)282 unsigned char uart_read_byte(uart_num_e uart_num)
283 {
284 unsigned char rx_data = reg_uart_data_buf(uart_num, uart_rx_byte_index[uart_num]);
285 uart_rx_byte_index[uart_num]++;
286 uart_rx_byte_index[uart_num] &= 0x03;
287 return rx_data;
288 }
289
290 /**
291 * @brief This function serves to judge if the transmission of uart is done.
292 * @param[in] uart_num - UART0 or UART1.
293 * @return return the tx status.
294 * - 0:tx is done 1:tx isn't done
295 */
uart_tx_is_busy(uart_num_e uart_num)296 unsigned char uart_tx_is_busy(uart_num_e uart_num)
297 {
298 return ((reg_uart_status2(uart_num) & FLD_UART_TX_DONE) ? 0 : 1);
299 }
300
301 /**
302 * @brief This function serves to send uart0 data by halfword with not DMA method.
303 * @param[in] uart_num - UART0 or UART1.
304 * @param[in] data - the data to be send.
305 * @return none
306 */
uart_send_hword(uart_num_e uart_num,unsigned short data)307 void uart_send_hword(uart_num_e uart_num, unsigned short data)
308 {
309 static unsigned char uart_tx_hword_index[2] = {0};
310
311 while (uart_get_txfifo_num(uart_num) > 6) {
312 }
313
314 reg_uart_data_hword_buf(uart_num, uart_tx_hword_index[uart_num]) = data;
315 uart_tx_hword_index[uart_num]++;
316 uart_tx_hword_index[uart_num] &= 0x01;
317 }
318
319 /**
320 * @brief This function serves to send data by word with not DMA method.
321 * @param[in] uart_num - UART0 or UART1.
322 * @param[in] data - the data to be send.
323 * @return none
324 */
uart_send_word(uart_num_e uart_num,unsigned int data)325 void uart_send_word(uart_num_e uart_num, unsigned int data)
326 {
327 while (uart_get_txfifo_num(uart_num) > 4) {
328 }
329
330 reg_uart_data_word_buf(uart_num) = data;
331 }
332
333 /**
334 * @brief This function serves to set the RTS pin's level manually.
335 * @param[in] uart_num - UART0 or UART1.
336 * @param[in] polarity - set the output of RTS pin(only for manual mode).
337 * @return none
338 */
uart_set_rts_level(uart_num_e uart_num,unsigned char polarity)339 void uart_set_rts_level(uart_num_e uart_num, unsigned char polarity)
340 {
341 if (polarity) {
342 reg_uart_ctrl2(uart_num) |= FLD_UART_RTS_MANUAL_V;
343 } else {
344 reg_uart_ctrl2(uart_num) &= (~FLD_UART_RTS_MANUAL_V);
345 }
346 }
347
348 /**
349 * @brief This function serves to set pin for UART0 cts function .
350 * @param[in] cts_pin -To set cts pin.
351 * @return none
352 */
uart_set_cts_pin(uart_cts_pin_e cts_pin)353 void uart_set_cts_pin(uart_cts_pin_e cts_pin)
354 {
355 unsigned char val = 0;
356 unsigned char mask = 0xff;
357 if (cts_pin == UART0_CTS_PA1) {
358 mask = (unsigned char)~(BIT(2) | BIT(3));
359 val = BIT(2);
360 } else if (cts_pin == UART0_CTS_PB6) {
361 mask = (unsigned char)~(BIT(4) | BIT(5));
362 val = BIT(5);
363 reg_gpio_pad_mul_sel |= BIT(0);
364 } else if (cts_pin == UART0_CTS_PD0) {
365 mask = (unsigned char)~(BIT(0) | BIT(1));
366 val = 0;
367 } else if (cts_pin == UART1_CTS_PC4) {
368 mask = (unsigned char)~(BIT(0) | BIT(1));
369 val = BIT(1);
370 reg_gpio_pad_mul_sel |= BIT(0);
371 } else if (cts_pin == UART1_CTS_PD4) {
372 mask = (unsigned char)~(BIT(0) | BIT(1));
373 val = 0;
374 } else if (cts_pin == UART1_CTS_PE1) {
375 mask = (unsigned char)~(BIT(2) | BIT(3));
376 val = BIT(2);
377 }
378 reg_gpio_func_mux(cts_pin) = (reg_gpio_func_mux(cts_pin) & mask) | val;
379 gpio_function_dis(cts_pin);
380 }
381
382 /**
383 * @brief This function serves to set pin for UART0 rts function .
384 * @param[in] rts_pin - To set rts pin.
385 * @return none
386 */
uart_set_rts_pin(uart_rts_pin_e rts_pin)387 void uart_set_rts_pin(uart_rts_pin_e rts_pin)
388 {
389 unsigned char val = 0;
390 unsigned char mask = 0xff;
391 if (rts_pin == UART0_RTS_PA2) {
392 mask = (unsigned char)~(BIT(4) | BIT(5));
393 val = BIT(4);
394 } else if (rts_pin == UART0_RTS_PB4) {
395 mask = (unsigned char)~(BIT(0) | BIT(1));
396 val = BIT(1);
397 reg_gpio_pad_mul_sel |= BIT(0);
398 } else if (rts_pin == UART0_RTS_PD1) {
399 mask = (unsigned char)~(BIT(2) | BIT(3));
400 val = 0;
401 } else if (rts_pin == UART1_RTS_PC5) {
402 mask = (unsigned char)~(BIT(2) | BIT(3));
403 val = BIT(3);
404 reg_gpio_pad_mul_sel |= BIT(0);
405 } else if (rts_pin == UART1_RTS_PD5) {
406 mask = (unsigned char)~(BIT(2) | BIT(3));
407 val = 0;
408 } else if (rts_pin == UART1_RTS_PE3) {
409 mask = (unsigned char)~(BIT(6) | BIT(7));
410 val = BIT(6);
411 }
412 reg_gpio_func_mux(rts_pin) = (reg_gpio_func_mux(rts_pin) & mask) | val;
413 gpio_function_dis(rts_pin);
414 }
415
416 /**
417 * @brief This function serves to select pin for UART module.
418 * @param[in] tx_pin - the pin to send data.
419 * @param[in] rx_pin - the pin to receive data.
420 * @return none
421 */
uart_set_pin(uart_tx_pin_e tx_pin,uart_rx_pin_e rx_pin)422 void uart_set_pin(uart_tx_pin_e tx_pin, uart_rx_pin_e rx_pin)
423 {
424 gpio_set_up_down_res(tx_pin, GPIO_PIN_PULLUP_10K);
425 gpio_set_up_down_res(rx_pin, GPIO_PIN_PULLUP_10K);
426 uart_set_fuc_pin(tx_pin, rx_pin); // set tx and rx pin
427 gpio_input_en(tx_pin);
428 gpio_input_en(rx_pin);
429 }
430
431 /**
432 * @brief This function serves to set rtx pin for UART module.
433 * @param[in] rx_pin - the rtx pin need to set.
434 * @return none
435 */
uart_set_rtx_pin(uart_rx_pin_e rx_pin)436 void uart_set_rtx_pin(uart_rx_pin_e rx_pin)
437 {
438 unsigned char val = 0;
439 unsigned char mask = 0xff;
440 gpio_set_up_down_res(rx_pin, GPIO_PIN_PULLUP_10K);
441 if (rx_pin == UART0_RX_PA4) {
442 mask = (unsigned char)~(BIT(1) | BIT(0));
443 val = BIT(0);
444 } else if (rx_pin == UART0_RX_PB3) {
445 mask = (unsigned char)~(BIT(7) | BIT(6));
446 val = BIT(7);
447 reg_gpio_pad_mul_sel |= BIT(0);
448 } else if (rx_pin == UART0_RX_PD3) {
449 mask = (unsigned char)~(BIT(7) | BIT(6));
450 val = 0;
451 } else if (rx_pin == UART1_RX_PC7) {
452 mask = (unsigned char)~(BIT(7) | BIT(6));
453 val = BIT(7);
454 reg_gpio_pad_mul_sel |= BIT(0);
455 } else if (rx_pin == UART1_RX_PD7) {
456 mask = (unsigned char)~(BIT(7) | BIT(6));
457 val = 0;
458 } else if (rx_pin == UART1_RX_PE2) {
459 mask = (unsigned char)~(BIT(5) | BIT(4));
460 val = BIT(4);
461 }
462 reg_gpio_func_mux(rx_pin) = (reg_gpio_func_mux(rx_pin) & mask) | val;
463 gpio_input_en(rx_pin);
464 gpio_function_dis(rx_pin);
465 }
466
467 /**
468 * @brief This function serves to send data with not DMA method.
469 * @param[in] uart_num - UART0 or UART1.
470 * @param[in] addr - pointer to the buffer containing data need to send.
471 * @param[in] len - NDMA transmission length.
472 * @return 1
473 */
uart_send(uart_num_e uart_num,unsigned char * addr,unsigned char len)474 unsigned char uart_send(uart_num_e uart_num, unsigned char *addr, unsigned char len)
475 {
476 for (unsigned char i = 0; i < len; i++) {
477 uart_send_byte(uart_num, addr[i]);
478 }
479 return 1;
480 }
481
482 /**
483 * @brief This function serves to send data by DMA, this function tell the DMA to get data from the RAM and start
484 * @param[in] uart_num - UART0 or UART1.
485 * @param[in] addr - pointer to the buffer containing data need to send.
486 * @param[in] len - DMA transmission length.The maximum transmission length of DMA is 0xFFFFFC bytes,
487 * so dont'n over this length.
488 * @return 1 dma start send.
489 * 0 the length is error.
490 */
uart_send_dma(uart_num_e uart_num,unsigned char * addr,unsigned int len)491 unsigned char uart_send_dma(uart_num_e uart_num, unsigned char *addr, unsigned int len)
492 {
493 if (len != 0) {
494 uart_clr_tx_done(uart_num);
495 dma_set_address(uart_dma_tx_chn[uart_num], (unsigned int)convert_ram_addr_cpu2bus(addr),
496 reg_uart_data_buf_adr(uart_num));
497 dma_set_size(uart_dma_tx_chn[uart_num], len, DMA_WORD_WIDTH);
498 dma_chn_en(uart_dma_tx_chn[uart_num]);
499 return 1;
500 } else {
501 return 0;
502 }
503 }
504
505 /**
506 * @brief This function serves to receive data function by DMA,
507 * this function tell the DMA to get data from the uart data fifo.
508 * @param[in] uart_num - UART0 or UART1.
509 * @param[in] addr - pointer to the buffer receive data.
510 * @param[in] rev_size - the receive length of DMA,The maximum transmission length of DMA is 0xFFFFFC bytes,
511 * so dont'n over this length.
512 * @note The DMA version of A0 has some limitians.
513 * 0:We should know the real receive length-len.
514 * 1:If the data length we receive isn't the multiple of 4(the DMA carry 4-byte one time),like 5,
515 * it will carry 8 byte, while the last 3-byte data is random.
516 * 2:The receive buff length sholud be equal to rec_size.
517 * The relation of the receive buff length and rec_size and the real receive data length-len:
518 * REC_BUFF_LEN=rec_size= ((len%4)==0 ? len : ((len/4)+1)*4).
519 * The DMA version of A1 can receive any length of data,the rev_size is useless.
520 * @return none
521 */
uart_receive_dma(uart_num_e uart_num,unsigned char * addr,unsigned int rev_size)522 void uart_receive_dma(uart_num_e uart_num, unsigned char *addr, unsigned int rev_size)
523 {
524 dma_chn_dis(uart_dma_rx_chn[uart_num]);
525 /* In order to be able to receive data of unknown length(A0 doesn't suppport),
526 * the DMA SIZE is set to the longest value 0xffffffff. After entering suspend and wake up,
527 * and then continue to receive, DMA will no longer move data from uart fifo,
528 * because DMA thinks that the last transmission was not completed and must disable dma_chn first.
529 * Modified by minghai,confirmed qiangkai 2020.11.26.
530 */
531 dma_set_address(uart_dma_rx_chn[uart_num], reg_uart_data_buf_adr(uart_num),
532 (unsigned int)convert_ram_addr_cpu2bus(addr));
533 if (g_chip_version == 0xff) {
534 dma_set_size(uart_dma_rx_chn[uart_num], rev_size, DMA_WORD_WIDTH);
535 } else {
536 reg_dma_size(uart_dma_rx_chn[uart_num]) = 0xffffffff;
537 }
538
539 dma_chn_en(uart_dma_rx_chn[uart_num]);
540 }
541
542 /**
543 * @brief This function serves to set uart tx_dam channel and config dma tx default.
544 * @param[in] uart_num - UART0 or UART1.
545 * @param[in] chn - dma channel.
546 * @return none
547 */
uart_set_tx_dma_config(uart_num_e uart_num,dma_chn_e chn)548 void uart_set_tx_dma_config(uart_num_e uart_num, dma_chn_e chn)
549 {
550 uart_dma_tx_chn[uart_num] = chn;
551 dma_config(chn, &uart_tx_dma_config[uart_num]);
552 }
553
554 /**
555 * @brief This function serves to set uart rx_dam channel and config dma rx default.
556 * @param[in] uart_num - UART0 or UART1.
557 * @param[in] chn - dma channel.
558 * @return none
559 */
uart_set_rx_dma_config(uart_num_e uart_num,dma_chn_e chn)560 void uart_set_rx_dma_config(uart_num_e uart_num, dma_chn_e chn)
561 {
562 uart_dma_rx_chn[uart_num] = chn;
563 dma_config(chn, &uart_rx_dma_config[uart_num]);
564 }
565
566 /**
567 * @brief UART hardware flow control configuration. Configure CTS.
568 * @param[in] uart_num - UART0 or UART1.
569 * @param[in] cts_pin - RTS pin select.
570 * @param[in] cts_parity - when CTS's input equals to select, tx will be stopped.
571 * @return none
572 */
uart_cts_config(uart_num_e uart_num,uart_cts_pin_e cts_pin,unsigned char cts_parity)573 void uart_cts_config(uart_num_e uart_num, uart_cts_pin_e cts_pin, unsigned char cts_parity)
574 {
575 uart_set_cts_pin(cts_pin);
576
577 gpio_input_en(cts_pin); // enable input
578
579 if (cts_parity) {
580 reg_uart_ctrl1(uart_num) |= FLD_UART_TX_CTS_POLARITY;
581 } else {
582 reg_uart_ctrl1(uart_num) &= (~FLD_UART_TX_CTS_POLARITY);
583 }
584 }
585
586 /**
587 * @brief UART hardware flow control configuration. Configure RTS.
588 * @param[in] uart_num - UART0 or UART1.
589 * @param[in] rts_pin - RTS pin select.
590 * @param[in] rts_parity - whether invert the output of RTS pin(only for auto mode)
591 * @param[in] auto_mode_en - set the mode of RTS(auto or manual).
592 * @return none
593 */
uart_rts_config(uart_num_e uart_num,uart_rts_pin_e rts_pin,unsigned char rts_parity,unsigned char auto_mode_en)594 void uart_rts_config(uart_num_e uart_num, uart_rts_pin_e rts_pin, unsigned char rts_parity, unsigned char auto_mode_en)
595 {
596 uart_set_rts_pin(rts_pin);
597
598 if (auto_mode_en) {
599 reg_uart_ctrl2(uart_num) |= FLD_UART_RTS_MANUAL_M;
600 } else {
601 reg_uart_ctrl2(uart_num) &= (~FLD_UART_RTS_MANUAL_M);
602 }
603
604 if (rts_parity) {
605 reg_uart_ctrl2(uart_num) |= FLD_UART_RTS_POLARITY;
606 } else {
607 reg_uart_ctrl2(uart_num) &= (~FLD_UART_RTS_POLARITY);
608 }
609 }
610
611 /**********************************************************************************************************************
612 * local function implementation *
613 *********************************************************************************************************************/
614 /**
615 * @brief This function is used to look for the prime.if the prime is finded,it will return 1, or return 0.
616 * @param[in] n - the calue to judge.
617 * @return 0 or 1
618 */
uart_is_prime(unsigned int n)619 static unsigned char uart_is_prime(unsigned int n)
620 {
621 unsigned int i = 5;
622 if (n <= 3) {
623 return 1; // althought n is prime, the bwpc must be larger than 2.
624 } else if ((n % 2 == 0) || (n % 3 == 0)) {
625 return 0;
626 } else {
627 for (i = 5; i * i < n; i += 6) {
628 if ((n % i == 0) || (n % (i + 2)) == 0) {
629 return 0;
630 }
631 }
632 return 1;
633 }
634 }
635
636 /**
637 * @brief This function serves to set pin for UART fuction.
638 * @param tx_pin - To set TX pin.
639 * @param rx_pin - To set RX pin.
640 * @return none
641 */
uart_set_fuc_pin(uart_tx_pin_e tx_pin,uart_rx_pin_e rx_pin)642 static void uart_set_fuc_pin(uart_tx_pin_e tx_pin, uart_rx_pin_e rx_pin)
643 {
644 unsigned char val = 0;
645 unsigned char mask = 0xff;
646
647 if (tx_pin == UART0_TX_PA3) {
648 mask = (unsigned char)~(BIT(7) | BIT(6));
649 val = BIT(6);
650 } else if (tx_pin == UART0_TX_PB2) {
651 mask = (unsigned char)~(BIT(5) | BIT(4));
652 val = BIT(5);
653 reg_gpio_pad_mul_sel |= BIT(0);
654 } else if (tx_pin == UART0_TX_PD2) {
655 mask = (unsigned char)~(BIT(5) | BIT(4));
656 val = 0;
657 } else if (tx_pin == UART1_TX_PC6) {
658 mask = (unsigned char)~(BIT(5) | BIT(4));
659 val = BIT(5);
660 reg_gpio_pad_mul_sel |= BIT(0);
661 } else if (tx_pin == UART1_TX_PD6) {
662 mask = (unsigned char)~(BIT(5) | BIT(4));
663 val = 0;
664 } else if (tx_pin == UART1_TX_PE0) {
665 mask = (unsigned char)~(BIT(1) | BIT(0));
666 ;
667 val = BIT(0);
668 }
669 reg_gpio_func_mux(tx_pin) = (reg_gpio_func_mux(tx_pin) & mask) | val;
670
671 if (rx_pin == UART0_RX_PA4) {
672 mask = (unsigned char)~(BIT(1) | BIT(0));
673 val = BIT(0);
674 } else if (rx_pin == UART0_RX_PB3) {
675 mask = (unsigned char)~(BIT(7) | BIT(6));
676 val = BIT(7);
677 reg_gpio_pad_mul_sel |= BIT(0);
678 } else if (rx_pin == UART0_RX_PD3) {
679 mask = (unsigned char)~(BIT(7) | BIT(6));
680 val = 0;
681 } else if (rx_pin == UART1_RX_PC7) {
682 mask = (unsigned char)~(BIT(7) | BIT(6));
683 val = BIT(7);
684 reg_gpio_pad_mul_sel |= BIT(0);
685 } else if (rx_pin == UART1_RX_PD7) {
686 mask = (unsigned char)~(BIT(7) | BIT(6));
687 val = 0;
688 } else if (rx_pin == UART1_RX_PE2) {
689 mask = (unsigned char)~(BIT(5) | BIT(4));
690 val = BIT(4);
691 }
692 // note: setting pad the function must before setting no_gpio function,
693 // cause it will lead to uart transmit extra one byte data at begin.(confirmed by minghai&sunpeng)
694 reg_gpio_func_mux(rx_pin) = (reg_gpio_func_mux(rx_pin) & mask) | val;
695
696 gpio_function_dis(tx_pin);
697 gpio_function_dis(rx_pin);
698 }
699