1 /**
2   ******************************************************************************
3   * @file    rtl8721dhp_usi_uart.c
4   * @author
5   * @version V1.0.0
6   * @date    2017-09-30
7   * @brief   This file contains all the functions prototypes for the USI UART firmware
8   *             library, including the following functionalities of the Universal Asynchronous
9   *             Receiver/Transmitter (UART) peripheral:
10   *           - Initialization
11   *           - Clear UART TX/RX FIFO
12   *           - Uart Rx Path Control (disable/enable)
13   *           - Baud Rate Setting
14   *           - Receive/Send Data Interface
15   *           - Uart Low Power Rx Initialization
16   *           - Uart Low Power Rx Monitor Function Initialization
17   *           - Low Power Rx Baud Rate Setting
18   *           - Uart IrDA Function Initialization
19   *           - Uart Rx Byte Counter Interface
20   *           - Interrupts and flags management
21   *
22   ******************************************************************************
23   * @attention
24   *
25   * This module is a confidential and proprietary property of RealTek and
26   * possession or use of this module requires written permission of RealTek.
27   *
28   * Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
29   ******************************************************************************
30   */
31 
32 #include "ameba_soc.h"
33 #include "rtl8721d_usi_uart.h"
34 
35 const USI_DevTable USI_DEV_TABLE[1] = {
36 		{USI0_DEV, GDMA_HANDSHAKE_INTERFACE_USI0_TX, GDMA_HANDSHAKE_INTERFACE_USI0_RX, USI_IRQ}
37 };
38 
39 u32 USI_UART_StateTx[1];
40 u32 USI_UART_StateRx[1];
41 
42 USI_UARTCFG_TypeDef usi_uart_config[2]=
43 {
44 	/* USI0-UART */
45 	{
46 		.LOW_POWER_RX_ENABLE = DISABLE, /*Enable low power RX*/
47 	},
48 	/* USI1-UART */
49 	{
50 		.LOW_POWER_RX_ENABLE = DISABLE,
51 	},
52 };
53 
54 /**
55   * @brief  Deinitializes the USIx peripheral registers to their default reset values in USI UART mode.
56   * @param  USIx: where x can be 0.
57   * @retval None
58   */
USI_UARTDeInit(USI_TypeDef * USIx)59 void USI_UARTDeInit(USI_TypeDef* USIx)
60 {
61 	/*check the parameters*/
62 	assert_param(IS_ALL_USI_PERIPH(USIx));
63 
64 	/*reset USI all logic*/
65 	USIx->SW_RESET &=(~USI_SW_RESET_RSTB);
66 	USIx->SW_RESET |=USI_SW_RESET_RSTB;
67 
68 	/*disable USI UART*/
69 	USIx->USI_MODE_CTRL &= (~USI_SERIAL_MODE);
70 
71 	/*clear all USI UART interrupts*/
72 	USIx->INTERRUPT_ALL_CLR = USI_INT_ALL_CLEAR;
73 
74 	/*disable all interrupts*/
75 	USIx->INTERRUPT_ENABLE = 0x00000000;
76 }
77 
78 /**
79   * @brief  Fills each USI_UARTInitStruct member with its default value.
80   * @param  USI_UARTInitStruct: pointer to an USI_UARTInitTypeDef structure which will be initialized.
81   * @retval   None
82   */
USI_UARTStructInit(USI_UARTInitTypeDef * USI_UARTInitStruct)83  void USI_UARTStructInit(USI_UARTInitTypeDef* USI_UARTInitStruct)
84 {
85 	/* USI_UARTInitStruct members default value */
86 	USI_UARTInitStruct->USI_UARTParity         = USI_RUART_PARITY_ENABLE;
87 	USI_UARTInitStruct->USI_UARTParityType = USI_RUART_ODD_PARITY;
88 	USI_UARTInitStruct->USI_UARTStickParity = USI_RUART_STICK_PARITY_DISABLE;
89 	USI_UARTInitStruct->USI_UARTStopBit       = USI_RUART_STOP_BIT_1;
90 	USI_UARTInitStruct->USI_UARTWordLen        = USI_RUART_WLS_8BITS;
91 	USI_UARTInitStruct->USI_UARTRxFifoTrigLevel = 1;
92 	USI_UARTInitStruct->USI_UARTDmaModeCtrl = ENABLE;
93 	USI_UARTInitStruct->USI_UARTFlowControl   = DISABLE;
94 	USI_UARTInitStruct->USI_UARTTxFifoTrigLevel = 0x40;
95 	USI_UARTInitStruct->USI_UARTFlwCtrlRxHoldThd = 0x04;
96 }
97 
98 /**
99   * @brief    Initializes the USIx peripheral according to the specified
100   *              parameters in the USI_UARTInitStruct.
101   * @param  USIx: where x can be 0.
102   * @param  USI_UARTInitStruct: pointer to a USI_UARTInitTypeDef structure that contains
103   *              the configuration information for the specified USART peripheral.
104   * @retval None
105   */
USI_UARTInit(USI_TypeDef * USIx,USI_UARTInitTypeDef * USI_UARTInitStruct)106  void USI_UARTInit(USI_TypeDef* USIx, USI_UARTInitTypeDef *USI_UARTInitStruct)
107 {
108 	/*check the parameters*/
109 	assert_param(IS_ALL_USI_PERIPH(USIx));
110 	assert_param(USI_UARTInitStruct->USI_UARTRxFifoTrigLevel <= 0x40);
111 	assert_param(IS_USI_UART_PARITY_ENABLE(USI_UARTInitStruct->USI_UARTParity));
112 	assert_param(IS_USI_UART_PARITY_TYPE(USI_UARTInitStruct->USI_UARTParityType));
113 	assert_param(IS_USI_UART_STICK_PARITY_ENABLE(USI_UARTInitStruct->USI_UARTStickParity));
114 	assert_param(IS_USI_UART_STOP_BIT(USI_UARTInitStruct->USI_UARTStopBit));
115 	assert_param(IS_USI_UART_WLS(USI_UARTInitStruct->USI_UARTWordLen));
116 	assert_param(USI_UARTInitStruct->USI_UARTTxFifoTrigLevel <= 0x40);
117 	assert_param(USI_UARTInitStruct->USI_UARTFlwCtrlRxHoldThd <= 0x40);
118 
119 	/*reset USI all logic, this step will clear tx/rx fifo*/
120 	USIx->SW_RESET &=(~USI_SW_RESET_RSTB);
121 	USIx->SW_RESET |=USI_SW_RESET_RSTB;
122 
123 	/*clear rx fifo and release rx fifo logic*/
124 	USIx->SW_RESET &= (~USI_SW_RESET_RXFIFO_RSTB);
125 	USIx->SW_RESET |= USI_SW_RESET_RXFIFO_RSTB;
126 
127 	/*clear tx fifo and release tx fifo logic*/
128 	USIx->SW_RESET &= (~USI_SW_RESET_TXFIFO_RSTB);
129 	USIx->SW_RESET |= USI_SW_RESET_TXFIFO_RSTB;
130 
131 	/*disable USI all mode, configure USI with UART mode*/
132 	USIx->USI_MODE_CTRL &= (~USI_SERIAL_MODE);
133 	USIx->USI_MODE_CTRL |= USI_SERIAL_UART_MODE;
134 
135 	/*reset RX path*/
136 	USIx->SW_RESET &= (~USI_SW_RESET_RX_RSTB);
137 
138 	/*release TX path*/
139 	USIx->SW_RESET |= USI_SW_RESET_TX_RSTB;
140 
141 	/*disable all interrupts*/
142 	USIx->INTERRUPT_ENABLE = 0x00000000;
143 
144 	/*clear all USI UART interrupts*/
145 	USIx->INTERRUPT_ALL_CLR = USI_INT_ALL_CLEAR;
146 
147 	/*configure RX fifo trigger level*/
148 	USIx->RX_FIFO_CTRL &= (~USI_RXFIFO_ALMOST_FULL_TH);
149 	USIx->RX_FIFO_CTRL |= USI_UARTInitStruct->USI_UARTRxFifoTrigLevel;
150 
151 	/*configure TX fifo trigger level*/
152 	USIx->TX_FIFO_CTRL &= (~USI_TXFIFO_ALMOST_EMPTY_TH);
153 	USIx->TX_FIFO_CTRL |= USI_UARTInitStruct->USI_UARTTxFifoTrigLevel;
154 
155 	/*set auto flow control RTS hold level*/
156 	USIx->UART_FLOW_CTRL &= (~USI_UART_RX_HOLD_THRD);
157 	USIx->UART_FLOW_CTRL |= USI_UARTInitStruct->USI_UARTFlwCtrlRxHoldThd<<8;
158 
159 	/* Configure FlowControl */
160 	if (USI_UARTInitStruct->USI_UARTFlowControl == ENABLE) {
161 		USIx->UART_FLOW_CTRL |= (USI_UART_AUTO_FLOW_EN|USI_UART_RX_RTS);
162 	} else {
163 		USIx->UART_FLOW_CTRL &= (~(USI_UART_AUTO_FLOW_EN|USI_UART_RX_RTS));
164 	}
165 
166 	/*configure word length, stop bit, parity, parity type, stickparity*/
167 	USIx->UART_CTRL &= (~(USI_UART_WORD_LEN_MD|USI_UART_STOP_BIT_MD|USI_UART_PARITY_ENABLE|USI_UART_PARITY_EVEN|USI_UART_STICK_PARITY_BIT));
168 	USIx->UART_CTRL |= ((USI_UARTInitStruct->USI_UARTWordLen) |
169 		(USI_UARTInitStruct->USI_UARTStopBit) |
170 		(USI_UARTInitStruct->USI_UARTParity) |
171 		(USI_UARTInitStruct->USI_UARTParityType) |
172 		(USI_UARTInitStruct->USI_UARTStickParity));
173 
174 	if(USI_UARTInitStruct->USI_UARTDmaModeCtrl  != ENABLE) {
175 		/* disable the USI UART TX/RX  DMA */
176 		USIx->DMA_ENABLE &= ~ (USI_TX_DMA_ENABLE|USI_RX_DMA_ENABLE);
177 	}
178 }
179 
180 /**
181   * @brief    get ovsr & ovsr_adj parameters for the given baudrate
182   * @param  USIx: where x can be 0.
183   * @param  baudrate: the desired baudrate
184   * @param  ovsr: the pointer to ovsr parameter
185   * @param  ovsr_adj: the pointer to ovsr_adj parameter
186   * @retval   searching status:
187   *              - 1: found
188   *              - 0: not found
189   */
USI_UARTBaudParaGet(u32 baudrate,u32 * ovsr,u32 * ovsr_adj)190  u32 USI_UARTBaudParaGet(u32 baudrate, u32 *ovsr, u32 *ovsr_adj)
191 {
192 	USI_UARTBaudParaGetFull(XTAL_ClkGet(), baudrate, ovsr, ovsr_adj);
193 	return 1;
194 }
195 
196 /**
197   * @brief    get ovsr & ovsr_adj parameters according to the given baudrate and UART IP clock.
198   * @param  USIx: where x can be 0.
199   * @param  IPclk: the given UART IP clock, Unit: [ Hz ]
200   * @param  baudrate: the desired baudrate, Unit: bps[ bit per second ]
201   * @param  ovsr: integer parameter related to the desired baud rate
202   * @param  ovsr_adj: fractional parameter related to the desired baud rate
203   * @retval  None
204   */
USI_UARTBaudParaGetFull(u32 IPclk,u32 baudrate,u32 * ovsr,u32 * ovsr_adj)205 void USI_UARTBaudParaGetFull(u32 IPclk, u32 baudrate, u32 *ovsr, u32 *ovsr_adj)
206 {
207 	u32 i;
208 	u32 Remainder;
209 	u32 TempAdj = 0;
210 	u32 TempMultly;
211 
212 	/*obtain the ovsr parameter*/
213 	*ovsr = IPclk / baudrate;
214 
215 	/*get the remainder related to the ovsr_adj parameter*/
216 	Remainder = IPclk % baudrate;
217 
218 	/*calculate the ovsr_adj parameter*/
219 	for(i = 0; i < 11; i++){
220 		TempAdj = TempAdj << 1;
221 		TempMultly = (Remainder * (12-i));
222 		TempAdj |= ((TempMultly / baudrate - (TempMultly - Remainder) / baudrate) ? 1 : 0);
223 	}
224 
225 	/*obtain the ovsr_adj parameter*/
226 	*ovsr_adj = TempAdj;
227 }
228 
229 /**
230   * @brief    Set Uart Baud Rate use baudrate val.
231   * @param  USIx: where x can be 0.
232   * @param  BaudRate: Baud Rate Val, like 115200 (unit is HZ).
233   * @retval  None
234   */
USI_UARTSetBaud(USI_TypeDef * USIx,u32 BaudRate)235 void USI_UARTSetBaud(USI_TypeDef* USIx, u32 BaudRate)
236 {
237 	u32 Ovsr;
238 	u32 Ovsr_adj;
239 
240 	/*check the parameters*/
241 	assert_param(IS_ALL_USI_PERIPH(USIx));
242 
243 	/* get baud rate parameter based on baudrate */
244 	USI_UARTBaudParaGetFull(XTAL_ClkGet(), BaudRate, &Ovsr, &Ovsr_adj);
245 
246 	/*confgure TX path baudrate*/
247 	USIx->UART_TX_FRACTION_BAUD &=(~(USI_UART_TX_XFACTOR|USI_UART_TX_XFACTOR_ADJ));
248 	USIx->UART_TX_FRACTION_BAUD |= (Ovsr|(Ovsr_adj<<20));
249 
250 	/*configure RX path baudrate*/
251 	USIx->UART_RX_BAUD_XTAL &= (~USI_RUART_LPRX_XTAL_CYCNUM_PERBIT);
252 	USIx->UART_RX_BAUD_XTAL |= Ovsr;
253 	USIx->UART_RX_FRACTION_BAUD_CTRL &= (~USI_UART_RX_XFACTOR_ADJ);
254 	USIx->UART_RX_FRACTION_BAUD_CTRL |= Ovsr_adj;
255 }
256 
257 /**
258   * @brief    Set Uart Baud Rate use baudrate parameter Ovsr & Ovsr_adj.
259   * @param  USIx: where x can be 0.
260   * @param  Ovsr: Specifies the ovsr parameter related to baud rate.
261   *				This parameter is caculated by using uart IP clock and the desired baud rate
262   * @param  Ovsr_adj: Specifies the ovsr_adj parameter related fractional part for the desired baud rate.
263   *				This parameter is also caculated by using uart IP clock and the desired baud rate
264   * @retval  None
265   */
USI_UARTSetBaudExt(USI_TypeDef * USIx,u32 Ovsr,u32 Ovsr_adj)266  void USI_UARTSetBaudExt(USI_TypeDef* USIx, u32 Ovsr, u32 Ovsr_adj)
267 {
268 	/*check the parameters*/
269 	assert_param(IS_ALL_USI_PERIPH(USIx));
270 
271 	/*confgure TX path baudrate*/
272 	USIx->UART_TX_FRACTION_BAUD &=(~(USI_UART_TX_XFACTOR|USI_UART_TX_XFACTOR_ADJ));
273 	USIx->UART_TX_FRACTION_BAUD |= (Ovsr|(Ovsr_adj<<20));
274 
275 	/*configure RX path baudrate*/
276 	USIx->UART_RX_BAUD_XTAL &= (~USI_RUART_LPRX_XTAL_CYCNUM_PERBIT);
277 	USIx->UART_RX_BAUD_XTAL |= Ovsr;
278 	USIx->UART_RX_FRACTION_BAUD_CTRL &= (~USI_UART_RX_XFACTOR_ADJ);
279 	USIx->UART_RX_FRACTION_BAUD_CTRL |= Ovsr_adj;
280 }
281 
282 /**
283   * @brief    to set the RX FIFO level to trigger RX interrupt/RTS de-assert
284   * @param  USIx: where x can be 0.
285   * @param  FifoLv: USI UART RX FIFO level, this value can be 1 to 62.
286   */
USI_UARTSetRxLevel(USI_TypeDef * USIx,u32 FifoLv)287 void USI_UARTSetRxLevel(USI_TypeDef* USIx, u32 FifoLv)
288 {
289 	/*check the parameters*/
290 	assert_param(IS_ALL_USI_PERIPH(USIx));
291 
292 	/*configure RX interrupt trigger level*/
293 	USIx->RX_FIFO_CTRL &= (~USI_RXFIFO_ALMOST_FULL_TH);
294 	USIx->RX_FIFO_CTRL |= FifoLv;
295 
296 	/*configure RX CTS hold level*/
297 	USIx->UART_FLOW_CTRL &=(~USI_UART_RX_HOLD_THRD);
298 	USIx->UART_FLOW_CTRL |= (FifoLv<<8);
299 }
300 
301 /**
302   * @brief    enable or disable USI Uart Rx Path
303   * @param  USIx: where x can be 0.
304   * @param  NewState: the new state of the Rx Path.
305   *              This parameter can be: ENABLE or DISABLE.
306   * @note    Because the TX/RX of the IrDA transceiver are in the same module,
307   *              RX fifo can also receive available data when in the process of TX.Therefore,
308   *              the RX Path must be disabled when TX is going on.Namely, IrDA must work
309   *              in the Half duplex mode, though normal UART IP supports Full duplex.
310   * @retval None
311   */
USI_UARTRxCmd(USI_TypeDef * USIx,u32 NewState)312 void USI_UARTRxCmd(USI_TypeDef* USIx, u32 NewState)
313 {
314 	/*check the parameters*/
315 	assert_param(IS_ALL_USI_PERIPH(USIx));
316 
317 	if (NewState != DISABLE) {
318 		/*enable uart receiver*/
319 		USIx->SW_RESET |= USI_SW_RESET_RX_RSTB;
320 	} else {
321 		/*disable uart receiver*/
322 		USIx->SW_RESET &= (~USI_SW_RESET_RX_RSTB);
323 	}
324 }
325 
326   /**
327   * @brief    check if write data to tx fifo.
328   * @param  USIx: where x can be 0.
329   * @retval   status value:
330   *              - 1: tx fifo is empty and can write data to tx fifo
331   *              - 0: tx fifo is not empty
332   */
USI_UARTWritable(USI_TypeDef * USIx)333  u32 USI_UARTWritable(USI_TypeDef* USIx)
334 {
335 	/*check the parameters*/
336 	assert_param(IS_ALL_USI_PERIPH(USIx));
337 
338 	/*check if tx fifo is empty or not. empty return 1 and not empty return 0.*/
339 	if (USIx->TX_FIFO_STATUS & USI_TXFIFO_EMPTY) {
340 		return 1;
341 	}
342 	else {
343 		return 0;
344 	}
345 }
346 
347   /**
348   * @brief    check if there is data in rx fifo.
349   * @param  USIx: where x can be 0.
350   * @retval   status value:
351   *              - 1: rx fifo has valid data and can read data from rx fifo
352   *              - 0: rx fifo is empty
353   */
USI_UARTReadable(USI_TypeDef * USIx)354 u32 USI_UARTReadable(USI_TypeDef* USIx)
355 {
356 	/*check the parameters*/
357 	assert_param(IS_ALL_USI_PERIPH(USIx));
358 
359 	/*check if rx fifo has available data.
360 	available data return 1 and no available data return 0.*/
361 	if (!(USIx->RX_FIFO_STATUS & USI_RXFIFO_EMPTY)) {
362 		return 1;
363 	}
364 	else {
365 		return 0;
366 	}
367 }
368 
369 /**
370   * @brief  Transmits single data through the USIx peripheral.
371   * @param  USIx: where x can be 0.
372   * @param  TxData: the data to transmit.
373   * @retval None
374   */
USI_UARTCharPut(USI_TypeDef * USIx,u8 TxData)375  void USI_UARTCharPut(USI_TypeDef* USIx, u8 TxData)
376 {
377 	/*check the parameters*/
378 	assert_param(IS_ALL_USI_PERIPH(USIx));
379 
380 	/*write one byte to tx fifo*/
381 	USIx->TX_FIFO_WRITE = TxData;
382 }
383 
384 /**
385   * @brief  Get the received data by the USIx peripheral.
386   * @param  USIx: where x can be 0.
387   * @param  pRxByte: the pointer to received data.
388   * @retval   None.
389   */
USI_UARTCharGet(USI_TypeDef * USIx,u8 * pRxByte)390 void USI_UARTCharGet(USI_TypeDef* USIx, u8  *pRxByte)
391 {
392 	/*check the parameters*/
393 	assert_param(IS_ALL_USI_PERIPH(USIx));
394 
395 	/*read one byte from rx fifo*/
396 	*pRxByte = (u8)USIx->RX_FIFO_READ;
397 }
398 
399 /**
400   * @brief  Receive data from rx FIFO, poll USI_UARTReadable.
401   * @param  USIx: selected UART peripheral, where x can be 0.
402   * @param[out]  outBuf: buffer to save data read from UART FIFO.
403   * @param  count: number of data to be read.
404   * @retval none
405   */
USI_UARTReceiveData(USI_TypeDef * USIx,u8 * OutBuf,u32 Count)406 void USI_UARTReceiveData(
407 	USI_TypeDef* USIx,
408 	u8* OutBuf,
409 	u32 Count
410 	)
411 {
412 	u32 cnt = 0;
413 
414 	/*check the parameters*/
415 	assert_param(IS_ALL_USI_PERIPH(USIx));
416 
417 	for(cnt = 0; cnt < Count; cnt++) {
418 		while (USI_UARTReadable(USIx) == 0);
419 
420 		*OutBuf++ = (u8)USIx->RX_FIFO_READ;
421 	}
422 }
423 
424 /**
425   * @brief  Send data to tx FIFO, poll USI_UARTWritable.
426   * @param  USIx: selected UART peripheral, where x can be 0.
427   * @param  inBuf: buffer to be written to Tx FIFO.
428   * @param  count: number of data to be written.
429   * @retval none
430   */
USI_UARTSendData(USI_TypeDef * USIx,u8 * InBuf,u32 Count)431 void USI_UARTSendData(
432 	USI_TypeDef* USIx,
433 	u8* InBuf,
434 	u32 Count
435 	)
436 {
437 	u32 cnt = 0;
438 
439 	/*check the parameters*/
440 	assert_param(IS_ALL_USI_PERIPH(USIx));
441 
442 	for(cnt = 0; cnt < Count; cnt++) {
443 		while (USI_UARTWritable(USIx) == 0);
444 
445 		USIx->TX_FIFO_WRITE = *InBuf++;
446 	}
447 }
448 
449 /**
450   * @brief  Receive data from rx FIFO, with timeout.
451   * @param  USIx: selected UART peripheral, where x can be 0.
452   * @param[out]  outBuf: buffer to save data read from UART FIFO.
453   * @param  count: number of data to be read.
454   * @param  Times: poll USI_UARTReadable times before timeout.
455   * @retval transfer len
456   */
USI_UARTReceiveDataTO(USI_TypeDef * USIx,u8 * OutBuf,u32 Count,u32 Times)457 u32 USI_UARTReceiveDataTO(
458 	USI_TypeDef* USIx,
459 	u8* OutBuf,
460 	u32 Count,
461 	u32 Times
462 	)
463 {
464 	u32 cnt = 0;
465 	u32 polltimes = 0;
466 
467 	/*check the parameters*/
468 	assert_param(IS_ALL_USI_PERIPH(USIx));
469 
470 	while (1) {
471 		if (USI_UARTReadable(USIx)) {
472 			*(OutBuf + cnt) = (u8)USIx->RX_FIFO_READ;
473 			cnt++;
474 			polltimes = 0;
475 
476 			if (cnt >= Count) {
477 				break;
478 			}
479 		} else {
480 			polltimes++;
481 
482 			/* time out */
483 			if (polltimes > Times) {
484 				break;
485 			}
486 		}
487 	}
488 
489 	return (cnt);
490 }
491 
492 /**
493   * @brief  Send data to tx FIFO, with timeout.
494   * @param  USIx: selected UART peripheral, where x can be 0.
495   * @param  InBuf: buffer to be written to Tx FIFO.
496   * @param  Count: number of data to be written.
497   * @param  Times: poll USI_UARTWritable times before timeout.
498   * @retval transfer len
499   */
USI_UARTSendDataTO(USI_TypeDef * USIx,u8 * InBuf,u32 Count,u32 Times)500 u32 USI_UARTSendDataTO(
501 	USI_TypeDef* USIx,
502 	u8* InBuf,
503 	u32 Count,
504 	u32 Times
505 	)
506 {
507 	u32 cnt = 0;
508 	u32 polltimes = 0;
509 
510 	/*check the parameters*/
511 	assert_param(IS_ALL_USI_PERIPH(USIx));
512 
513 	while (1) {
514 		if (USI_UARTWritable(USIx)) {
515 			USIx->TX_FIFO_WRITE = *(InBuf + cnt);
516 			cnt++;
517 			polltimes = 0;
518 
519 			if (cnt >= Count) {
520 				break;
521 			}
522 		} else {
523 			polltimes++;
524 
525 			/* time out */
526 			if (polltimes > Times) {
527 				break;
528 			}
529 		}
530 	}
531 
532 	return (cnt);
533 }
534 
535   /**
536   * @brief    Clear Rx Byte Counter.
537   * @param  USIx: where x can be 0.
538   * @retval   None
539   */
USI_UARTRxByteCntClear(USI_TypeDef * USIx)540 void USI_UARTRxByteCntClear(USI_TypeDef* USIx)
541 {
542 	/*check the parameters*/
543 	assert_param(IS_ALL_USI_PERIPH(USIx));
544 
545 	/*write 1 to clear*/
546 	USIx->RX_FIFO_RD_CNT |= USI_RX_FIFO_RD_CNT_CLR;
547 }
548 
549 /**
550   * @brief    Get the Rx Byte Counter Value.
551   * @param  USIx: where x can be 0.
552   * @note    Get the Rx Byte Counter Value
553   * @note    this counter will increase 1 for each reading the rx fifo, no matter rx fifo is empty or not.
554   * @retval   the value of Rx Byte Counter
555   */
USI_UARTRxByteCntGet(USI_TypeDef * USIx)556 u32 USI_UARTRxByteCntGet(USI_TypeDef* USIx)
557 {
558 	u32 RegValue;
559 
560 	/*check the parameters*/
561 	assert_param(IS_ALL_USI_PERIPH(USIx));
562 
563 	/*Read the REG_RX_BYTE_CNT register value*/
564 	RegValue = USIx->RX_FIFO_RD_CNT;
565 
566 	/*Get the rx byte counter field (REG_RX_BYTE_CNT[15:0]) value*/
567 	RegValue &= USI_RX_FIFO_RD_CNT;
568 
569 	return RegValue;
570 }
571 
572   /**
573   * @brief    enable or disable UART break contol function .
574   * @param  USIx: where x can be 0.
575   * @param  NewState: This parameter can be: ENABLE or DISABLE.
576   * @retval   None
577   */
USI_UARTBreakCtl(USI_TypeDef * USIx,u32 NewState)578 void USI_UARTBreakCtl(USI_TypeDef* USIx, u32 NewState)
579 {
580 	u32 RegValue;
581 
582 	/*check the parameters*/
583 	assert_param(IS_ALL_USI_PERIPH(USIx));
584 
585 	/*get the Line Control Register(LCR) value*/
586 	RegValue = USIx->UART_CTRL;
587 
588 	if(NewState == ENABLE)
589 		/*enable break control*/
590 		RegValue |= USI_UART_BREAK_CTRL;
591 	else
592 		/*disable break control*/
593 		RegValue &= (~ USI_UART_BREAK_CTRL);
594 
595 	USIx->UART_CTRL = RegValue;
596 }
597 
598 /**
599   * @brief    Clear Rx fifo
600   * @param  USIx: where x can be 0.
601   * @retval   None
602   */
USI_UARTClearRxFifo(USI_TypeDef * USIx)603 u32 USI_UARTClearRxFifo(USI_TypeDef* USIx)
604 {
605 	u32  Temp;
606 	u32  WaitTime = 5;
607 
608 	/*check the parameters*/
609 	assert_param(IS_ALL_USI_PERIPH(USIx));
610 
611 	/*write 0 to clear rx fifo*/
612 	USIx->SW_RESET &= (~USI_SW_RESET_RXFIFO_RSTB);
613 
614 	while(WaitTime > 0) {
615 		/*check Rx fifo if empty or not*/
616 		Temp = USIx->RX_FIFO_STATUS & USI_RXFIFO_EMPTY;
617 		if (Temp != 0)
618 			break;
619 
620 		WaitTime--;
621 	}
622 
623 	USIx->SW_RESET |= USI_SW_RESET_RXFIFO_RSTB;
624 
625 	if (Temp != 0)
626 		return _TRUE;
627 	else
628 		return _FALSE;
629 }
630 
631 
632 /**
633   * @brief    Clear Tx fifo .
634   * @param  USIx: where x can be 0.
635   * @retval   None
636   */
USI_UARTClearTxFifo(USI_TypeDef * USIx)637 void USI_UARTClearTxFifo(USI_TypeDef* USIx)
638 {
639 	/*check the parameters*/
640 	assert_param(IS_ALL_USI_PERIPH(USIx));
641 
642 	/*clear tx fifo*/
643 	USIx->SW_RESET &= (~USI_SW_RESET_TXFIFO_RSTB);
644 	USIx->SW_RESET |= USI_SW_RESET_TXFIFO_RSTB;
645 }
646 
647 /**
648   * @brief    USI UART get valid entry count in RX FIFO .
649   * @param  USIx: where x can be 0.
650   * @retval   None
651   */
USI_UARTGetRxFifoValidCnt(USI_TypeDef * USIx)652 u32 USI_UARTGetRxFifoValidCnt(USI_TypeDef* USIx)
653 {
654 	/*check the parameters*/
655 	assert_param(IS_ALL_USI_PERIPH(USIx));
656 
657 	/*acquire RX FIFO valid count*/
658 	return (u32)((USIx->RX_FIFO_STATUS & USI_RXFIFO_VALID_CNT)>>8);
659 }
660 
661 /**
662   * @brief    USI UART get empty entry count in TX FIFO .
663   * @param  USIx: where x can be 0.
664   * @retval   None
665   */
USI_UARTGetTxFifoEmptyCnt(USI_TypeDef * USIx)666 u32 USI_UARTGetTxFifoEmptyCnt(USI_TypeDef* USIx)
667 {
668 	/*check the parameters*/
669 	assert_param(IS_ALL_USI_PERIPH(USIx));
670 
671 	/*acquire TX FIFO empty count*/
672 	return (u32)((USIx->TX_FIFO_STATUS & USI_TXFIFO_EMPTY_SPACE)>>8);
673 }
674 
675 /**
676   * @brief    Enables or disables the specified USIx UART interrupts.
677   * @param  USIx: where x can be 0.
678   * @param  USI_UARTIT: specifies the USIx interrupt sources to be enabled or disabled.
679   *          This parameter can be one or combinations of the following values:
680   *            @arg USI_TX_FIFO_ALMOST_EMPTY_INTER:  tx fifo almost empty interrupt
681   *            @arg USI_TX_FIFO_OVERFLOW_INTER: tx fifo overflow interrupt
682   *            @arg USI_RX_FIFO_ALMOST_FULL_INTER:   rx fifo almost full interrupt
683   *            @arg USI_RX_FIFO_OVERFLOW_INTER: rx fifo overflow interrupt
684   *            @arg USI_RX_FIFO_UNDERFLOW_INTER: rx fifo underflow interrupt
685   *            @arg USI_UART_PARITY_ERROR_INTER:  uart parity error interrupt
686   *            @arg USI_UART_STOP_ERROR_INTER: uart stop bit error interrupt
687   *            @arg USI_UART_BREAK_INTER:  uart break interrupt
688   *            @arg USI_RX_FIFO_TIMEOUT_INTER:   rx fifo timeout interrupt
689   *            @arg USI_RX_BAUDMON_DONE_INTER: uart baud rate monitor done interrupt
690   *            @arg USI_TX_CTS_CHANGE_INTER: uart CTS change interrupt
691   * @param  newState: new state of the specified USIx interrupts.
692   *          This parameter can be: ENABLE or DISABLE.
693   * @retval None
694   */
USI_UARTINTConfig(USI_TypeDef * USIx,u32 USI_UARTIT,u32 newState)695 void USI_UARTINTConfig(
696         USI_TypeDef* USIx,
697         u32 USI_UARTIT,
698         u32 newState
699         )
700 {
701 	/*check the parameters*/
702 	assert_param(IS_ALL_USI_PERIPH(USIx));
703 	assert_param(IS_USI_UART_IT(USI_UARTIT));
704 
705 	if (newState == ENABLE) {
706 		/* Enable the selected USIx interrupts */
707 		USIx->INTERRUPT_ENABLE |= USI_UARTIT;
708 	} else {
709 		/* Disable the selected USIx interrupts */
710 		USIx->INTERRUPT_ENABLE &= (u32)~USI_UARTIT;
711 	}
712 }
713 
714 /**
715   * @brief    get the interrupt identification register value.
716   * @param  USIx: where x can be 0.
717   * @retval   the interrupt identification register value.
718   */
USI_UARTIntStatus(USI_TypeDef * USIx)719 u32 USI_UARTIntStatus(USI_TypeDef* USIx)
720 {
721 	/*check the parameters*/
722 	assert_param(IS_ALL_USI_PERIPH(USIx));
723 
724 	/*return the uart interrupt identification register value*/
725 	return USIx->INTERRUPT_STATUS;
726 }
727 
728 /**
729   * @brief    get the raw interrupt register value.
730   * @param  USIx: where x can be 0.
731   * @retval   the interrupt raw status value.
732   */
USI_UARTGetRawIntStatus(USI_TypeDef * USIx)733 u32 USI_UARTGetRawIntStatus(USI_TypeDef* USIx)
734 {
735 	/*check the parameters*/
736 	assert_param(IS_ALL_USI_PERIPH(USIx));
737 
738 	/*return the uart interrupt raw status register value*/
739 	return USIx->RAW_INTERRUPT_STATUS;
740 }
741 
742 /**
743   * @brief    Clear all USI UART interrupt status.
744   * @param  USIx: where x can be 0.
745   * @note    Write "1" to this register to clear the combined interrupt, all individual interrupts,
746   *               interrupt status register and raw interrupt status register. This bit does not clear
747   *               hardware clearable interrupts but software dis-clearable interrupts, and the relate register
748   *               (include txfifo_almost_empty, rxfifo_almost_full, uart_rxfifo_timeout).
749   * @retval   None
750   */
USI_UARTClearAllIntStatus(USI_TypeDef * USIx)751 void USI_UARTClearAllIntStatus(USI_TypeDef* USIx)
752 {
753 	/*check the parameters*/
754 	assert_param(IS_ALL_USI_PERIPH(USIx));
755 
756 	/*write 1 to clear all interrupts*/
757 	USIx->INTERRUPT_ALL_CLR = USI_INT_ALL_CLEAR;
758 }
759 
760 /**
761   * @brief    Clear specified USI UART interrupt pending bits.
762   * @param  USIx: where x can be 0.
763   * @param  USIUART_IT: specifies the interrupt to be cleared.
764   *   This parameter can be any combination of the following values:
765   *            @arg USI_TX_FIFO_OVERFLOW_INTER: tx fifo overflow interrupt
766   *            @arg USI_RX_FIFO_OVERFLOW_INTER: rx fifo overflow interrupt
767   *            @arg USI_RX_FIFO_UNDERFLOW_INTER: rx fifo underflow interrupt
768   *            @arg USI_UART_PARITY_ERROR_INTER:  uart parity error interrupt
769   *            @arg USI_UART_STOP_ERROR_INTER: uart stop bit error interrupt
770   *            @arg USI_UART_BREAK_INTER:  uart break interrupt
771   *            @arg USI_RX_BAUDMON_DONE_INTER: uart baud rate monitor done interrupt
772   *            @arg USI_TX_CTS_CHANGE_INTER: uart CTS change interrupt
773   * @retval   None
774   */
USI_UARTClearIntStatus(USI_TypeDef * USIx,u32 USIUART_IT)775 void USI_UARTClearIntStatus(USI_TypeDef* USIx, u32 USIUART_IT)
776 {
777 	/*check the parameters*/
778 	assert_param(IS_ALL_USI_PERIPH(USIx));
779 	assert_param(IS_USI_UART_CLEAR_IT(USIUART_IT));
780 
781 	/*write 1 to clear all interrupts*/
782 	USIx->INTERRUPT_STATUS_CLR =  USIUART_IT;
783 }
784 
785 /**
786   * @brief  wait uart tx complete.
787   * @param  USIx: where x can be 0.
788   * @retval: none
789   */
USI_UARTWaitBusy(USI_TypeDef * USIx,u32 PollTimes)790 void USI_UARTWaitBusy(USI_TypeDef* USIx, u32 PollTimes)
791 {
792 	u32 times = 0;
793 
794 	/*check the parameters*/
795 	assert_param(IS_ALL_USI_PERIPH(USIx));
796 
797 	/* Wait for Uart print out */
798 	while(1) {
799 		if (USIx->TX_FIFO_STATUS & USI_TXFIFO_EMPTY){
800 			break;
801 		}
802 
803 		DelayUs(100);
804 
805 		times++;
806 
807 		if (times > PollTimes)
808 			break;
809 	}
810 }
811 
812 /**
813   * @brief    USI-UART RX timeout configuration .
814   * @param  USIx: where x can be 0.
815   * @param  TimeOutCnt: timeout counter, unit: bit period.
816   * @retval   None
817   */
USI_UARTRxTimeOutConfig(USI_TypeDef * USIx,u32 TimeOutCnt)818 void USI_UARTRxTimeOutConfig(USI_TypeDef* USIx, u32 TimeOutCnt)
819 {
820 	u32 TempReg;
821 
822 	/* Set rx timeout threshold.*/
823 	TempReg = USIx->UART_RXFIFO_TO_TH;
824 	TempReg &= ~(USI_UART_RXFIFO_TO_TH);
825 	TempReg |= TimeOutCnt;
826 
827 	USIx->UART_RXFIFO_TO_TH = TempReg;
828 }
829 
830  /**
831   * @brief    USI UART RX DMA flow control mode configuration .
832   * @param  USIx: where x can be 0
833   * @param  Mode: DMA flow control mode.
834   			This parameter can be: USI_UART_RX_UART_IS_DMA_FLOW_CTRL or USI_UART_RX_GDMA_IS_DMA_FLOW_CTRL.
835   * @retval   None
836   */
USI_UARTRxDMAModeConfig(USI_TypeDef * USIx,u32 Mode)837 void USI_UARTRxDMAModeConfig(USI_TypeDef* USIx, u32 Mode)
838 {
839 	u32 TempReg;
840 
841 	assert_param(IS_USI_UART_RX_DMA_MODE(Mode));
842 
843 	/* Set USI UART RX DMA flow control mode.*/
844 	TempReg = USIx->UART_RXDMA_FLOW_CTRL;
845 	TempReg &= ~(USI_UART_RXDMA_RXDMA_OWNER);
846 	TempReg |= Mode;
847 
848 	USIx->UART_RXDMA_FLOW_CTRL = TempReg;
849 }
850 
851  /**
852   * @brief    USI UART RX DMA dummy data configuration .
853   * @param  USIx: where x can be 0~1.
854   * @param  Byte: dummy data.
855   * @retval   None
856   */
USI_UARTRxDMADummyDataConfig(USI_TypeDef * USIx,u8 Byte)857 void USI_UARTRxDMADummyDataConfig(USI_TypeDef* USIx, u8 Byte)
858 {
859 	u32 TempReg;
860 
861 	/* Set UART RX DMA flow control mode.*/
862 	TempReg = USIx->UART_RXDMA_FLOW_CTRL;
863 	TempReg &= ~(USI_UART_RXDMA_DUMMY_DATA);
864 	TempReg |= (Byte<<8);
865 
866 	USIx->UART_RXDMA_FLOW_CTRL = TempReg;
867 }
868 
869  /**
870   * @brief    Get USI UART RX DMA dummy flag .
871   * @param  USIx: where x can be 0.
872   * @retval   status value:
873 		    - 0: master not read dummy data from rx fifo
874 		    - 1: master read dummy data from rx fifo
875   */
USI_UARTGetRxDMADummyFlag(USI_TypeDef * USIx)876 u32 USI_UARTGetRxDMADummyFlag(USI_TypeDef* USIx)
877 {
878 	if(USIx->UART_RXDMA_FLOW_CTRL & USI_UART_RXDMA_DUMMY_FLAG) {
879 		return 1;
880 	} else {
881 		return 0;
882 	}
883 }
884 
885  /**
886   * @brief    Clear USI UART RX DMA dummy flag .
887   * @param  USIx: where x can be 0.
888   * @retval   None
889   */
USI_UARTRxClearDMADummyFlag(USI_TypeDef * USIx)890 void USI_UARTRxClearDMADummyFlag(USI_TypeDef* USIx)
891 {
892 	USIx->UART_RXDMA_FLOW_CTRL |= USI_UART_RXDMA_DUMMY_FLAG;
893 }
894 
895   /**
896   * @brief    configure USI UART TX DMA burst size .
897   * @param  USIx: where x can be 0.
898   * @param  TxDmaBurstSize: UART TX DMA burst size.
899   * @note     Because UART tx fifo depth is 64 in hardware.
900   *              Therefore this value must be no more than 64.
901   * @retval   None
902   */
USI_UARTTXDMAConfig(USI_TypeDef * USIx,u32 TxDmaBurstSize)903 void USI_UARTTXDMAConfig(USI_TypeDef* USIx, u32 TxDmaBurstSize)
904 {
905 	u32 Temp;
906 
907 	/*check the parameters*/
908 	assert_param(IS_ALL_USI_PERIPH(USIx));
909 
910 	/* Set UART TX DMA burst size.*/
911 	Temp = USIx->DMA_REQ_SIZE;
912 	Temp &= ~(USI_TX_DMA_BURST_SIZE|USI_TX_DMA_SINGLE_SIZE);
913 	Temp |= (TxDmaBurstSize|(1<<8));
914 
915 	USIx->DMA_REQ_SIZE = Temp;
916 }
917 
918   /**
919   * @brief    configure UART RX DMA burst size .
920   * @param  USIx: where x can be 0.
921   * @param  RxDmaBurstSize: UART RX DMA burst size.
922   * @note     Because UART rx fifo depth is 64 in hardare.
923   *              Therefore this value must be no more than 64.
924   * @retval   None
925   */
USI_UARTRXDMAConfig(USI_TypeDef * USIx,u32 RxDmaBurstSize)926 void USI_UARTRXDMAConfig(USI_TypeDef* USIx, u32 RxDmaBurstSize)
927 {
928 	u32 Temp;
929 
930 	/*check the parameters*/
931 	assert_param(IS_ALL_USI_PERIPH(USIx));
932 
933 	/* Set UART RX DMA burst size.*/
934 	Temp = USIx->DMA_REQ_SIZE;
935 	Temp &= ~(USI_RX_DMA_BURST_SIZE|USI_RX_DMA_BURST_SIZE);
936 	Temp |= ((RxDmaBurstSize<<16)|(1<<24));
937 
938 	USIx->DMA_REQ_SIZE = Temp;
939 }
940 
941   /**
942   * @brief    enable or disable USI UART TX DMA .
943   * @param  USIx: where x can be 0.
944   * @param  NewState: the new state of UART TX DMA.
945   *               This parameter can be: ENABLE or DISABLE.
946   * @retval   None
947   */
USI_UARTTXDMACmd(USI_TypeDef * USIx,u32 NewState)948 void USI_UARTTXDMACmd(USI_TypeDef* USIx, u32 NewState)
949 {
950 	/*check the parameters*/
951 	assert_param(IS_ALL_USI_PERIPH(USIx));
952 
953 	if(NewState != DISABLE ){
954 		/* enable the UART TX DMA */
955 		USIx->DMA_ENABLE |= USI_TX_DMA_ENABLE;
956 	} else {
957 		/* disable the UART TX DMA */
958 		USIx->DMA_ENABLE &= (~ USI_TX_DMA_ENABLE);
959 	}
960 }
961 
962   /**
963   * @brief    enable or disable USI UART RX DMA .
964   * @param  USIx: where x can be 0.
965   * @param  NewState: the new state of UART RX DMA.
966   *              This parameter can be: ENABLE or DISABLE.
967   * @retval   None
968   */
USI_UARTRXDMACmd(USI_TypeDef * USIx,u32 NewState)969 void USI_UARTRXDMACmd(USI_TypeDef* USIx, u32 NewState)
970 {
971 	/*check the parameters*/
972 	assert_param(IS_ALL_USI_PERIPH(USIx));
973 
974 	if(NewState != DISABLE ){
975 		/* enable the UART RX DMA */
976 		USIx->DMA_ENABLE |= USI_RX_DMA_ENABLE;
977 	} else {
978 		/* disable the UART RX DMA */
979 		USIx->DMA_ENABLE &= (~ USI_RX_DMA_ENABLE);
980 	}
981 }
982 
983 /**
984   * @brief    Init and Enable USI UART TX GDMA.
985   * @param  USIIndex: 0.
986   * @param  GDMA_InitStruct: pointer to a GDMA_InitTypeDef structure that contains
987   *         the configuration information for the GDMA peripheral.
988   * @param  CallbackData: GDMA callback data.
989   * @param  CallbackFunc: GDMA callback function.
990   * @param  pTxBuf: Tx Buffer.
991   * @param  TxCount: Tx Count.
992   * @retval   TRUE/FLASE
993   */
USI_UARTTXGDMA_Init(u8 USIIndex,GDMA_InitTypeDef * GDMA_InitStruct,void * CallbackData,IRQ_FUN CallbackFunc,u8 * pTxBuf,int TxCount)994 BOOL USI_UARTTXGDMA_Init(
995 	u8 USIIndex,
996 	GDMA_InitTypeDef *GDMA_InitStruct,
997 	void *CallbackData,
998 	IRQ_FUN CallbackFunc,
999 	u8 *pTxBuf,
1000 	int TxCount
1001 	)
1002 {
1003 	u8 GdmaChnl;
1004 
1005 	assert_param(GDMA_InitStruct != NULL);
1006 
1007 	GdmaChnl = GDMA_ChnlAlloc(0, (IRQ_FUN)CallbackFunc, (u32)CallbackData, 12);//ACUT is 0x10, BCUT is 12
1008 	if (GdmaChnl == 0xFF) {
1009 		/*  No Available DMA channel */
1010 		return _FALSE;
1011 	}
1012 
1013 	_memset((void *)GDMA_InitStruct, 0, sizeof(GDMA_InitTypeDef));
1014 
1015 	GDMA_InitStruct->MuliBlockCunt     = 0;
1016 	GDMA_InitStruct->MaxMuliBlock      = 1;
1017 
1018 	GDMA_InitStruct->GDMA_DIR      = TTFCMemToPeri;
1019 	GDMA_InitStruct->GDMA_DstHandshakeInterface   = USI_DEV_TABLE[USIIndex].Tx_HandshakeInterface;
1020 	GDMA_InitStruct->GDMA_DstAddr = (u32)&USI_DEV_TABLE[USIIndex].USIx->TX_FIFO_WRITE;
1021 	GDMA_InitStruct->GDMA_Index   = 0;
1022 	GDMA_InitStruct->GDMA_ChNum       = GdmaChnl;
1023 	GDMA_InitStruct->GDMA_IsrType = (BlockType|TransferType|ErrType);
1024 
1025 	GDMA_InitStruct->GDMA_DstMsize  = MsizeFour;
1026 	GDMA_InitStruct->GDMA_DstDataWidth = TrWidthOneByte;
1027 	GDMA_InitStruct->GDMA_DstInc = NoChange;
1028 	GDMA_InitStruct->GDMA_SrcInc = IncType;
1029 
1030 	if (((TxCount & 0x03)==0) && (((u32)(pTxBuf) & 0x03)==0)) {
1031 		/* 4-bytes aligned, move 4 bytes each transfer */
1032 		GDMA_InitStruct->GDMA_SrcMsize   = MsizeOne;
1033 		GDMA_InitStruct->GDMA_SrcDataWidth = TrWidthFourBytes;
1034 		GDMA_InitStruct->GDMA_BlockSize = TxCount >> 2;
1035 	} else {
1036 		/* move 1 byte each transfer */
1037 		GDMA_InitStruct->GDMA_SrcMsize   = MsizeFour;
1038 		GDMA_InitStruct->GDMA_SrcDataWidth = TrWidthOneByte;
1039 		GDMA_InitStruct->GDMA_BlockSize = TxCount;
1040 	}
1041 
1042 	assert_param(GDMA_InitStruct->GDMA_BlockSize < 4096);
1043 
1044 	GDMA_InitStruct->GDMA_SrcAddr = (u32)(pTxBuf);
1045 
1046 	GDMA_Init(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum, GDMA_InitStruct);
1047 	GDMA_Cmd(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum, ENABLE);
1048 
1049 	return _TRUE;
1050 }
1051 
1052 /**
1053   * @brief    Init and Enable UART RX GDMA.
1054   * @param  USIIndex: 0.
1055   * @param  GDMA_InitStruct: pointer to a GDMA_InitTypeDef structure that contains
1056   *         the configuration information for the GDMA peripheral.
1057   * @param  CallbackData: GDMA callback data.
1058   * @param  CallbackFunc: GDMA callback function.
1059   * @param  pRxBuf: Rx Buffer.
1060   * @param  RxCount: Rx Count.
1061   * @retval   TRUE/FLASE
1062   */
USI_UARTRXGDMA_Init(u8 USIIndex,GDMA_InitTypeDef * GDMA_InitStruct,void * CallbackData,IRQ_FUN CallbackFunc,u8 * pRxBuf,int RxCount)1063 BOOL USI_UARTRXGDMA_Init(
1064 	u8 USIIndex,
1065 	GDMA_InitTypeDef *GDMA_InitStruct,
1066 	void *CallbackData,
1067 	IRQ_FUN CallbackFunc,
1068 	u8 *pRxBuf,
1069 	int RxCount
1070 	)
1071 {
1072 	u8 GdmaChnl;
1073 
1074 	assert_param(GDMA_InitStruct != NULL);
1075 
1076 	GdmaChnl = GDMA_ChnlAlloc(0, (IRQ_FUN)CallbackFunc, (u32)CallbackData, 12);//ACUT is 0x10, BCUT is 12
1077 	if (GdmaChnl == 0xFF) {
1078 		/* No Available DMA channel */
1079 		return _FALSE;
1080 	}
1081 
1082 	_memset((void *)GDMA_InitStruct, 0, sizeof(GDMA_InitTypeDef));
1083 
1084 	GDMA_InitStruct->GDMA_DIR      = TTFCPeriToMem;
1085 	GDMA_InitStruct->GDMA_ReloadSrc = 1;
1086 	GDMA_InitStruct->GDMA_SrcHandshakeInterface = USI_DEV_TABLE[USIIndex].Rx_HandshakeInterface;
1087 	GDMA_InitStruct->GDMA_SrcAddr = (u32)&USI_DEV_TABLE[USIIndex].USIx->RX_FIFO_READ;
1088 	GDMA_InitStruct->GDMA_Index   = 0;
1089 	GDMA_InitStruct->GDMA_ChNum       = GdmaChnl;
1090 	GDMA_InitStruct->GDMA_IsrType = (BlockType|TransferType|ErrType);
1091 	GDMA_InitStruct->GDMA_SrcMsize   = MsizeFour;
1092 	GDMA_InitStruct->GDMA_SrcDataWidth = TrWidthOneByte;
1093 	GDMA_InitStruct->GDMA_DstInc = IncType;
1094 	GDMA_InitStruct->GDMA_SrcInc = NoChange;
1095 
1096 	if (((u32)(pRxBuf) & 0x03)==0) {
1097 		/*  4-bytes aligned, move 4 bytes each DMA transaction */
1098 		GDMA_InitStruct->GDMA_DstMsize   = MsizeOne;
1099 		GDMA_InitStruct->GDMA_DstDataWidth = TrWidthFourBytes;
1100 	} else {
1101 		/*  move 1 byte each DMA transaction */
1102 		GDMA_InitStruct->GDMA_DstMsize   = MsizeFour;
1103 		GDMA_InitStruct->GDMA_DstDataWidth = TrWidthOneByte;
1104 	}
1105 	GDMA_InitStruct->GDMA_BlockSize = RxCount;
1106 	GDMA_InitStruct->GDMA_DstAddr = (u32)(pRxBuf);
1107 
1108 	assert_param(GDMA_InitStruct->GDMA_BlockSize < 4096);
1109 
1110 	/* multi block close */
1111 	GDMA_InitStruct->MuliBlockCunt     = 0;
1112 	GDMA_InitStruct->GDMA_ReloadSrc = 0;
1113 	GDMA_InitStruct->MaxMuliBlock = 1;
1114 
1115 	GDMA_Init(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum, GDMA_InitStruct);
1116 	GDMA_Cmd(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum, ENABLE);
1117 
1118 	return _TRUE;
1119 }
1120 
1121 /**
1122   * @brief  Fills USI_LPUARTInitStruct member low power rx path related with its default value.
1123   * @param  USI_LPUARTInitStruct: pointer to an USI_LPUARTInitTypeDef structure which will be initialized.
1124   * @retval None
1125   */
USI_UARTLPRxStructInit(USI_LPUARTInitTypeDef * USI_LPUARTInitStruct)1126 void USI_UARTLPRxStructInit(USI_LPUARTInitTypeDef* USI_LPUARTInitStruct)
1127 {
1128 	/* USI_LPUARTInitStruct members default value */
1129 	USI_LPUARTInitStruct->USI_LPUARTBitNumThres  = 100;
1130 	USI_LPUARTInitStruct->USI_LPUARTOscPerbitUpdCtrl = ENABLE;
1131 }
1132 
1133 /**
1134   * @brief    Initializes the the UART Low Power RX path peripheral according to the specified
1135   *              parameters in the USI_LPUARTInitStruct.
1136   * @param  USIx: where x can be 0.
1137   * @param  USI_LPUARTInitStruct: pointer to an USI_LPUARTInitTypeDef structure which has been configured.
1138   * @note    Initial UART Low Power Rx path  steps:
1139   *              - step1:  Reset Low Power Rx Path.
1140   *              - step2:  Configure bit number threshold of one monitor period.
1141   *              - step3:  Configure the update OSC cycnum_perbit bit.
1142   * @retval   None
1143   */
USI_UARTLPRxInit(USI_TypeDef * USIx,USI_LPUARTInitTypeDef * USI_LPUARTInitStruct)1144 void USI_UARTLPRxInit(USI_TypeDef* USIx, USI_LPUARTInitTypeDef *USI_LPUARTInitStruct)
1145 {
1146 	u32 RegValue = 0;
1147 
1148 	/*check the parameters*/
1149 	assert_param(IS_ALL_USI_LP_PERIPH(USIx));
1150 	assert_param((USI_LPUARTInitStruct->USI_LPUARTBitNumThres>0) && (USI_LPUARTInitStruct->USI_LPUARTBitNumThres<128));
1151 
1152 	/* Step 1: Reset Low Power Rx Path */
1153 	USIx->SW_RESET &= (~USI_SW_RESET_RX_RSTB);
1154 
1155 	RegValue = USIx->UART_BAUD_MON_CTRL;
1156 
1157 	/*step 2: Configure bit number threshold of one monitor period.*/
1158 	RegValue &= (~ USI_UART_LP_RX_BIT_NUM_THRES);
1159 	RegValue |= (USI_LPUARTInitStruct->USI_LPUARTBitNumThres << 8);
1160 
1161 	/*step 3: Configure the OSC cycnum_perbit update bit*/
1162 	if(USI_LPUARTInitStruct->USI_LPUARTOscPerbitUpdCtrl != DISABLE){
1163 		/*enable OSC cycnum_perbit update*/
1164 		RegValue |= USI_UART_LP_RX_OSC_UPD_IN_XTAL;
1165 	} else {
1166 		/*disable OSC cycnum_perbit update*/
1167 		RegValue &= ~ USI_UART_LP_RX_OSC_UPD_IN_XTAL;
1168 	}
1169 	USIx->UART_BAUD_MON_CTRL = RegValue;
1170 }
1171 
1172 /**
1173   * @brief    set uart baud rate of low power rx path
1174   * @param  USIx: where x can be 0.
1175   * @param  BaudRate: the desired baud rate
1176   * @param  RxIPClockHz: the uart rx clock. unit: [Hz]
1177   * @note    according to the baud rate calculation formlula in low power rx path, method
1178   *              implemented is as follows:
1179   *                                 - CycPerbit = round( fpclock/BaudRate)
1180   * @retval  None
1181   */
USI_UARTLPRxBaudSet(USI_TypeDef * USIx,u32 BaudRate,u32 RxIPClockHz)1182 void USI_UARTLPRxBaudSet(USI_TypeDef* USIx, u32 BaudRate, u32 RxIPClockHz)
1183 {
1184 	u32 CycPerbit = 0;
1185 	u32 RegValue = 0;
1186 	u32 RegOscBaud = 0;
1187 
1188 	/*check the parameters*/
1189 	assert_param(IS_ALL_USI_LP_PERIPH(USIx));
1190 	assert_param((BaudRate > 0 && BaudRate <= 500000));
1191 
1192 	/*Calculate the r_cycnum_perbit field,
1193 	   according to clock and the desired baud rate*/
1194 	if((RxIPClockHz % BaudRate) >= (BaudRate + 1) / 2){
1195 		CycPerbit = RxIPClockHz / BaudRate + 1;
1196 	} else {
1197 		CycPerbit = RxIPClockHz / BaudRate;
1198 	}
1199 
1200 	/* Average clock cycle number of XTAL clock. */
1201 	RegValue = USIx->UART_RX_BAUD_XTAL;
1202 
1203 	RegValue &= (~ USI_RUART_LPRX_XTAL_CYCNUM_PERBIT);
1204 	RegValue |= CycPerbit;
1205 
1206 	/* set XTAL CycPerbit */
1207 	USIx->UART_RX_BAUD_OSC= RegValue;
1208 
1209 	/* Average clock cycle number of one bit OSC. */
1210 	RegOscBaud = USIx->UART_RX_BAUD_OSC;
1211 	RegOscBaud &= (~ USI_UART_LPRX_OSC_CYCNUM_PERBIT);
1212 	RegOscBaud |= CycPerbit;
1213 
1214 	/*set the OSC CycPerbit*/
1215 	USIx->UART_RX_BAUD_OSC = RegOscBaud;
1216 
1217 	/*set uart_rxbaud_adj = 0*/
1218 	USIx->UART_RX_FRACTION_BAUD_CTRL &= (~USI_UART_RX_XFACTOR_ADJ);
1219 }
1220 
1221 /**
1222   * @brief    enable or disable the monitor function in Low Power Rx Path.
1223   * @param  USIx: where x can be 0.
1224   * @param  NewState: the new state of monitoring.
1225   *              This parameter can be: ENABLE or DISABLE.
1226   * @retval None
1227   */
USI_UARTLPRxMonitorCmd(USI_TypeDef * USIx,u32 NewState)1228 void USI_UARTLPRxMonitorCmd(USI_TypeDef* USIx, u32 NewState)
1229 {
1230 	/*check the parameters*/
1231 	assert_param(IS_ALL_USI_LP_PERIPH(USIx));
1232 
1233 	/* configure Low Power rx monitoring function*/
1234 	if(NewState != DISABLE ){
1235 		/* Function enable of monitoring rx baud */
1236 		USIx->UART_BAUD_MON_CTRL |= USI_UART_LP_RX_MON_ENABLE;
1237 	} else {
1238 		/* Function disable of monitoring rx baud */
1239 		USIx->UART_BAUD_MON_CTRL &= (~ USI_UART_LP_RX_MON_ENABLE);
1240 	}
1241 }
1242 
1243 /**
1244   * @brief    select uart rx path.
1245   * @param  USIx: where x can be 0.
1246   * @param  LPRxpath: the new state of uart rx path.
1247   *              This parameter can be: ENABLE or DISABLE.
1248   *              DISABLE is high rate rx path, ENABLE is low power rx path
1249   * @retval  None
1250   */
USI_UARTLPRxpathSet(USI_TypeDef * USIx,u32 LPRxpath)1251 void USI_UARTLPRxpathSet(USI_TypeDef* USIx, u32 LPRxpath)
1252 {
1253 	/* To avoid gcc warnings */
1254 	( void ) USIx;
1255 	( void ) LPRxpath;
1256 	/*AmebaZ's API, AmebaD doesn't use this API any more; this API is reserved for compatibility with AmebaZ*/
1257 }
1258 
1259 /**
1260   * @brief    Configure USI UART RX Clock.
1261   * @param  USIx: where x can be 0.
1262   * @param  RxClock:  This parameter can be one of the following values:
1263   * @retval   None
1264   * @note    USI V01(Ameba-D) not support this function.
1265   */
USI_UARTLPRxIPClockSet(USI_TypeDef * USIx,u32 RxIPClock)1266 void USI_UARTLPRxIPClockSet(USI_TypeDef* USIx, u32 RxIPClock)
1267 {
1268 	/* To avoid gcc warnings */
1269 	( void ) RxIPClock;
1270 
1271 	/* Check the parameters */
1272 	assert_param(IS_ALL_USI_PERIPH(USIx));
1273 	//assert_param(IS_USI_UART_RX_CLK(RxIPClock));
1274 
1275 	/* not support */
1276 }
1277 
1278 /**
1279   * @brief    enable or disable Uart Low Power Rx Path
1280   * @param  USIx: where x can be 0.
1281   * @param  NewState: the new state of the Rx Path.
1282   *              This parameter can be: ENABLE or DISABLE.
1283   * @note    Because the TX/RX of the IrDA transceiver are in the same module,
1284   *              RX fifo can also receive available data when in the process of TX.Therefore,
1285   *              the RX Path must be disabled when TX is going on.Namely, IrDA must work
1286   *              in the Half duplex mode, though normal UART IP supports Full duplex.
1287   * @retval None
1288   */
USI_UARTLPRxCmd(USI_TypeDef * USIx,u32 NewState)1289 void USI_UARTLPRxCmd(USI_TypeDef* USIx, u32 NewState)
1290 {
1291 
1292 	/*check the parameters*/
1293 	assert_param(IS_ALL_USI_LP_PERIPH(USIx));
1294 
1295 	if (NewState != DISABLE) {
1296 		/*enable uart receiver*/
1297 		USIx->SW_RESET |= USI_SW_RESET_RX_RSTB;
1298 	} else {
1299 		/*disable uart receiver*/
1300 		USIx->SW_RESET &= (~USI_SW_RESET_RX_RSTB);
1301 	}
1302 }
1303 
1304 /**
1305   * @brief    Fills each IrDA_InitStruct member with its default value.
1306   * @param  IrDA_InitStruct : pointer to a USI_UartIrDAInitTypeDef
1307   *              structure which will be initialized.
1308   * @retval   None
1309   */
USI_UARTIrDAStructInit(USI_UartIrDAInitTypeDef * IrDA_InitStruct)1310 void USI_UARTIrDAStructInit(USI_UartIrDAInitTypeDef * IrDA_InitStruct)
1311 {
1312 	/* Set the default value */
1313 	IrDA_InitStruct->USI_UARTIrDARxInv = DISABLE;
1314 	IrDA_InitStruct->USI_UARTIrDATxInv = DISABLE;
1315 	IrDA_InitStruct->USI_UARTLowShift = USI_UART_IRDA_PULSE_LEFT_SHIFT;
1316 	IrDA_InitStruct->USI_UARTLowShiftVal = 0;
1317 	IrDA_InitStruct->USI_UARTUpperShift = USI_UART_IRDA_PULSE_LEFT_SHIFT;
1318 	IrDA_InitStruct->USI_UARTUpperShiftVal = 0;
1319 	IrDA_InitStruct->USI_UARTRxFilterCmd = ENABLE;
1320 	IrDA_InitStruct->USI_UARTRxFilterThres = 7;
1321 }
1322 
1323 /**
1324   * @brief    Configures the USI UART's IrDA interface .
1325   * @param  USIx: where x can be 0.
1326   * @param  IrDA_InitStruct: pointer to a USI_UartIrDAInitTypeDef structure that contains
1327   *              the configuration information for the IrDA module.
1328   * @note    the details of IrDA_InitStruct members are:
1329   * @verbatim
1330   *	           IrDA_InitStruct-> USI_UARTIrDARxInv:
1331   *				IrDA Rx invert bit:
1332   *                 		ENABLE: invert irda rx
1333   *                 		DISABLE: not invert irda rx
1334   *
1335   *	           IrDA_InitStruct->USI_UARTIrDATxInv:
1336   *				IrDA Tx invert bit:
1337   *                 		ENABLE: invert irda tx
1338   *                 		DISABLE: not invert irda tx
1339   *
1340   *	           IrDA_InitStruct->USI_UARTUpperShift:
1341   *			 	Upperbound(right edge) Shift direction:
1342   *			 		UART_IRDA_PULSE_LEFT_SHIFT: shift left
1343   *                 		UART_IRDA_PULSE_RIGHT_SHIFT: shift right
1344   *	           IrDA_InitStruct->UpperShiftVal:
1345   *				Upperbound Shift value
1346   *
1347   *	           IrDA_InitStruct->USI_UARTLowShift:
1348   *				Lowbound(left edge) Shift direction:
1349   *			 		UART_IRDA_PULSE_LEFT_SHIFT: shift left
1350   *                 		UART_IRDA_PULSE_RIGHT_SHIFT: shift right
1351   *	           IrDA_InitStruct->USI_UARTLowShiftVal:
1352   *				Lowbound Shift value
1353   *
1354   *	           IrDA_InitStruct->USI_UARTRxFilterThres:
1355   *				IrDA RX filter threshold
1356   *
1357   *	           IrDA_InitStruct->USI_UARTRxFilterCmd:
1358   *				IrDA RX filter enable or disable:
1359   *                 		ENABLE: enable IrDA rx filter
1360   *                 		DISABLE: disable IrDA rx filter
1361   * @endverbatim
1362   * @retval   None
1363   */
USI_UARTIrDAInit(USI_TypeDef * USIx,USI_UartIrDAInitTypeDef * IrDA_InitStruct)1364 void USI_UARTIrDAInit(USI_TypeDef* USIx, USI_UartIrDAInitTypeDef * IrDA_InitStruct)
1365 {
1366 	u32 TempCtrl;
1367 	u32 TempTxpulse;
1368 	u32 TempRxPulse;
1369 
1370 	/*check the parameters*/
1371 	assert_param(IS_ALL_USI_PERIPH(USIx));
1372 	assert_param(IrDA_InitStruct->USI_UARTUpperShiftVal <= 0x7fff );
1373 	assert_param(IrDA_InitStruct->USI_UARTLowShiftVal <= 0x7fff);
1374 	assert_param(IS_USI_IRDA_PUL_SHIFT(IrDA_InitStruct->USI_UARTLowShift));
1375 	assert_param(IS_USI_IRDA_PUL_SHIFT(IrDA_InitStruct->USI_UARTUpperShift));
1376 	assert_param((IrDA_InitStruct->USI_UARTRxFilterThres <= 0x7fff));
1377 
1378 	/*Get the UART_IRDA_CTRL register value*/
1379 	TempCtrl = USIx->UART_IRDA_CTRL;
1380 
1381 	/*configure the IrDA RX invert bit*/
1382 	if(IrDA_InitStruct->USI_UARTIrDARxInv != DISABLE){
1383 		/*invert the irda_rx_i*/
1384 		TempCtrl |= USI_UART_IRDA_RX_INV;
1385 	} else {
1386 		/*not invert the irda_rx_i*/
1387 		TempCtrl &= (~ USI_UART_IRDA_RX_INV);
1388 	}
1389 
1390 	/*configure the IrDA TX invert bit*/
1391 	if(IrDA_InitStruct->USI_UARTIrDATxInv != DISABLE){
1392 		/*invert the irda_tx_o*/
1393 		TempCtrl |= USI_UART_IRDA_TX_INV;
1394 	} else {
1395 		/*not invert the irda_tx_o*/
1396 		TempCtrl &= (~ USI_UART_IRDA_TX_INV);
1397 	}
1398 	USIx->UART_IRDA_CTRL = TempCtrl;
1399 
1400 	/*Get the UART_IRDA_TX_PULSE_WD register value*/
1401 	TempTxpulse = USIx->UART_IRDA_TX_PULSE_WD;
1402 
1403 	/*configure IrDA SIR TX Pulse Width*/
1404 	/*configure Upperbound(right edge) shift direction*/
1405 	TempTxpulse &= (~ USI_UART_IRDA_TX_PUL_UP_BUND_SHIFT);
1406 	TempTxpulse |= (IrDA_InitStruct->USI_UARTUpperShift << 31);
1407 
1408 	/*configure the Upperbound shift value*/
1409 	TempTxpulse &= (~ USI_UART_IRDA_TX_PUL_UP_BUND_VAL);
1410 	TempTxpulse |= (IrDA_InitStruct->USI_UARTUpperShiftVal << 16);
1411 
1412 	/*configure Lowbound(left edge) shift direction*/
1413 	TempTxpulse &= (~ USI_UART_IRDA_TX_PUL_LOW_BUND_SHIFT);
1414 	TempTxpulse |= (IrDA_InitStruct->USI_UARTLowShift << 15);
1415 
1416 	/*configure the Lowbound shift value*/
1417 	TempTxpulse &= (~ USI_UART_IRDA_TX_PUL_LOW_BUND_VAL);
1418 	TempTxpulse |= (IrDA_InitStruct->USI_UARTLowShiftVal);
1419 
1420 	USIx->UART_IRDA_TX_PULSE_WD = TempTxpulse;
1421 
1422 	/*Get the RXPLSR register value*/
1423 	TempRxPulse = USIx->UART_IRDA_RX_PULSE_WD;
1424 
1425 	/*configure IrDA RX filter threshold*/
1426 	TempRxPulse &= (~ USI_UART_IRDA_RX_FILTER_THRES);
1427 	TempRxPulse |= (IrDA_InitStruct->USI_UARTRxFilterThres << 1);
1428 
1429 	if(IrDA_InitStruct->USI_UARTRxFilterCmd != DISABLE){
1430 		/*enable IrDA rx filter*/
1431 		TempRxPulse |= USI_UART_IRDA_RX_FILTER_ENABLE;
1432 	} else {
1433 		/*disable IrDA rx filter*/
1434 		TempRxPulse &= (~ USI_UART_IRDA_RX_FILTER_ENABLE);
1435 	}
1436 
1437 	USIx->UART_IRDA_RX_PULSE_WD = TempRxPulse;
1438 }
1439 
1440 /**
1441   * @brief    enable or disable the IrDA function.
1442   * @param  USIx: where x can be 0.
1443   * @param  NewState: the new state of the IrDA.
1444   *              This parameter can be: ENABLE or DISABLE.
1445   * @retval   None
1446   */
USI_UARTIrDACmd(USI_TypeDef * USIx,u32 NewState)1447 void USI_UARTIrDACmd(USI_TypeDef* USIx, u32 NewState)
1448 {
1449 	/*check the parameters*/
1450 	assert_param(IS_ALL_USI_PERIPH(USIx));
1451 
1452 	if(NewState != DISABLE ){
1453 		/* enable the IrDA */
1454 		USIx->UART_IRDA_CTRL|= USI_UART_IRDA_ENABLE;
1455 	} else {
1456 		/* disable the IrDA */
1457 		USIx->UART_IRDA_CTRL &= (~ USI_UART_IRDA_ENABLE);
1458 	}
1459 }
1460 /******************* (C) COPYRIGHT 2017 Realtek Semiconductor *****END OF FILE****/
1461