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