1 /******************************************************************************
2  *
3  * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
4  * Analog Devices, Inc.),
5  * Copyright (C) 2023-2024 Analog Devices, Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************************/
20 
21 #include <stdio.h>
22 #include "mxc_device.h"
23 #include "mxc_assert.h"
24 #include "uart.h"
25 #include "uart_revc.h"
26 #include "dma.h"
27 
28 /* **** Definitions **** */
29 #define MXC_UART_REVC_ERRINT_EN                                                       \
30     (MXC_F_UART_REVC_INT_EN_RX_FRAME_ERROR | MXC_F_UART_REVC_INT_EN_RX_PARITY_ERROR | \
31      MXC_F_UART_REVC_INT_EN_RX_OVERRUN)
32 
33 #define MXC_UART_REVC_ERRINT_FL                                                       \
34     (MXC_F_UART_REVC_INT_FL_RX_FRAME_ERROR | MXC_F_UART_REVC_INT_FL_RX_PARITY_ERROR | \
35      MXC_F_UART_REVC_INT_FL_RX_OVERRUN)
36 
37 /* **** Variable Declaration **** */
38 static void *AsyncRequests[MXC_UART_INSTANCES];
39 // static int baudRate;
40 
41 // Structure to save DMA state
42 typedef struct {
43     mxc_uart_revc_req_t *req;
44     int channelTx;
45     int channelRx;
46 } uart_revc_req_state_t;
47 
48 uart_revc_req_state_t states[MXC_UART_INSTANCES];
49 
50 /* **** Function Prototypes **** */
51 
52 /* ************************************************************************* */
53 /* Control/Configuration functions                                           */
54 /* ************************************************************************* */
MXC_UART_RevC_Init(mxc_uart_revc_regs_t * uart,unsigned int baud)55 int MXC_UART_RevC_Init(mxc_uart_revc_regs_t *uart, unsigned int baud)
56 {
57     int err;
58 
59     MXC_ASSERT(MXC_UART_GET_IDX((mxc_uart_regs_t *)uart) >= 0)
60 
61     // Initialize UART
62     // Set RX threshold to 1 byte
63     if ((err = MXC_UART_SetRXThreshold((mxc_uart_regs_t *)uart, 1)) != E_NO_ERROR) {
64         return err;
65     }
66 
67     // Set Datasize to 8 bits
68     if ((err = MXC_UART_SetDataSize((mxc_uart_regs_t *)uart, 8)) != E_NO_ERROR) {
69         return err;
70     }
71 
72     if ((err = MXC_UART_SetParity((mxc_uart_regs_t *)uart, MXC_UART_PARITY_DISABLE)) !=
73         E_NO_ERROR) {
74         return err;
75     }
76 
77     if ((err = MXC_UART_SetStopBits((mxc_uart_regs_t *)uart, MXC_UART_STOP_1)) != E_NO_ERROR) {
78         return err;
79     }
80 
81     // uart->ctrl |= MXC_F_UART_REVC_CTRL_ENABLE;
82     MXC_UART_SetFrequency((mxc_uart_regs_t *)uart, baud);
83 
84     return E_NO_ERROR;
85 }
86 
MXC_UART_RevC_ReadyForSleep(mxc_uart_revc_regs_t * uart)87 int MXC_UART_RevC_ReadyForSleep(mxc_uart_revc_regs_t *uart)
88 {
89     if (AsyncRequests[MXC_UART_GET_IDX((mxc_uart_regs_t *)uart)] != NULL) {
90         return E_BUSY;
91     }
92 
93     return MXC_UART_GetActive((mxc_uart_regs_t *)uart);
94 }
95 
MXC_UART_RevC_SetFrequency(mxc_uart_revc_regs_t * uart,unsigned int baud)96 int MXC_UART_RevC_SetFrequency(mxc_uart_revc_regs_t *uart, unsigned int baud)
97 {
98     int div = 0, baud0 = 0, baud1 = 0;
99 
100     // Set the baud rate
101     // Calculate divisor
102     div = PeripheralClock / baud;
103     // Search for integer and fractional baud rate registers based on divisor
104     baud0 = div >> (7); // divide by 128 extract integer part
105     baud1 = ((div) - (baud0 << 7)); //subtract factor corrected div - integer parts
106 
107     MXC_SETFIELD(uart->baud0, MXC_F_UART_REVC_BAUD0_IBAUD, baud0);
108     MXC_SETFIELD(uart->baud1, MXC_F_UART_REVC_BAUD1_DBAUD, baud1);
109 
110     return MXC_UART_GetFrequency((mxc_uart_regs_t *)uart);
111 }
112 
MXC_UART_RevC_GetFrequency(mxc_uart_revc_regs_t * uart)113 int MXC_UART_RevC_GetFrequency(mxc_uart_revc_regs_t *uart)
114 {
115     int div = 0;
116 
117     div = uart->baud0 << 7;
118     div += uart->baud1;
119 
120     return div * PeripheralClock;
121 }
122 
MXC_UART_RevC_SetDataSize(mxc_uart_revc_regs_t * uart,int dataSize)123 int MXC_UART_RevC_SetDataSize(mxc_uart_revc_regs_t *uart, int dataSize)
124 {
125     if (dataSize < 5 || dataSize > 8) {
126         return E_BAD_PARAM;
127     }
128 
129     dataSize = (dataSize - 5) << MXC_F_UART_REVC_CTRL_CHAR_SIZE_POS;
130 
131     MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVC_CTRL_CHAR_SIZE, dataSize);
132 
133     return E_NO_ERROR;
134 }
135 
MXC_UART_RevC_SetStopBits(mxc_uart_revc_regs_t * uart,mxc_uart_stop_t stopBits)136 int MXC_UART_RevC_SetStopBits(mxc_uart_revc_regs_t *uart, mxc_uart_stop_t stopBits)
137 {
138     switch (stopBits) {
139     case MXC_UART_STOP_1:
140         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVC_CTRL_STOPBITS,
141                      0 << MXC_F_UART_REVC_CTRL_STOPBITS_POS);
142         break;
143 
144     case MXC_UART_STOP_2:
145         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVC_CTRL_STOPBITS,
146                      1 << MXC_F_UART_REVC_CTRL_STOPBITS_POS);
147         break;
148 
149     default:
150         return E_BAD_PARAM;
151         break;
152     }
153 
154     return E_NO_ERROR;
155 }
156 
MXC_UART_RevC_SetParity(mxc_uart_revc_regs_t * uart,mxc_uart_parity_t parity)157 int MXC_UART_RevC_SetParity(mxc_uart_revc_regs_t *uart, mxc_uart_parity_t parity)
158 {
159     switch (parity) {
160     case MXC_UART_PARITY_DISABLE:
161         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVC_CTRL_PARITY_EN,
162                      0 << MXC_F_UART_REVC_CTRL_PARITY_EN_POS);
163         break;
164 
165     case MXC_UART_PARITY_EVEN:
166     case MXC_UART_PARITY_EVEN_0:
167         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVC_CTRL_PARITY_EN,
168                      1 << MXC_F_UART_REVC_CTRL_PARITY_EN_POS);
169         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVC_CTRL_PARITY, 0 << MXC_F_UART_REVC_CTRL_PARITY_POS);
170         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVC_CTRL_PARMD, 0 << MXC_F_UART_REVC_CTRL_PARMD_POS);
171         break;
172 
173     case MXC_UART_PARITY_EVEN_1:
174         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVC_CTRL_PARITY_EN,
175                      1 << MXC_F_UART_REVC_CTRL_PARITY_EN_POS);
176         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVC_CTRL_PARITY, 0 << MXC_F_UART_REVC_CTRL_PARITY_POS);
177         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVC_CTRL_PARMD, 1 << MXC_F_UART_REVC_CTRL_PARMD_POS);
178         break;
179 
180     case MXC_UART_PARITY_ODD:
181     case MXC_UART_PARITY_ODD_0:
182         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVC_CTRL_PARITY_EN,
183                      1 << MXC_F_UART_REVC_CTRL_PARITY_EN_POS);
184         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVC_CTRL_PARITY, 1 << MXC_F_UART_REVC_CTRL_PARITY_POS);
185         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVC_CTRL_PARMD, 0 << MXC_F_UART_REVC_CTRL_PARMD_POS);
186         break;
187 
188     case MXC_UART_PARITY_ODD_1:
189         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVC_CTRL_PARITY_EN,
190                      1 << MXC_F_UART_REVC_CTRL_PARITY_EN_POS);
191         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVC_CTRL_PARITY, 1 << MXC_F_UART_REVC_CTRL_PARITY_POS);
192         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVC_CTRL_PARMD, 1 << MXC_F_UART_REVC_CTRL_PARMD_POS);
193         break;
194 
195     default:
196         return E_BAD_PARAM;
197         break;
198     }
199 
200     return E_NO_ERROR;
201 }
202 
MXC_UART_RevC_GetActive(mxc_uart_revc_regs_t * uart)203 int MXC_UART_RevC_GetActive(mxc_uart_revc_regs_t *uart)
204 {
205     if (uart->status & (MXC_F_UART_REVC_STATUS_TX_BUSY | MXC_F_UART_REVC_STATUS_RX_BUSY)) {
206         return E_BUSY;
207     }
208 
209     return E_NO_ERROR;
210 }
211 
MXC_UART_RevC_AbortTransmission(mxc_uart_revc_regs_t * uart)212 int MXC_UART_RevC_AbortTransmission(mxc_uart_revc_regs_t *uart)
213 {
214     return MXC_UART_ClearTXFIFO((mxc_uart_regs_t *)uart);
215 }
216 
MXC_UART_RevC_ReadCharacterRaw(mxc_uart_revc_regs_t * uart)217 int MXC_UART_RevC_ReadCharacterRaw(mxc_uart_revc_regs_t *uart)
218 {
219     if (uart->status & MXC_F_UART_REVC_STATUS_RX_EMPTY) {
220         return E_UNDERFLOW;
221     }
222 
223     return uart->fifo;
224 }
225 
MXC_UART_RevC_WriteCharacterRaw(mxc_uart_revc_regs_t * uart,uint8_t character)226 int MXC_UART_RevC_WriteCharacterRaw(mxc_uart_revc_regs_t *uart, uint8_t character)
227 {
228     // Return error if the FIFO is full
229     if (uart->status & MXC_F_UART_REVC_STATUS_TX_FULL) {
230         return E_OVERFLOW;
231     }
232 
233     uart->fifo = character;
234 
235     return E_NO_ERROR;
236 }
237 
MXC_UART_RevC_Read(mxc_uart_revc_regs_t * uart,uint8_t * buffer,int * len)238 int MXC_UART_RevC_Read(mxc_uart_revc_regs_t *uart, uint8_t *buffer, int *len)
239 {
240     int read = 0;
241 
242     for (; read < *len; read++) {
243         int retVal = MXC_UART_ReadCharacter((mxc_uart_regs_t *)uart);
244 
245         if (retVal < 0) {
246             *len = read;
247             return retVal;
248         } else {
249             buffer[read] = retVal;
250         }
251     }
252 
253     *len = read;
254     return E_NO_ERROR;
255 }
256 
MXC_UART_RevC_Write(mxc_uart_revc_regs_t * uart,uint8_t * byte,int * len)257 int MXC_UART_RevC_Write(mxc_uart_revc_regs_t *uart, uint8_t *byte, int *len)
258 {
259     int written = 0;
260 
261     for (; written < *len; written++) {
262         int retVal = MXC_UART_WriteCharacter((mxc_uart_regs_t *)uart, byte[written]);
263 
264         if (retVal != E_NO_ERROR) {
265             *len = written;
266             return retVal;
267         }
268     }
269 
270     *len = written;
271     return E_NO_ERROR;
272 }
273 
MXC_UART_RevC_ReadRXFIFO(mxc_uart_revc_regs_t * uart,unsigned char * bytes,unsigned int len)274 unsigned int MXC_UART_RevC_ReadRXFIFO(mxc_uart_revc_regs_t *uart, unsigned char *bytes,
275                                       unsigned int len)
276 {
277     int read = 0;
278 
279     for (; read < len; read++) {
280         if (uart->status & MXC_F_UART_REVC_STATUS_RX_EMPTY) {
281             break;
282         }
283 
284         bytes[read] = uart->fifo;
285     }
286 
287     return read;
288 }
289 
MXC_UART_RevC_ReadRXFIFODMA(mxc_uart_revc_regs_t * uart,unsigned char * bytes,unsigned int len,mxc_uart_dma_complete_cb_t callback,mxc_dma_config_t config)290 int MXC_UART_RevC_ReadRXFIFODMA(mxc_uart_revc_regs_t *uart, unsigned char *bytes, unsigned int len,
291                                 mxc_uart_dma_complete_cb_t callback, mxc_dma_config_t config)
292 {
293     uint8_t channel;
294     mxc_dma_srcdst_t srcdst;
295 
296     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
297 
298     channel = MXC_DMA_AcquireChannel();
299 
300     config.ch = channel;
301 
302     config.srcwd = MXC_DMA_WIDTH_BYTE;
303     config.dstwd = MXC_DMA_WIDTH_BYTE;
304 
305     config.srcinc_en = 0;
306     config.dstinc_en = 1;
307 
308     srcdst.ch = channel;
309     srcdst.dest = bytes;
310     srcdst.len = len;
311 
312     states[uart_num].channelRx = channel;
313     MXC_DMA_ConfigChannel(config, srcdst);
314     MXC_DMA_SetCallback(channel, MXC_UART_DMACallback);
315     MXC_DMA_EnableInt(channel);
316     MXC_DMA_Start(channel);
317     //MXC_DMA->ch[channel].ctrl |= MXC_F_DMA_CTRL_CTZ_IE;
318     MXC_DMA_SetChannelInterruptEn(channel, 0, 1);
319     uart->dma |= MXC_F_UART_REVC_DMA_RXDMA_EN;
320 
321     return E_NO_ERROR;
322 }
323 
MXC_UART_RevC_GetRXFIFOAvailable(mxc_uart_revc_regs_t * uart)324 unsigned int MXC_UART_RevC_GetRXFIFOAvailable(mxc_uart_revc_regs_t *uart)
325 {
326     return (uart->status & MXC_F_UART_REVC_STATUS_RX_FIFO_CNT) >>
327            MXC_F_UART_REVC_STATUS_RX_FIFO_CNT_POS;
328 }
329 
MXC_UART_RevC_WriteTXFIFO(mxc_uart_revc_regs_t * uart,unsigned char * bytes,unsigned int len)330 unsigned int MXC_UART_RevC_WriteTXFIFO(mxc_uart_revc_regs_t *uart, unsigned char *bytes,
331                                        unsigned int len)
332 {
333     int written = 0;
334 
335     for (; written < len; written++) {
336         if (uart->status & MXC_F_UART_REVC_STATUS_TX_FULL) {
337             break;
338         }
339 
340         uart->fifo = bytes[written];
341     }
342 
343     return written;
344 }
345 
MXC_UART_RevC_WriteTXFIFODMA(mxc_uart_revc_regs_t * uart,unsigned char * bytes,unsigned int len,mxc_uart_dma_complete_cb_t callback,mxc_dma_config_t config)346 int MXC_UART_RevC_WriteTXFIFODMA(mxc_uart_revc_regs_t *uart, unsigned char *bytes, unsigned int len,
347                                  mxc_uart_dma_complete_cb_t callback, mxc_dma_config_t config)
348 {
349     uint8_t channel;
350     mxc_dma_srcdst_t srcdst;
351 
352     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
353 
354     channel = MXC_DMA_AcquireChannel();
355 
356     config.ch = channel;
357 
358     config.srcwd = MXC_DMA_WIDTH_BYTE;
359     config.dstwd = MXC_DMA_WIDTH_BYTE;
360 
361     config.srcinc_en = 1;
362     config.dstinc_en = 0;
363 
364     srcdst.ch = channel;
365     srcdst.source = bytes;
366     srcdst.len = len;
367 
368     states[uart_num].channelTx = channel;
369     MXC_DMA_ConfigChannel(config, srcdst);
370     MXC_DMA_SetCallback(channel, MXC_UART_DMACallback);
371     MXC_DMA_EnableInt(channel);
372     MXC_DMA_Start(channel);
373     //MXC_DMA->ch[channel].ctrl |= MXC_F_DMA_CTRL_CTZ_IE;
374     MXC_DMA_SetChannelInterruptEn(channel, 0, 1);
375     uart->dma |= MXC_F_UART_REVC_DMA_TXDMA_EN;
376 
377     return E_NO_ERROR;
378 }
379 
MXC_UART_RevC_GetTXFIFOAvailable(mxc_uart_revc_regs_t * uart)380 unsigned int MXC_UART_RevC_GetTXFIFOAvailable(mxc_uart_revc_regs_t *uart)
381 {
382     int txCnt = (uart->status & MXC_F_UART_REVC_STATUS_TX_FIFO_CNT) >>
383                 MXC_F_UART_REVC_STATUS_TX_FIFO_CNT_POS;
384     return MXC_UART_FIFO_DEPTH - txCnt;
385 }
386 
MXC_UART_RevC_ClearRXFIFO(mxc_uart_revc_regs_t * uart)387 int MXC_UART_RevC_ClearRXFIFO(mxc_uart_revc_regs_t *uart)
388 {
389     uart->ctrl |= MXC_F_UART_REVC_CTRL_RX_FLUSH;
390 
391     while (uart->ctrl & MXC_F_UART_REVC_CTRL_RX_FLUSH) {}
392 
393     return E_NO_ERROR;
394 }
395 
MXC_UART_RevC_ClearTXFIFO(mxc_uart_revc_regs_t * uart)396 int MXC_UART_RevC_ClearTXFIFO(mxc_uart_revc_regs_t *uart)
397 {
398     uart->ctrl |= MXC_F_UART_REVC_CTRL_TX_FLUSH;
399 
400     while (uart->ctrl & MXC_F_UART_REVC_CTRL_TX_FLUSH) {}
401 
402     return E_NO_ERROR;
403 }
404 
MXC_UART_RevC_SetRXThreshold(mxc_uart_revc_regs_t * uart,unsigned int numBytes)405 int MXC_UART_RevC_SetRXThreshold(mxc_uart_revc_regs_t *uart, unsigned int numBytes)
406 {
407     if (numBytes < 1 || numBytes > MXC_UART_FIFO_DEPTH) {
408         return E_BAD_PARAM;
409     }
410 
411     numBytes <<= MXC_F_UART_REVC_CTRL_RXTHD_POS;
412     MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVC_CTRL_RXTHD, numBytes);
413 
414     return E_NO_ERROR;
415 }
416 
MXC_UART_RevC_GetRXThreshold(mxc_uart_revc_regs_t * uart)417 unsigned int MXC_UART_RevC_GetRXThreshold(mxc_uart_revc_regs_t *uart)
418 {
419     return (uart->ctrl & MXC_F_UART_REVC_CTRL_RXTHD) >> MXC_F_UART_REVC_CTRL_RXTHD_POS;
420 }
421 
MXC_UART_RevC_GetFlags(mxc_uart_revc_regs_t * uart)422 unsigned int MXC_UART_RevC_GetFlags(mxc_uart_revc_regs_t *uart)
423 {
424     return uart->int_fl;
425 }
426 
MXC_UART_RevC_ClearFlags(mxc_uart_revc_regs_t * uart,unsigned int flags)427 int MXC_UART_RevC_ClearFlags(mxc_uart_revc_regs_t *uart, unsigned int flags)
428 {
429     uart->int_fl &= ~flags;
430 
431     return E_NO_ERROR;
432 }
433 
MXC_UART_RevC_EnableInt(mxc_uart_revc_regs_t * uart,unsigned int intEn)434 int MXC_UART_RevC_EnableInt(mxc_uart_revc_regs_t *uart, unsigned int intEn)
435 {
436     uart->int_en |= intEn;
437 
438     return E_NO_ERROR;
439 }
440 
MXC_UART_RevC_DisableInt(mxc_uart_revc_regs_t * uart,unsigned int intDis)441 int MXC_UART_RevC_DisableInt(mxc_uart_revc_regs_t *uart, unsigned int intDis)
442 {
443     uart->int_en &= ~intDis;
444 
445     return E_NO_ERROR;
446 }
447 
MXC_UART_RevC_GetStatus(mxc_uart_revc_regs_t * uart)448 unsigned int MXC_UART_RevC_GetStatus(mxc_uart_revc_regs_t *uart)
449 {
450     return uart->status;
451 }
452 
MXC_UART_RevC_Transaction(mxc_uart_revc_req_t * req)453 int MXC_UART_RevC_Transaction(mxc_uart_revc_req_t *req)
454 {
455     int numToWrite, numToRead;
456 
457     if (MXC_UART_GET_IDX((mxc_uart_regs_t *)(req->uart)) < 0) {
458         return E_BAD_PARAM;
459     }
460 
461     MXC_UART_DisableInt((mxc_uart_regs_t *)(req->uart), 0xFFFFFFFF);
462     MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart), 0xFFFFFFFF);
463 
464     MXC_UART_ClearRXFIFO((mxc_uart_regs_t *)(req->uart));
465     MXC_UART_ClearTXFIFO((mxc_uart_regs_t *)(req->uart));
466 
467     req->txCnt = 0;
468     req->rxCnt = 0;
469 
470     if (req->rxLen) {
471         if (req->rxData == NULL) {
472             return E_BAD_PARAM;
473         }
474     }
475 
476     if (req->txLen) {
477         if (req->txData == NULL) {
478             return E_BAD_PARAM;
479         }
480 
481         numToWrite = MXC_UART_GetTXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
482         numToWrite = numToWrite > (req->txLen - req->txCnt) ? req->txLen - req->txCnt : numToWrite;
483         req->txCnt += MXC_UART_WriteTXFIFO((mxc_uart_regs_t *)(req->uart), &req->txData[req->txCnt],
484                                            numToWrite);
485 
486         while (req->txCnt < req->txLen) {
487             while (!(MXC_UART_GetFlags((mxc_uart_regs_t *)(req->uart)) &
488                      MXC_F_UART_REVC_INT_FL_TX_FIFO_HALF_EMPTY)) {}
489 
490             numToWrite = MXC_UART_GetTXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
491             numToWrite = numToWrite > (req->txLen - req->txCnt) ? req->txLen - req->txCnt :
492                                                                   numToWrite;
493             req->txCnt += MXC_UART_WriteTXFIFO((mxc_uart_regs_t *)(req->uart),
494                                                &req->txData[req->txCnt], numToWrite);
495             MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart),
496                                 MXC_F_UART_REVC_INT_FL_TX_FIFO_HALF_EMPTY);
497         }
498     }
499 
500     if (req->rxLen) {
501         numToRead = MXC_UART_GetRXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
502         numToRead = numToRead > (req->rxLen - req->rxCnt) ? req->rxLen - req->rxCnt : numToRead;
503         req->rxCnt += MXC_UART_ReadRXFIFO((mxc_uart_regs_t *)(req->uart), &req->rxData[req->rxCnt],
504                                           numToRead);
505 
506         while (req->rxCnt < req->rxLen) {
507             while (!(MXC_UART_GetFlags((mxc_uart_regs_t *)(req->uart)) &
508                      MXC_F_UART_REVC_INT_FL_RX_FIFO_THRESH)) {}
509 
510             numToRead = MXC_UART_GetRXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
511             numToRead = numToRead > (req->rxLen - req->rxCnt) ? req->rxLen - req->rxCnt : numToRead;
512             req->rxCnt += MXC_UART_ReadRXFIFO((mxc_uart_regs_t *)(req->uart),
513                                               &req->rxData[req->rxCnt], numToRead);
514             MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart),
515                                 MXC_F_UART_REVC_INT_FL_RX_FIFO_THRESH);
516         }
517     }
518 
519     return E_NO_ERROR;
520 }
521 
MXC_UART_RevC_TransactionAsync(mxc_uart_revc_req_t * req)522 int MXC_UART_RevC_TransactionAsync(mxc_uart_revc_req_t *req)
523 {
524     unsigned int intEn;
525     int numToWrite, numToRead;
526 
527     if (MXC_UART_GET_IDX((mxc_uart_regs_t *)(req->uart)) < 0) {
528         return E_BAD_PARAM;
529     }
530 
531     MXC_UART_DisableInt((mxc_uart_regs_t *)(req->uart), 0xFFFFFFFF);
532     MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart), 0xFFFFFFFF);
533 
534     MXC_UART_ClearRXFIFO((mxc_uart_regs_t *)(req->uart));
535     MXC_UART_ClearTXFIFO((mxc_uart_regs_t *)(req->uart));
536 
537     req->txCnt = 0;
538     req->rxCnt = 0;
539 
540     // Check for bad requests.
541     if (req->txLen) {
542         if (req->txData == NULL) {
543             MXC_UART_DisableInt((mxc_uart_regs_t *)(req->uart), 0xFFFFFFFF);
544             return E_BAD_PARAM;
545         }
546     }
547 
548     if (req->rxLen) {
549         if (req->rxData == NULL) {
550             MXC_UART_DisableInt((mxc_uart_regs_t *)(req->uart), 0xFFFFFFFF);
551             return E_BAD_PARAM;
552         }
553     }
554 
555     // Register request.
556     MXC_ASSERT(AsyncRequests[MXC_UART_GET_IDX((mxc_uart_regs_t *)(req->uart))] == NULL);
557     AsyncRequests[MXC_UART_GET_IDX((mxc_uart_regs_t *)(req->uart))] = (void *)req;
558 
559     // Select interrupts to enable atomically.
560     // returning success by default.
561     intEn = 0;
562 
563     // Be it a tx fifo interrupt,
564     if (req->txLen) {
565         intEn |= MXC_F_UART_REVC_INT_EN_TX_FIFO_HALF_EMPTY;
566         numToWrite = MXC_UART_GetTXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
567         numToWrite = numToWrite > (req->txLen - req->txCnt) ? req->txLen - req->txCnt : numToWrite;
568         req->txCnt += MXC_UART_WriteTXFIFO((mxc_uart_regs_t *)(req->uart), &req->txData[req->txCnt],
569                                            numToWrite);
570     }
571 
572     // Or an rx interrupt.
573     if (req->rxLen) {
574         // All error interrupts are related to RX
575         intEn |= MXC_UART_REVC_ERRINT_EN;
576         intEn |= MXC_F_UART_REVC_INT_EN_RX_FIFO_THRESH;
577         numToRead = MXC_UART_GetRXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
578         numToRead = numToRead > (req->rxLen - req->rxCnt) ? req->rxLen - req->rxCnt : numToRead;
579         req->rxCnt += MXC_UART_ReadRXFIFO((mxc_uart_regs_t *)(req->uart), &req->rxData[req->rxCnt],
580                                           numToRead);
581         MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart), MXC_F_UART_REVC_INT_FL_RX_FIFO_THRESH);
582     }
583 
584     // Enable all interrupts at the same time.
585     MXC_UART_EnableInt((mxc_uart_regs_t *)(req->uart), intEn);
586 
587     return E_NO_ERROR;
588 }
589 
MXC_UART_RevC_TransactionDMA(mxc_uart_revc_req_t * req)590 int MXC_UART_RevC_TransactionDMA(mxc_uart_revc_req_t *req)
591 {
592     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)(req->uart));
593 
594     MXC_ASSERT(uart_num >= 0)
595 
596     if (req->txLen) {
597         if (req->txData == NULL) {
598             return E_BAD_PARAM;
599         }
600     }
601 
602     if (req->rxLen) {
603         if (req->rxData == NULL) {
604             return E_BAD_PARAM;
605         }
606     }
607 
608     MXC_UART_DisableInt((mxc_uart_regs_t *)(req->uart), 0xFFFFFFFF);
609     MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart), 0xFFFFFFFF);
610 
611     MXC_UART_ClearRXFIFO((mxc_uart_regs_t *)(req->uart));
612     MXC_UART_ClearTXFIFO((mxc_uart_regs_t *)(req->uart));
613 
614     (req->uart)->dma |=
615         (1 << MXC_F_UART_REVC_DMA_RXDMA_LEVEL_POS); // Set RX DMA threshold to 1 byte
616     (req->uart)->dma |=
617         (2 << MXC_F_UART_REVC_DMA_TXDMA_LEVEL_POS); // Set TX DMA threshold to 2 bytes
618 
619     MXC_DMA_Init();
620 
621     //tx
622     if ((req->txData != NULL) && (req->txLen)) {
623         if (MXC_UART_WriteTXFIFODMA((mxc_uart_regs_t *)(req->uart), req->txData, req->txLen,
624                                     NULL) != E_NO_ERROR) {
625             return E_BAD_PARAM;
626         }
627     }
628 
629     if ((req->rxData != NULL) && (req->rxLen)) {
630         if (MXC_UART_ReadRXFIFODMA((mxc_uart_regs_t *)(req->uart), req->rxData, req->rxLen, NULL) !=
631             E_NO_ERROR) {
632             return E_BAD_PARAM;
633         }
634     }
635 
636     return E_NO_ERROR;
637 }
638 
MXC_UART_RevC_DMACallback(int ch,int error)639 void MXC_UART_RevC_DMACallback(int ch, int error)
640 {
641     mxc_uart_revc_req_t *temp_req;
642 
643     for (int i = 0; i < MXC_UART_INSTANCES; i++) {
644         if (states[i].channelTx == ch) {
645             //save the request
646             temp_req = states[i].req;
647             // Callback if not NULL
648             if (temp_req->callback != NULL) {
649                 temp_req->callback((mxc_uart_req_t *)temp_req, E_NO_ERROR);
650             }
651             break;
652         } else if (states[i].channelRx == ch) {
653             //save the request
654             temp_req = states[i].req;
655             // Callback if not NULL
656             if (temp_req->callback != NULL) {
657                 temp_req->callback((mxc_uart_req_t *)temp_req, E_NO_ERROR);
658             }
659             break;
660         }
661     }
662 }
663 
MXC_UART_RevC_AsyncCallback(mxc_uart_revc_regs_t * uart,int retVal)664 int MXC_UART_RevC_AsyncCallback(mxc_uart_revc_regs_t *uart, int retVal)
665 {
666     mxc_uart_revc_req_t *req =
667         (mxc_uart_revc_req_t *)AsyncRequests[MXC_UART_GET_IDX((mxc_uart_regs_t *)uart)];
668 
669     if (req->callback != NULL) {
670         req->callback((mxc_uart_req_t *)req, retVal);
671     }
672 
673     return E_NO_ERROR;
674 }
675 
MXC_UART_RevC_AsyncStop(mxc_uart_revc_regs_t * uart)676 int MXC_UART_RevC_AsyncStop(mxc_uart_revc_regs_t *uart)
677 {
678     MXC_UART_DisableInt((mxc_uart_regs_t *)uart, 0xFFFFFFFF);
679     AsyncRequests[MXC_UART_GET_IDX((mxc_uart_regs_t *)uart)] = NULL;
680 
681     return E_NO_ERROR;
682 }
683 
MXC_UART_RevC_AbortAsync(mxc_uart_revc_regs_t * uart)684 int MXC_UART_RevC_AbortAsync(mxc_uart_revc_regs_t *uart)
685 {
686     MXC_UART_AsyncCallback((mxc_uart_regs_t *)uart, E_ABORT);
687     MXC_UART_AsyncStop((mxc_uart_regs_t *)uart);
688 
689     return E_NO_ERROR;
690 }
691 
MXC_UART_RevC_AsyncHandler(mxc_uart_revc_regs_t * uart)692 int MXC_UART_RevC_AsyncHandler(mxc_uart_revc_regs_t *uart)
693 {
694     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
695     int flags, numToWrite, numToRead;
696     mxc_uart_revc_req_t *req;
697 
698     MXC_ASSERT(uart_num >= 0)
699 
700     req = (mxc_uart_revc_req_t *)AsyncRequests[uart_num];
701 
702     flags = MXC_UART_GetFlags((mxc_uart_regs_t *)uart);
703 
704     if (flags & MXC_UART_REVC_ERRINT_FL & uart->int_en) {
705         MXC_UART_AsyncCallback((mxc_uart_regs_t *)uart, E_COMM_ERR);
706         MXC_UART_AsyncStop((mxc_uart_regs_t *)uart);
707         return E_INVALID;
708     }
709 
710     if ((flags & MXC_F_UART_REVC_INT_FL_TX_FIFO_HALF_EMPTY) && (req->txLen)) {
711         numToWrite = MXC_UART_GetTXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
712         numToWrite = numToWrite > (req->txLen - req->txCnt) ? req->txLen - req->txCnt : numToWrite;
713         req->txCnt += MXC_UART_WriteTXFIFO((mxc_uart_regs_t *)(req->uart), &req->txData[req->txCnt],
714                                            numToWrite);
715         MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart),
716                             MXC_F_UART_REVC_INT_FL_TX_FIFO_HALF_EMPTY);
717     }
718 
719     if ((flags & MXC_F_UART_REVC_INT_FL_RX_FIFO_THRESH) && (req->rxLen)) {
720         numToRead = MXC_UART_GetRXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
721         numToRead = numToRead > (req->rxLen - req->rxCnt) ? req->rxLen - req->rxCnt : numToRead;
722         req->rxCnt += MXC_UART_ReadRXFIFO((mxc_uart_regs_t *)(req->uart), &req->rxData[req->rxCnt],
723                                           numToRead);
724 
725         if ((req->rxLen - req->rxCnt) < MXC_UART_GetRXThreshold((mxc_uart_regs_t *)(req->uart))) {
726             MXC_UART_SetRXThreshold((mxc_uart_regs_t *)(req->uart), req->rxLen - req->rxCnt);
727         }
728 
729         MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart), MXC_F_UART_REVC_INT_FL_RX_FIFO_THRESH);
730     }
731 
732     if ((req->rxCnt == req->rxLen) && (req->txCnt == req->txLen)) {
733         MXC_UART_AsyncCallback((mxc_uart_regs_t *)uart, E_NO_ERROR);
734         MXC_UART_AsyncStop((mxc_uart_regs_t *)uart);
735     }
736 
737     return E_NO_ERROR;
738 }
739