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