• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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