1 /*
2  * Copyright (c) 2006-2020, YICHIP Development Team
3  * @file     yc_uart.c
4  * @brief    source file for setting uart
5  *
6  * Change Logs:
7  * Date            Author             Version        Notes
8  * 2020-11-06      wushengyan         V1.0.0         the first version
9  */
10 
11 #include "yc_uart.h"
12 
13 #define uart_DMA_buf_len    1024
14 const UART_TypeDef * const UARTs[] = {MUART0, MUART1, MUART2, MUART3};
15 uint8_t uart0_DMA_buf[uart_DMA_buf_len] = {0};
16 uint8_t uart1_DMA_buf[uart_DMA_buf_len] = {0};
17 uint8_t uart2_DMA_buf[uart_DMA_buf_len] = {0};
18 uint8_t uart3_DMA_buf[uart_DMA_buf_len] = {0};
19 
20 #define RX_ENABLE           BIT0
21 #define UART_DMA_ENABLE     BIT31
22 #define TX_INTR_ENABLE      BIT31
23 #define Set_RxITNum_Mask    0xff00
24 #define Statu_RxNum_Mask    (uint32_t)0xffff0000
25 
26 /**
27  * @method UART_Buffer_Select
28  * @brief  select UART buffer
29  * @param  UARTx: Select the UART peripheral.
30  *         This parameter can be one of the following values:
31  *         MUART0, MUART1, MUART2 or MUART3.
32  * @retval NULL
33  */
UART_Buffer_Select(UART_TypeDef * UARTx)34 static uint8_t *UART_Buffer_Select(UART_TypeDef *UARTx)
35 {
36     _ASSERT(IS_UART(UARTx));
37     uint8_t *buffers[] = {uart0_DMA_buf, uart1_DMA_buf, uart2_DMA_buf, uart3_DMA_buf};
38 
39     for (int i = 0; i < sizeof(UARTs) / sizeof(UARTs[0]); i++)
40     {
41         if ((void *)UARTs[i] == (void *)UARTx)
42         {
43             return buffers[i];
44         }
45     }
46     return NULL;
47 }
48 
49 /**
50  * @method UART_DeInit
51  * @brief  DeInit UART
52  * @param  UARTx: Select the UART peripheral.
53  *         This parameter can be one of the following values:
54  *         MUART0, MUART1, MUART2 or MUART3.
55  * @retval None
56  */
UART_DeInit(UART_TypeDef * UARTx)57 void UART_DeInit(UART_TypeDef *UARTx)
58 {
59     _ASSERT(IS_UART(UARTx));
60     UARTx->CTRL.reg = 0;
61     UARTx->RX_INT_LEN.reg = 0;
62 }
63 
64 /**
65  * @method UART_Init
66  * @brief  Initializes the UARTx peripheral according to
67  *         the specified parameters.
68  * @param  UARTx: Select the UART peripheral.
69  *         This parameter can be one of the following values:
70  *         MUART0, MUART1, MUART2 or MUART3.
71  * @param  UART_InitStruct: pointer to a UART_InitTypeDef structure that
72  *         contains the configuration information.
73  */
UART_Init(UART_TypeDef * UARTx,UART_InitTypeDef * UART_InitStruct)74 void UART_Init(UART_TypeDef *UARTx, UART_InitTypeDef *UART_InitStruct)
75 {
76     DMA_TypeDef *DMAx = NULL;
77     uint8_t *uartx_DMA_buf = NULL;
78     uint32_t temp_baudrate = 0;
79 
80     _ASSERT(IS_UART(UARTx));
81     _ASSERT(IS_UART_RX_MODE(UART_InitStruct->RxMode));
82     _ASSERT(IS_UART_PARITY(UART_InitStruct->Parity));
83     _ASSERT(IS_UART_WORD_LENGTH(UART_InitStruct->DataBits));
84     _ASSERT(IS_UART_STOPBITS(UART_InitStruct->StopBits));
85     _ASSERT(IS_UART_FLOW_CTRL(UART_InitStruct->FlowCtrl));
86     _ASSERT(IS_UART_SMART_CARD(UART_InitStruct->SmartCard));
87     _ASSERT(IS_UART_COMM_MODE(UART_InitStruct->CommMode));
88     _ASSERT(IS_UART_BAUDRATE(UART_InitStruct->BaudRate));
89 
90     DMAx = (DMA_TypeDef *)((uint32_t)UARTx - sizeof(DMA_TypeDef));
91     uartx_DMA_buf = UART_Buffer_Select(UARTx);
92     temp_baudrate = (48000000 / UART_InitStruct->BaudRate);
93 
94     UART_DeInit(UARTx);
95     DMAx->DEST_ADDR.reg               = (uint32_t)uartx_DMA_buf;
96     DMAx->LEN_LOW.bit.RX_LEN_L        = uart_DMA_buf_len;
97     DMAx->CTRL.bit.LOOPBACK           = 1;
98     DMAx->CTRL.bit.RESET              = 1;
99     DMAx->CTRL.bit.RESET              = 0;
100 
101     UARTx->CTRL.bit.RX_EN           = UART_InitStruct->RxMode;
102     UARTx->CTRL.bit.PARITY          = UART_InitStruct->Parity;
103     UARTx->CTRL.bit.DATA_BITS       = UART_InitStruct->DataBits;
104     UARTx->CTRL.bit.STOP_BITS       = UART_InitStruct->StopBits;
105     UARTx->CTRL.bit.FLOW_CTRL       = UART_InitStruct->FlowCtrl;
106     UARTx->CTRL.bit.SMART_CARD      = UART_InitStruct->SmartCard;
107     UARTx->CTRL.bit.HDX_EN          = UART_InitStruct->CommMode;
108     UARTx->CTRL.bit.RESET_BAUD      = ENABLE;
109     UARTx->BAUD.bit.BAUD_RATE       = temp_baudrate;
110 }
111 
112 /**
113  * @method UART_StructInit
114  * @brief  Fills each USART_InitStruct member with its default value.
115  * @param  USART_InitStruct: pointer to a USART_InitTypeDef structure
116  *         which will be initialized.
117  * @retval None
118  */
UART_StructInit(UART_InitTypeDef * UART_InitStruct)119 void UART_StructInit(UART_InitTypeDef *UART_InitStruct)
120 {
121     UART_InitStruct->BaudRate  = 9600;
122     UART_InitStruct->RxMode    = MODE_RX_ENABLE;
123     UART_InitStruct->Parity    = YC_PARITY_NONE;
124     UART_InitStruct->DataBits  = DATABITS_8B;
125     UART_InitStruct->StopBits  = STOPBITS_1;
126     UART_InitStruct->FlowCtrl  = FLOWCTRL_NONE;
127     UART_InitStruct->SmartCard = SMARTCARD_DISABLE;
128     UART_InitStruct->CommMode  = MODE_DUPLEX;
129 }
130 
131 /**
132  * @method UART_ITConfig
133  * @brief  Enable or disable the specified UART interrupt.
134  * @param  UARTx: Select the UART peripheral.
135  *         This parameter can be one of the following values:
136  *         MUART0, MUART1, MUART2 or MUART3.
137  * @param  UART_IT: specifies the UART interrupt sources
138  *         This parameter can be one of the following values:
139  *     @arg UART_IT_TX:interrupt trigger after send data completed.
140  *     @arg UART_IT_RX:interrupt trigger when received data.
141  * @param  NewState: new state of the specified UART interrupt
142  *          This parameter can be ENABLE or DISABLE
143  */
UART_ITConfig(UART_TypeDef * UARTx,uint32_t UART_IT,FunctionalState NewState)144 void UART_ITConfig(UART_TypeDef *UARTx, uint32_t UART_IT, FunctionalState NewState)
145 {
146     _ASSERT(IS_UART(UARTx));
147     _ASSERT(IS_UART_IT(UART_IT));
148 
149     if (UART_IT == UART_IT_TX)
150     {
151         UARTx->BAUD.bit.TX_INT_EN = NewState;
152     }
153     else if (UART_IT == UART_IT_RX)
154     {
155         UARTx->RX_INT_LEN.bit.VAL = NewState;
156     }
157 }
158 
159 /**
160  * @method UART_SendData
161  * @brief  UART Send One Data
162  * @param  UARTx: Select  the UART peripheral.
163  *         This parameter can be one of the following values:
164  *         MUART0, MUART1, MUART2 or MUART3.
165  * @retval None
166  */
UART_SendData(UART_TypeDef * UARTx,uint8_t Data)167 void UART_SendData(UART_TypeDef *UARTx, uint8_t Data)
168 {
169     _ASSERT(IS_UART(UARTx));
170 
171     volatile uint8_t buf[1];
172 
173     buf[0] = Data;
174     DMA_TypeDef *DMAx                    = (DMA_TypeDef *)((uint32_t)UARTx - sizeof(DMA_TypeDef));
175     DMAx->SRC_ADDR.reg                   = (uint32_t)buf;
176     DMAx->LEN_LOW.bit.TX_LEN_L           = 1;
177     DMAx->CTRL.bit.START                 = 1;
178 
179     while (DMAx->STATUS.bit.DONE != 1);
180 }
181 
182 /**
183  * @method UART_SendBuf
184  * @brief  Transmits datas via UART DMA, the function will return after datas is sent.
185  * @param  USARTx: Select the USART or the UART peripheral.
186  *         This parameter can be one of the following values:
187  *         MUART0, MUART1, MUART2 or MUART3.
188  * @param  buf: pointer to a buf that contains the data you want transmit.
189  * @param  len: the buf length
190  * @retval None
191  */
UART_SendBuf(UART_TypeDef * UARTx,uint8_t * buf,uint32_t len)192 void UART_SendBuf(UART_TypeDef *UARTx, uint8_t *buf, uint32_t len)
193 {
194     _ASSERT(IS_UART(UARTx));
195     _ASSERT(NULL != buf);
196     _ASSERT(len < 0xfffff);
197 
198     DMA_TypeDef *DMAx                = (DMA_TypeDef *)((uint32_t)UARTx - sizeof(DMA_TypeDef));
199     DMAx->SRC_ADDR.reg               = (uint32_t)buf;
200     DMAx->LEN_LOW.bit.TX_LEN_L       = len & 0xffff;
201     DMAx->CTRL.bit.TX_LEN_H          = len >> 16;
202     DMAx->CTRL.bit.START             = 1;
203 
204     while (DMAx->STATUS.bit.DONE != 1);
205 }
206 
207 /**
208  * @method UART_ReceiveData
209  * @brief  Receive single data through the USARTx peripheral.
210  * @param  USARTx: Select the USART or the UART peripheral.
211  *         This parameter can be one of the following values:
212  *         MUART0, MUART1, MUART2 or MUART3.
213  * @retval An one byte received data.
214  */
UART_ReceiveData(UART_TypeDef * UARTx)215 uint8_t UART_ReceiveData(UART_TypeDef *UARTx)
216 {
217     _ASSERT(IS_UART(UARTx));
218 
219     return UARTx->RX_DATA.bit.VAL;
220 
221 }
222 
223 /**
224  * @method UART_ReceiveBuf
225  * @brief  Receives datas through the UART DMA.
226  * @param  USARTx: Select the USART or the UART peripheral.
227  *         This parameter can be one of the following values:
228  *         MUART0, MUART1, MUART2 or MUART3.
229  * @param  buf: pointer to a buf that contains the data you want receive.
230  * @param  len: the buf length, which size should be less than 20 bit (len < 0xfffff)
231  * @retval The length of received data before return.
232  */
UART_ReceiveBuf(UART_TypeDef * UARTx,uint8_t * buf,uint32_t len)233 uint32_t UART_ReceiveBuf(UART_TypeDef *UARTx, uint8_t *buf, uint32_t len)
234 {
235     _ASSERT(IS_UART(UARTx));
236     _ASSERT(NULL != buf);
237     _ASSERT(len < 0xfffff);
238 
239     uint32_t rcv_len = 0;
240     while ((UART_ReceiveDataLen(UARTx) > 0) && (rcv_len < len))
241     {
242         buf[rcv_len++] = UARTx->RX_DATA.bit.VAL;
243     }
244 
245     return rcv_len;
246 }
247 
248 /**
249  * @method UART_AutoFlowCtrlCmd
250  * @brief  ENABLE or DISABLE UARTx auto flow control
251  * @param  USARTx: Select the USART or the UART peripheral.
252  *         This parameter can be one of the following values:
253  *         MUART0, MUART1, MUART2 or MUART3.
254  * @param  NewState: ENABLE or DISABLE auto flow control
255  * @retval None
256  */
UART_AutoFlowCtrlCmd(UART_TypeDef * UARTx,FunctionalState NewState)257 void UART_AutoFlowCtrlCmd(UART_TypeDef *UARTx, FunctionalState NewState)
258 {
259     _ASSERT(IS_UART(UARTx));
260 
261     UARTx->CTRL.bit.FLOW_CTRL = NewState;
262 }
263 
264 /**
265  * @method UART_GetITIdentity
266  * @brief  Get IT Identity
267  * @param  UARTx: Select the UART peripheral.
268  *         This parameter can be one of the following values:
269  *         MUART0, MUART1, MUART2 or MUART3.
270  * @retval IT Identity
271  */
UART_GetITIdentity(UART_TypeDef * UARTx)272 uint8_t UART_GetITIdentity(UART_TypeDef *UARTx)
273 {
274     _ASSERT(IS_UART(UARTx));
275     //return (0 || (UARTx->BAUD.bit.TX_INT_EN) || (UARTx->RX_INT_LEN.bit.VAL));
276     if((UARTx->RX_INT_LEN.reg > 0)&& (UARTx->STATUS.bit.RX_ITEMS_L >=UARTx->RX_INT_LEN.reg))
277     {
278         return UART_IT_RX;
279     }
280     else if(UARTx->BAUD.bit.TX_INT_EN)
281     {
282         return UART_IT_TX;
283     }
284     return 0;
285 }
286 
287 /**
288  * @method UART_IsRXFIFOFull
289  * @brief  Check if the Rx fifo is full or not.
290  * @param  UARTx: Select the UART peripheral.
291  *         This parameter can be one of the following values:
292  *         MUART0, MUART1, MUART2 or MUART3.
293  * @retval TRUE:  Rx fifo is full.
294  *         FALSE: Rx fifo is not full
295  */
UART_IsRXFIFOFull(UART_TypeDef * UARTx)296 Boolean UART_IsRXFIFOFull(UART_TypeDef *UARTx)
297 {
298     _ASSERT(IS_UART(UARTx));
299 
300     return (Boolean)(UARTx->STATUS.bit.RX_FULL);
301 }
302 
303 /**
304  * @method UART_IsRXFIFONotEmpty
305  * @brief  Check if the Rx fifo is empty or not.
306  * @param  UARTx: Select the UART peripheral.
307  *         This parameter can be one of the following values:
308  *         MUART0, MUART1, MUART2 or MUART3.
309  * @retval TRUE: Rx fifo is not empty.
310  *         FALSE: Rx fifo is empty
311  */
UART_IsRXFIFONotEmpty(UART_TypeDef * UARTx)312 Boolean UART_IsRXFIFONotEmpty(UART_TypeDef *UARTx)
313 {
314     _ASSERT(IS_UART(UARTx));
315 
316     return (Boolean)(!(UARTx->STATUS.bit.RX_EMPTY));
317 }
318 
319 /**
320  * @method UART_IsBusy
321  * @brief  Check if the UARTx is busy or not.
322  * @param  UARTx: Select the UART peripheral.
323  *         This parameter can be one of the following values:
324  *         MUART0, MUART1, MUART2 or MUART3.
325  * @retval TRUE: UARTx is busy.
326  *         FALSE: UARTx is not busy.
327  */
UART_IsBusy(UART_TypeDef * UARTx)328 Boolean UART_IsBusy(UART_TypeDef *UARTx)
329 {
330     _ASSERT(IS_UART(UARTx));
331 
332     return (Boolean)(!(UARTx->STATUS.bit.RX_EMPTY));
333 }
334 
335 /**
336  * @method UART_SetITTimeout
337  * @brief  Sets the interruption time for serial port timeout.
338  * @param  USARTx: Select the USART or the UART peripheral.
339  *         This parameter can be one of the following values:
340  *         MUART0, MUART1, MUART2 or MUART3.
341  * @param  timeout: 0x00~0xff
342  * @retval None
343  */
UART_SetITTimeout(UART_TypeDef * UARTx,uint16_t timeout)344 void UART_SetITTimeout(UART_TypeDef *UARTx, uint16_t timeout)
345 {
346     _ASSERT(IS_UART(UARTx));
347 
348     UARTx->TIMEOUT_INT.reg = timeout;
349 }
350 
351 /**
352  * @method UART_SetRxITNum
353  * @brief  Set the number of uart receive data intterupt trigger
354  * @param  UARTx: Select the UART peripheral.
355  *         This parameter can be one of the following values:
356  *         MUART0, MUART1, MUART2 or MUART3.
357  * @param  Bcnt: if the number of receive datas greater than Bcnt,interrupt trigger
358  * @retval None
359  */
UART_SetRxITNum(UART_TypeDef * UARTx,uint8_t Bcnt)360 void UART_SetRxITNum(UART_TypeDef *UARTx, uint8_t Bcnt)
361 {
362     _ASSERT(IS_UART(UARTx));
363 
364     UARTx->RX_INT_LEN.reg = Bcnt;
365 }
366 
367 /**
368  * @method UART_ReceiveDataLen
369  * @brief  Return the length of received data
370  * @param  UARTx: Select the UART peripheral.
371  *         This parameter can be one of the following values:
372  *         MUART0, MUART1, MUART2 or MUART3.
373  * @retval Data len
374  */
UART_ReceiveDataLen(UART_TypeDef * UARTx)375 uint32_t UART_ReceiveDataLen(UART_TypeDef *UARTx)
376 {
377     _ASSERT(IS_UART(UARTx));
378 
379     return (UARTx->STATUS.bit.RX_ITEMS_H << 16) + UARTx->STATUS.bit.RX_ITEMS_L;
380 }
381 
382 /************************ (C) COPYRIGHT Yichip Microelectronics *****END OF FILE****/
383