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. All Rights Reserved. This software
6  * is proprietary to Analog Devices, Inc. and its licensors.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  ******************************************************************************/
21 
22 #include <stdio.h>
23 #include "mxc_device.h"
24 #include "mxc_assert.h"
25 #include "uart.h"
26 #include "uart_revb.h"
27 #include "dma.h"
28 #ifdef __arm__
29 #include "nvic_table.h"
30 #endif
31 
32 /* **** Definitions **** */
33 #define MXC_UART_REVB_ERRINT_EN \
34     (MXC_F_UART_REVB_INT_EN_RX_FERR | MXC_F_UART_REVB_INT_EN_RX_PAR | MXC_F_UART_REVB_INT_EN_RX_OV)
35 
36 #define MXC_UART_REVB_ERRINT_FL \
37     (MXC_F_UART_REVB_INT_FL_RX_FERR | MXC_F_UART_REVB_INT_FL_RX_PAR | MXC_F_UART_REVB_INT_FL_RX_OV)
38 
39 /* **** Variable Declaration **** */
40 static void *AsyncTxRequests[MXC_UART_INSTANCES];
41 static void *AsyncRxRequests[MXC_UART_INSTANCES];
42 
43 typedef struct {
44     mxc_uart_revb_req_t *tx_req;
45     mxc_uart_revb_req_t *rx_req;
46     int channelTx;
47     int channelRx;
48     bool auto_dma_handlers;
49 } uart_revb_req_state_t;
50 
51 uart_revb_req_state_t states[MXC_UART_INSTANCES];
52 
53 /* **** Function Prototypes **** */
54 
55 /* ************************************************************************* */
56 /* Control/Configuration functions                                           */
57 /* ************************************************************************* */
MXC_UART_RevB_Init(mxc_uart_revb_regs_t * uart,unsigned int baud,mxc_uart_revb_clock_t clock)58 int MXC_UART_RevB_Init(mxc_uart_revb_regs_t *uart, unsigned int baud, mxc_uart_revb_clock_t clock)
59 {
60     int err;
61 
62     MXC_ASSERT(MXC_UART_GET_IDX((mxc_uart_regs_t *)uart) >= 0)
63 
64     // Initialize UART
65     if ((err = MXC_UART_SetRXThreshold((mxc_uart_regs_t *)uart, 1)) !=
66         E_NO_ERROR) { // Set RX threshold to 1 byte
67         return err;
68     }
69 
70     if ((err = MXC_UART_SetDataSize((mxc_uart_regs_t *)uart, 8)) !=
71         E_NO_ERROR) { // Set Datasize to 8 bits
72         return err;
73     }
74 
75     if ((err = MXC_UART_SetParity((mxc_uart_regs_t *)uart, MXC_UART_PARITY_DISABLE)) !=
76         E_NO_ERROR) {
77         return err;
78     }
79 
80     if ((err = MXC_UART_SetStopBits((mxc_uart_regs_t *)uart, MXC_UART_STOP_1)) != E_NO_ERROR) {
81         return err;
82     }
83 
84     if ((err = MXC_UART_SetFrequency((mxc_uart_regs_t *)uart, baud, (mxc_uart_clock_t)clock)) <
85         E_NO_ERROR) {
86         return err;
87     }
88 
89     // Initialize state struct
90     unsigned int i = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
91     states[i].channelRx = -1;
92     states[i].channelTx = -1;
93     states[i].tx_req = NULL;
94     states[i].rx_req = NULL;
95     states[i].auto_dma_handlers = false;
96 
97     return E_NO_ERROR;
98 }
99 
MXC_UART_RevB_ReadyForSleep(mxc_uart_revb_regs_t * uart)100 int MXC_UART_RevB_ReadyForSleep(mxc_uart_revb_regs_t *uart)
101 {
102     if (AsyncTxRequests[MXC_UART_GET_IDX((mxc_uart_regs_t *)uart)] != NULL) {
103         return E_BUSY;
104     }
105 
106     if (AsyncRxRequests[MXC_UART_GET_IDX((mxc_uart_regs_t *)uart)] != NULL) {
107         return E_BUSY;
108     }
109 
110     return MXC_UART_GetActive((mxc_uart_regs_t *)uart);
111 }
112 
MXC_UART_RevB_SetFrequency(mxc_uart_revb_regs_t * uart,unsigned int baud,mxc_uart_revb_clock_t clock)113 int MXC_UART_RevB_SetFrequency(mxc_uart_revb_regs_t *uart, unsigned int baud,
114                                mxc_uart_revb_clock_t clock)
115 {
116     unsigned clkDiv = 0, mod = 0;
117 
118     // OSR default value
119     uart->osr = 5;
120 
121     switch (clock) {
122     case MXC_UART_REVB_APB_CLK:
123         clkDiv = (PeripheralClock / baud);
124         mod = (PeripheralClock % baud);
125         break;
126 
127     case MXC_UART_REVB_EXT_CLK:
128         uart->ctrl |= MXC_S_UART_REVB_CTRL_BCLKSRC_EXTERNAL_CLOCK;
129         clkDiv = UART_EXTCLK_FREQ / baud;
130         mod = UART_EXTCLK_FREQ % baud;
131         break;
132 
133     //case MXC_UART_IBRO_CLK:
134     case MXC_UART_REVB_CLK2:
135         clkDiv = (IBRO_FREQ / baud);
136         mod = (IBRO_FREQ % baud);
137 
138         uart->ctrl |= MXC_S_UART_REVB_CTRL_BCLKSRC_CLK2;
139         break;
140 
141     //case MXC_UART_ERFO:
142     case MXC_UART_REVB_CLK3:
143 #if (TARGET_NUM == 78000 || TARGET_NUM == 78002)
144         return E_BAD_PARAM;
145 #else
146         clkDiv = (ERFO_FREQ / baud);
147         mod = (ERFO_FREQ % baud);
148 #endif
149 
150         uart->ctrl |= MXC_S_UART_REVB_CTRL_BCLKSRC_CLK3;
151         break;
152 
153     default:
154         return E_BAD_PARAM;
155     }
156 
157     if (!clkDiv || mod > (baud / 2)) {
158         clkDiv++;
159     }
160     uart->clkdiv = clkDiv;
161     return MXC_UART_GetFrequency((mxc_uart_regs_t *)uart);
162 }
163 
MXC_UART_RevB_GetFrequency(mxc_uart_revb_regs_t * uart)164 int MXC_UART_RevB_GetFrequency(mxc_uart_revb_regs_t *uart)
165 {
166     int periphClock = 0;
167 
168     if ((uart->ctrl & MXC_F_UART_REVB_CTRL_BCLKSRC) ==
169         MXC_S_UART_REVB_CTRL_BCLKSRC_EXTERNAL_CLOCK) {
170         periphClock = UART_EXTCLK_FREQ;
171     } else if ((uart->ctrl & MXC_F_UART_REVB_CTRL_BCLKSRC) ==
172                MXC_S_UART_REVB_CTRL_BCLKSRC_PERIPHERAL_CLOCK) {
173         periphClock = PeripheralClock;
174     } else if ((uart->ctrl & MXC_F_UART_REVB_CTRL_BCLKSRC) == MXC_S_UART_REVB_CTRL_BCLKSRC_CLK2) {
175         periphClock = IBRO_FREQ;
176     } else if ((uart->ctrl & MXC_F_UART_REVB_CTRL_BCLKSRC) == MXC_S_UART_REVB_CTRL_BCLKSRC_CLK3) {
177 #if (TARGET_NUM == 78000 || TARGET_NUM == 78002)
178         return E_BAD_PARAM;
179 #else
180         periphClock = ERFO_FREQ;
181 #endif
182     } else {
183         return E_BAD_PARAM;
184     }
185 
186     return (periphClock / uart->clkdiv);
187 }
188 
MXC_UART_RevB_SetDataSize(mxc_uart_revb_regs_t * uart,int dataSize)189 int MXC_UART_RevB_SetDataSize(mxc_uart_revb_regs_t *uart, int dataSize)
190 {
191     if (dataSize < 5 || dataSize > 8) {
192         return E_BAD_PARAM;
193     }
194 
195     dataSize = (dataSize - 5) << MXC_F_UART_REVB_CTRL_CHAR_SIZE_POS;
196 
197     MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVB_CTRL_CHAR_SIZE, dataSize);
198 
199     return E_NO_ERROR;
200 }
201 
MXC_UART_RevB_SetStopBits(mxc_uart_revb_regs_t * uart,mxc_uart_stop_t stopBits)202 int MXC_UART_RevB_SetStopBits(mxc_uart_revb_regs_t *uart, mxc_uart_stop_t stopBits)
203 {
204     switch (stopBits) {
205     case MXC_UART_STOP_1:
206         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVB_CTRL_STOPBITS,
207                      0 << MXC_F_UART_REVB_CTRL_STOPBITS_POS);
208         break;
209 
210     case MXC_UART_STOP_2:
211         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVB_CTRL_STOPBITS,
212                      1 << MXC_F_UART_REVB_CTRL_STOPBITS_POS);
213         break;
214 
215     default:
216         return E_BAD_PARAM;
217         break;
218     }
219 
220     return E_NO_ERROR;
221 }
222 
MXC_UART_RevB_SetParity(mxc_uart_revb_regs_t * uart,mxc_uart_parity_t parity)223 int MXC_UART_RevB_SetParity(mxc_uart_revb_regs_t *uart, mxc_uart_parity_t parity)
224 {
225     switch (parity) {
226     case MXC_UART_PARITY_DISABLE:
227         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVB_CTRL_PAR_EN, 0 << MXC_F_UART_REVB_CTRL_PAR_EN_POS);
228         break;
229 
230     case MXC_UART_PARITY_EVEN_0:
231         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVB_CTRL_PAR_EN, 1 << MXC_F_UART_REVB_CTRL_PAR_EN_POS);
232         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVB_CTRL_PAR_EO, 0 << MXC_F_UART_REVB_CTRL_PAR_EO_POS);
233         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVB_CTRL_PAR_MD, 0 << MXC_F_UART_REVB_CTRL_PAR_MD_POS);
234         break;
235 
236     case MXC_UART_PARITY_EVEN_1:
237         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVB_CTRL_PAR_EN, 1 << MXC_F_UART_REVB_CTRL_PAR_EN_POS);
238         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVB_CTRL_PAR_EO, 0 << MXC_F_UART_REVB_CTRL_PAR_EO_POS);
239         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVB_CTRL_PAR_MD, 1 << MXC_F_UART_REVB_CTRL_PAR_MD_POS);
240         break;
241 
242     case MXC_UART_PARITY_ODD_0:
243         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVB_CTRL_PAR_EN, 1 << MXC_F_UART_REVB_CTRL_PAR_EN_POS);
244         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVB_CTRL_PAR_EO, 1 << MXC_F_UART_REVB_CTRL_PAR_EO_POS);
245         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVB_CTRL_PAR_MD, 0 << MXC_F_UART_REVB_CTRL_PAR_MD_POS);
246         break;
247 
248     case MXC_UART_PARITY_ODD_1:
249         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVB_CTRL_PAR_EN, 1 << MXC_F_UART_REVB_CTRL_PAR_EN_POS);
250         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVB_CTRL_PAR_EO, 1 << MXC_F_UART_REVB_CTRL_PAR_EO_POS);
251         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVB_CTRL_PAR_MD, 1 << MXC_F_UART_REVB_CTRL_PAR_MD_POS);
252         break;
253 
254     default:
255         return E_BAD_PARAM;
256         break;
257     }
258 
259     return E_NO_ERROR;
260 }
261 
MXC_UART_RevB_SetFlowCtrl(mxc_uart_revb_regs_t * uart,mxc_uart_flow_t flowCtrl,int rtsThreshold)262 int MXC_UART_RevB_SetFlowCtrl(mxc_uart_revb_regs_t *uart, mxc_uart_flow_t flowCtrl,
263                               int rtsThreshold)
264 {
265     switch (flowCtrl) {
266     case MXC_UART_FLOW_DIS:
267         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVB_CTRL_HFC_EN, 0 << MXC_F_UART_REVB_CTRL_HFC_EN_POS);
268         break;
269 
270     case MXC_UART_FLOW_EN:
271         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVB_CTRL_HFC_EN, 1 << MXC_F_UART_REVB_CTRL_HFC_EN_POS);
272         break;
273 
274     default:
275         return E_BAD_PARAM;
276         break;
277     }
278 
279     //FIXME: Fix missing code for CTS threshhold.
280 
281     return E_NO_ERROR;
282 }
283 
MXC_UART_RevB_SetClockSource(mxc_uart_revb_regs_t * uart,mxc_uart_revb_clock_t clock)284 int MXC_UART_RevB_SetClockSource(mxc_uart_revb_regs_t *uart, mxc_uart_revb_clock_t clock)
285 {
286     switch (clock) {
287     case MXC_UART_REVB_APB_CLK:
288         break;
289 
290     case MXC_UART_REVB_EXT_CLK:
291         uart->ctrl |= MXC_S_UART_REVB_CTRL_BCLKSRC_EXTERNAL_CLOCK;
292         break;
293 
294     case MXC_UART_REVB_CLK2:
295         uart->ctrl |= MXC_S_UART_REVB_CTRL_BCLKSRC_CLK2;
296         break;
297 
298     case MXC_UART_REVB_CLK3:
299         uart->ctrl |= MXC_S_UART_REVB_CTRL_BCLKSRC_CLK3;
300         break;
301 
302     default:
303         return E_BAD_PARAM;
304     }
305 
306     return E_NO_ERROR;
307 }
308 
MXC_UART_RevB_GetActive(mxc_uart_revb_regs_t * uart)309 int MXC_UART_RevB_GetActive(mxc_uart_revb_regs_t *uart)
310 {
311     if (uart->status & (MXC_F_UART_REVB_STATUS_TX_BUSY | MXC_F_UART_REVB_STATUS_RX_BUSY)) {
312         return E_BUSY;
313     }
314 
315     return E_NO_ERROR;
316 }
317 
MXC_UART_RevB_AbortTransmission(mxc_uart_revb_regs_t * uart)318 int MXC_UART_RevB_AbortTransmission(mxc_uart_revb_regs_t *uart)
319 {
320     MXC_UART_ClearTXFIFO((mxc_uart_regs_t *)uart);
321     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
322 
323     if (states[uart_num].channelTx >= 0) {
324         MXC_DMA_Stop(states[uart_num].channelTx);
325     }
326     if (states[uart_num].channelRx >= 0) {
327         MXC_DMA_Stop(states[uart_num].channelRx);
328     }
329 
330     if (states[uart_num].auto_dma_handlers) {
331         MXC_DMA_ReleaseChannel(states[uart_num].channelTx);
332         states[uart_num].channelTx = -1;
333         MXC_DMA_ReleaseChannel(states[uart_num].channelRx);
334         states[uart_num].channelRx = -1;
335     }
336 
337     return E_NO_ERROR;
338 }
339 
MXC_UART_RevB_ReadCharacterRaw(mxc_uart_revb_regs_t * uart)340 int MXC_UART_RevB_ReadCharacterRaw(mxc_uart_revb_regs_t *uart)
341 {
342     if (uart->status & MXC_F_UART_REVB_STATUS_RX_EM) {
343         return E_UNDERFLOW;
344     }
345 
346     return uart->fifo;
347 }
348 
MXC_UART_RevB_WriteCharacterRaw(mxc_uart_revb_regs_t * uart,uint8_t character)349 int MXC_UART_RevB_WriteCharacterRaw(mxc_uart_revb_regs_t *uart, uint8_t character)
350 {
351     // Require the TX FIFO to be empty, so that we write out the expected character
352     // Return error if the FIFO is full
353     if (uart->status & MXC_F_UART_REVB_STATUS_TX_FULL) {
354         return E_OVERFLOW;
355     }
356 
357     uart->fifo = character;
358 
359     return E_NO_ERROR;
360 }
361 
MXC_UART_RevB_ReadCharacter(mxc_uart_revb_regs_t * uart)362 int MXC_UART_RevB_ReadCharacter(mxc_uart_revb_regs_t *uart)
363 {
364     if (uart->status & MXC_F_UART_REVB_STATUS_RX_EM) {
365         return E_UNDERFLOW;
366     }
367 
368     return uart->fifo;
369 }
370 
MXC_UART_RevB_WriteCharacter(mxc_uart_revb_regs_t * uart,uint8_t character)371 int MXC_UART_RevB_WriteCharacter(mxc_uart_revb_regs_t *uart, uint8_t character)
372 {
373     // Require the TX FIFO to be empty, so that we write out the expected character
374     // Return error if the FIFO is full
375     if (uart->status & MXC_F_UART_REVB_STATUS_TX_FULL) {
376         return E_OVERFLOW;
377     }
378 
379     uart->fifo = character;
380 
381     return E_NO_ERROR;
382 }
383 
MXC_UART_RevB_Read(mxc_uart_revb_regs_t * uart,uint8_t * buffer,int * len)384 int MXC_UART_RevB_Read(mxc_uart_revb_regs_t *uart, uint8_t *buffer, int *len)
385 {
386     int read = 0;
387     int retVal;
388 
389     if (buffer == NULL) {
390         return E_NULL_PTR;
391     }
392 
393     if (len == NULL) {
394         return E_NULL_PTR;
395     }
396 
397     for (; read < *len; read++) {
398         retVal = MXC_UART_ReadCharacter((mxc_uart_regs_t *)uart);
399 
400         if (retVal < 0) {
401             *len = read;
402             return retVal;
403         } else {
404             buffer[read] = retVal;
405         }
406     }
407 
408     *len = read;
409     return E_NO_ERROR;
410 }
411 
MXC_UART_RevB_Write(mxc_uart_revb_regs_t * uart,const uint8_t * byte,int * len)412 int MXC_UART_RevB_Write(mxc_uart_revb_regs_t *uart, const uint8_t *byte, int *len)
413 {
414     int written = 0;
415     int retVal;
416 
417     if (byte == NULL) {
418         return E_NULL_PTR;
419     }
420 
421     if (len == NULL) {
422         return E_NULL_PTR;
423     }
424 
425     for (; written < *len; written++) {
426         retVal = MXC_UART_WriteCharacterRaw((mxc_uart_regs_t *)uart, byte[written]);
427 
428         if (retVal != E_NO_ERROR) {
429             *len = written;
430             return retVal;
431         }
432     }
433 
434     *len = written;
435     return E_NO_ERROR;
436 }
437 
MXC_UART_RevB_ReadRXFIFO(mxc_uart_revb_regs_t * uart,unsigned char * bytes,unsigned int len)438 unsigned int MXC_UART_RevB_ReadRXFIFO(mxc_uart_revb_regs_t *uart, unsigned char *bytes,
439                                       unsigned int len)
440 {
441     unsigned read = 0;
442 
443     for (; read < len; read++) {
444         if (uart->status & MXC_F_UART_REVB_STATUS_RX_EM) {
445             break;
446         }
447 
448         bytes[read] = uart->fifo;
449     }
450 
451     return read;
452 }
453 
MXC_UART_RevB_GetRXFIFOAvailable(mxc_uart_revb_regs_t * uart)454 unsigned int MXC_UART_RevB_GetRXFIFOAvailable(mxc_uart_revb_regs_t *uart)
455 {
456     return (uart->status & MXC_F_UART_REVB_STATUS_RX_LVL) >> MXC_F_UART_REVB_STATUS_RX_LVL_POS;
457 }
458 
MXC_UART_RevB_WriteTXFIFO(mxc_uart_revb_regs_t * uart,const unsigned char * bytes,unsigned int len)459 unsigned int MXC_UART_RevB_WriteTXFIFO(mxc_uart_revb_regs_t *uart, const unsigned char *bytes,
460                                        unsigned int len)
461 {
462     unsigned written = 0;
463 
464     for (; written < len; written++) {
465         if (uart->status & MXC_F_UART_REVB_STATUS_TX_FULL) {
466             break;
467         }
468 
469         uart->fifo = bytes[written];
470     }
471 
472     return written;
473 }
474 
MXC_UART_RevB_GetTXFIFOAvailable(mxc_uart_revb_regs_t * uart)475 unsigned int MXC_UART_RevB_GetTXFIFOAvailable(mxc_uart_revb_regs_t *uart)
476 {
477     int txCnt = (uart->status & MXC_F_UART_REVB_STATUS_TX_LVL) >> MXC_F_UART_REVB_STATUS_TX_LVL_POS;
478     return MXC_UART_FIFO_DEPTH - txCnt;
479 }
480 
MXC_UART_RevB_ClearRXFIFO(mxc_uart_revb_regs_t * uart)481 int MXC_UART_RevB_ClearRXFIFO(mxc_uart_revb_regs_t *uart)
482 {
483     uart->ctrl |= MXC_F_UART_REVB_CTRL_RX_FLUSH;
484     while (!(uart->status & MXC_F_UART_REVB_STATUS_RX_EM)) {}
485 
486     return E_NO_ERROR;
487 }
488 
MXC_UART_RevB_ClearTXFIFO(mxc_uart_revb_regs_t * uart)489 int MXC_UART_RevB_ClearTXFIFO(mxc_uart_revb_regs_t *uart)
490 {
491     uart->ctrl |= MXC_F_UART_REVB_CTRL_TX_FLUSH;
492     while (uart->ctrl & MXC_F_UART_REVB_CTRL_TX_FLUSH) {}
493 
494     return E_NO_ERROR;
495 }
496 
MXC_UART_RevB_SetRXThreshold(mxc_uart_revb_regs_t * uart,unsigned int numBytes)497 int MXC_UART_RevB_SetRXThreshold(mxc_uart_revb_regs_t *uart, unsigned int numBytes)
498 {
499     if (numBytes < 1 || numBytes > MXC_UART_FIFO_DEPTH) {
500         return E_BAD_PARAM;
501     }
502 
503     numBytes <<= MXC_F_UART_REVB_CTRL_RX_THD_VAL_POS;
504     MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVB_CTRL_RX_THD_VAL, numBytes);
505 
506     return E_NO_ERROR;
507 }
508 
MXC_UART_RevB_GetRXThreshold(mxc_uart_revb_regs_t * uart)509 unsigned int MXC_UART_RevB_GetRXThreshold(mxc_uart_revb_regs_t *uart)
510 {
511     return ((uart->ctrl & MXC_F_UART_REVB_CTRL_RX_THD_VAL) >> MXC_F_UART_REVB_CTRL_RX_THD_VAL_POS);
512 }
513 
MXC_UART_RevB_GetFlags(mxc_uart_revb_regs_t * uart)514 unsigned int MXC_UART_RevB_GetFlags(mxc_uart_revb_regs_t *uart)
515 {
516     return uart->int_fl;
517 }
518 
MXC_UART_RevB_ClearFlags(mxc_uart_revb_regs_t * uart,unsigned int flags)519 int MXC_UART_RevB_ClearFlags(mxc_uart_revb_regs_t *uart, unsigned int flags)
520 {
521     uart->int_fl = flags;
522 
523     return E_NO_ERROR;
524 }
525 
MXC_UART_RevB_EnableInt(mxc_uart_revb_regs_t * uart,unsigned int intEn)526 int MXC_UART_RevB_EnableInt(mxc_uart_revb_regs_t *uart, unsigned int intEn)
527 {
528     uart->int_en |= intEn;
529 
530     return E_NO_ERROR;
531 }
532 
MXC_UART_RevB_DisableInt(mxc_uart_revb_regs_t * uart,unsigned int intDis)533 int MXC_UART_RevB_DisableInt(mxc_uart_revb_regs_t *uart, unsigned int intDis)
534 {
535     uart->int_en &= ~intDis;
536 
537     return E_NO_ERROR;
538 }
539 
MXC_UART_RevB_GetStatus(mxc_uart_revb_regs_t * uart)540 unsigned int MXC_UART_RevB_GetStatus(mxc_uart_revb_regs_t *uart)
541 {
542     return uart->status;
543 }
544 
MXC_UART_RevB_Transaction(mxc_uart_revb_req_t * req)545 int MXC_UART_RevB_Transaction(mxc_uart_revb_req_t *req)
546 {
547     uint32_t numToWrite, numToRead;
548 
549     if (MXC_UART_GET_IDX((mxc_uart_regs_t *)(req->uart)) < 0) {
550         return E_BAD_PARAM;
551     }
552 
553     MXC_UART_DisableInt((mxc_uart_regs_t *)(req->uart), 0xFFFFFFFF);
554     MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart), 0xFFFFFFFF);
555 
556     req->txCnt = 0;
557     req->rxCnt = 0;
558 
559     if (req->rxLen) {
560         if (req->rxData == NULL) {
561             return E_BAD_PARAM;
562         }
563     }
564 
565     if (req->txLen) {
566         if (req->txData == NULL) {
567             return E_BAD_PARAM;
568         }
569 
570         numToWrite = MXC_UART_GetTXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
571         numToWrite = numToWrite > (req->txLen - req->txCnt) ? req->txLen - req->txCnt : numToWrite;
572         req->txCnt += MXC_UART_WriteTXFIFO((mxc_uart_regs_t *)(req->uart), &req->txData[req->txCnt],
573                                            numToWrite);
574 
575         while (req->txCnt < req->txLen) {
576             while (!(MXC_UART_GetFlags((mxc_uart_regs_t *)(req->uart)) &
577                      MXC_F_UART_REVB_INT_FL_TX_HE) &&
578                    !(req->uart->status & MXC_F_UART_REVB_STATUS_TX_EM)) {}
579 
580             numToWrite = MXC_UART_GetTXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
581             numToWrite = numToWrite > (req->txLen - req->txCnt) ? req->txLen - req->txCnt :
582                                                                   numToWrite;
583             req->txCnt += MXC_UART_WriteTXFIFO((mxc_uart_regs_t *)(req->uart),
584                                                &req->txData[req->txCnt], numToWrite);
585             MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart), MXC_F_UART_REVB_INT_FL_TX_HE);
586         }
587     }
588 
589     if (req->rxLen) {
590         numToRead = MXC_UART_GetRXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
591         numToRead = numToRead > (req->rxLen - req->rxCnt) ? req->rxLen - req->rxCnt : numToRead;
592         req->rxCnt += MXC_UART_ReadRXFIFO((mxc_uart_regs_t *)(req->uart), &req->rxData[req->rxCnt],
593                                           numToRead);
594 
595         while (req->rxCnt < req->rxLen) {
596             while (!(MXC_UART_GetFlags((mxc_uart_regs_t *)(req->uart)) &
597                      MXC_F_UART_REVB_INT_FL_RX_THD)) {}
598 
599             numToRead = MXC_UART_GetRXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
600             numToRead = numToRead > (req->rxLen - req->rxCnt) ? req->rxLen - req->rxCnt : numToRead;
601             req->rxCnt += MXC_UART_ReadRXFIFO((mxc_uart_regs_t *)(req->uart),
602                                               &req->rxData[req->rxCnt], numToRead);
603             MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart), MXC_F_UART_REVB_INT_FL_RX_THD);
604         }
605     }
606 
607     return E_NO_ERROR;
608 }
609 
MXC_UART_RevB_TransactionAsync(mxc_uart_revb_req_t * req)610 int MXC_UART_RevB_TransactionAsync(mxc_uart_revb_req_t *req)
611 {
612     uint32_t numToWrite, numToRead;
613     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)(req->uart));
614 
615     if (!AsyncTxRequests[uart_num] && !AsyncRxRequests[uart_num]) {
616         /* No requests pending, clear the interrupt state */
617         MXC_UART_DisableInt((mxc_uart_regs_t *)(req->uart), 0xFFFFFFFF);
618         MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart), 0xFFFFFFFF);
619 
620     } else if (AsyncRxRequests[uart_num] && req->rxLen) {
621         /* RX request pending */
622         return E_BUSY;
623     } else if (AsyncTxRequests[uart_num] && req->txLen) {
624         /* TX request pending */
625         return E_BUSY;
626     }
627 
628     req->txCnt = 0;
629     req->rxCnt = 0;
630 
631     if (req->txLen) {
632         if (req->txData == NULL) {
633             return E_BAD_PARAM;
634         }
635 
636         // Save TX Request
637         AsyncTxRequests[MXC_UART_GET_IDX((mxc_uart_regs_t *)(req->uart))] = (void *)req;
638 
639         MXC_UART_EnableInt((mxc_uart_regs_t *)(req->uart), MXC_F_UART_REVB_INT_EN_TX_HE);
640         numToWrite = MXC_UART_GetTXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
641         numToWrite = numToWrite > (req->txLen - req->txCnt) ? req->txLen - req->txCnt : numToWrite;
642         req->txCnt += MXC_UART_WriteTXFIFO((mxc_uart_regs_t *)(req->uart), &req->txData[req->txCnt],
643                                            numToWrite);
644 
645         /* If we're finished writing to the TX FIFO and it's less than half+1 full, pend the interrupt */
646         if ((MXC_UART_GetTXFIFOAvailable((mxc_uart_regs_t *)(req->uart)) >=
647              (MXC_UART_FIFO_DEPTH / 2)) &&
648             (req->txCnt == req->txLen)) {
649             NVIC_SetPendingIRQ(MXC_UART_GET_IRQ(uart_num));
650         }
651     }
652 
653     if (req->rxLen) {
654         if (req->rxData == NULL) {
655             MXC_UART_DisableInt((mxc_uart_regs_t *)(req->uart), 0xFFFFFFFF);
656             MXC_UART_ClearTXFIFO((mxc_uart_regs_t *)(req->uart));
657             return E_BAD_PARAM;
658         }
659 
660         // Save RX Request
661         AsyncRxRequests[MXC_UART_GET_IDX((mxc_uart_regs_t *)(req->uart))] = (void *)req;
662 
663         // All error interrupts are related to RX
664         MXC_UART_EnableInt((mxc_uart_regs_t *)(req->uart), MXC_UART_REVB_ERRINT_EN);
665 
666         MXC_UART_EnableInt((mxc_uart_regs_t *)(req->uart), MXC_F_UART_REVB_INT_EN_RX_THD);
667         numToRead = MXC_UART_GetRXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
668         numToRead = numToRead > (req->rxLen - req->rxCnt) ? req->rxLen - req->rxCnt : numToRead;
669         req->rxCnt += MXC_UART_ReadRXFIFO((mxc_uart_regs_t *)(req->uart), &req->rxData[req->rxCnt],
670                                           numToRead);
671         MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart), MXC_F_UART_REVB_INT_FL_RX_THD);
672     }
673 
674     return E_NO_ERROR;
675 }
676 
MXC_UART_RevB_AsyncTxCallback(mxc_uart_revb_regs_t * uart,int retVal)677 int MXC_UART_RevB_AsyncTxCallback(mxc_uart_revb_regs_t *uart, int retVal)
678 {
679     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
680 
681     mxc_uart_req_t *req = (mxc_uart_req_t *)AsyncTxRequests[uart_num];
682     if ((req != NULL) && (req->callback != NULL)) {
683         AsyncTxRequests[uart_num] = NULL;
684         req->callback(req, retVal);
685     }
686 
687     return E_NO_ERROR;
688 }
689 
MXC_UART_RevB_AsyncRxCallback(mxc_uart_revb_regs_t * uart,int retVal)690 int MXC_UART_RevB_AsyncRxCallback(mxc_uart_revb_regs_t *uart, int retVal)
691 {
692     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
693 
694     mxc_uart_req_t *req = (mxc_uart_req_t *)AsyncRxRequests[uart_num];
695     if ((req != NULL) && (req->callback != NULL)) {
696         AsyncRxRequests[uart_num] = NULL;
697         req->callback(req, retVal);
698     }
699 
700     return E_NO_ERROR;
701 }
702 
MXC_UART_RevB_AsyncCallback(mxc_uart_revb_regs_t * uart,int retVal)703 int MXC_UART_RevB_AsyncCallback(mxc_uart_revb_regs_t *uart, int retVal)
704 {
705     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
706 
707     MXC_UART_RevB_AsyncTxCallback(uart, retVal);
708 
709     /* Only call the callback once if it's for the same request */
710     if (AsyncRxRequests[uart_num] != AsyncTxRequests[uart_num]) {
711         MXC_UART_RevB_AsyncRxCallback(uart, retVal);
712     }
713 
714     return E_NO_ERROR;
715 }
716 
MXC_UART_RevB_AsyncStopTx(mxc_uart_revb_regs_t * uart)717 int MXC_UART_RevB_AsyncStopTx(mxc_uart_revb_regs_t *uart)
718 {
719     MXC_UART_DisableInt((mxc_uart_regs_t *)uart, MXC_F_UART_REVB_INT_EN_TX_HE);
720 
721     return E_NO_ERROR;
722 }
723 
MXC_UART_RevB_AsyncStopRx(mxc_uart_revb_regs_t * uart)724 int MXC_UART_RevB_AsyncStopRx(mxc_uart_revb_regs_t *uart)
725 {
726     MXC_UART_DisableInt((mxc_uart_regs_t *)uart, MXC_UART_REVB_ERRINT_EN);
727 
728     return E_NO_ERROR;
729 }
730 
MXC_UART_RevB_AsyncStop(mxc_uart_revb_regs_t * uart)731 int MXC_UART_RevB_AsyncStop(mxc_uart_revb_regs_t *uart)
732 {
733     MXC_UART_DisableInt((mxc_uart_regs_t *)uart, 0xFFFFFFFF);
734 
735     return E_NO_ERROR;
736 }
737 
MXC_UART_RevB_AbortAsync(mxc_uart_revb_regs_t * uart)738 int MXC_UART_RevB_AbortAsync(mxc_uart_revb_regs_t *uart)
739 {
740     MXC_UART_AsyncStop((mxc_uart_regs_t *)uart);
741     MXC_UART_AsyncCallback((mxc_uart_regs_t *)uart, E_ABORT);
742 
743     return E_NO_ERROR;
744 }
745 
MXC_UART_RevB_AsyncHandler(mxc_uart_revb_regs_t * uart)746 int MXC_UART_RevB_AsyncHandler(mxc_uart_revb_regs_t *uart)
747 {
748     uint32_t numToWrite, numToRead, flags;
749     mxc_uart_req_t *req;
750 
751     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
752 
753     flags = MXC_UART_GetFlags((mxc_uart_regs_t *)uart);
754 
755     /* Unexpected interrupt */
756     if (!AsyncTxRequests[uart_num] && !AsyncRxRequests[uart_num]) {
757         MXC_UART_ClearFlags((mxc_uart_regs_t *)uart, uart->int_fl);
758         return E_INVALID;
759     }
760 
761     if (flags & MXC_UART_REVB_ERRINT_FL & uart->int_en) {
762         MXC_UART_AsyncStop((mxc_uart_regs_t *)uart);
763         MXC_UART_AsyncCallback((mxc_uart_regs_t *)uart, E_COMM_ERR);
764         return E_INVALID;
765     }
766 
767     req = (mxc_uart_req_t *)AsyncTxRequests[uart_num];
768     if ((req != NULL) && (req->txLen)) {
769         numToWrite = MXC_UART_GetTXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
770         numToWrite = numToWrite > (req->txLen - req->txCnt) ? req->txLen - req->txCnt : numToWrite;
771         numToWrite = MXC_UART_WriteTXFIFO((mxc_uart_regs_t *)(req->uart), &req->txData[req->txCnt],
772                                           numToWrite);
773         req->txCnt += numToWrite;
774         MXC_UART_ClearFlags(req->uart, MXC_F_UART_REVB_INT_FL_TX_HE);
775     }
776 
777     req = (mxc_uart_req_t *)AsyncRxRequests[uart_num];
778     if ((req != NULL) && (flags & MXC_F_UART_REVB_INT_FL_RX_THD) && (req->rxLen)) {
779         numToRead = MXC_UART_GetRXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
780         numToRead = numToRead > (req->rxLen - req->rxCnt) ? req->rxLen - req->rxCnt : numToRead;
781         numToRead = MXC_UART_ReadRXFIFO((mxc_uart_regs_t *)(req->uart), &req->rxData[req->rxCnt],
782                                         numToRead);
783         req->rxCnt += numToRead;
784 
785         if ((req->rxLen - req->rxCnt) < MXC_UART_GetRXThreshold((mxc_uart_regs_t *)(req->uart))) {
786             MXC_UART_SetRXThreshold((mxc_uart_regs_t *)(req->uart), req->rxLen - req->rxCnt);
787         }
788 
789         MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart), MXC_F_UART_REVB_INT_FL_RX_THD);
790     }
791 
792     if (AsyncRxRequests[uart_num] == AsyncTxRequests[uart_num]) {
793         if ((req != NULL) && (req->rxCnt == req->rxLen) && (req->txCnt == req->txLen)) {
794             MXC_UART_AsyncStop((mxc_uart_regs_t *)uart);
795             MXC_UART_AsyncCallback((mxc_uart_regs_t *)uart, E_NO_ERROR);
796         }
797         return E_NO_ERROR;
798     }
799 
800     req = (mxc_uart_req_t *)AsyncRxRequests[uart_num];
801     if ((req != NULL) && (req->rxCnt == req->rxLen)) {
802         MXC_UART_RevB_AsyncStopRx(uart);
803         MXC_UART_RevB_AsyncRxCallback(uart, E_NO_ERROR);
804         return E_NO_ERROR;
805     }
806 
807     req = (mxc_uart_req_t *)AsyncTxRequests[uart_num];
808     if ((req != NULL) && (req->txCnt == req->txLen)) {
809         MXC_UART_RevB_AsyncStopTx(uart);
810         MXC_UART_RevB_AsyncTxCallback(uart, E_NO_ERROR);
811         return E_NO_ERROR;
812     }
813 
814     return E_NO_ERROR;
815 }
816 
MXC_UART_RevB_SetAutoDMAHandlers(mxc_uart_revb_regs_t * uart,bool enable)817 int MXC_UART_RevB_SetAutoDMAHandlers(mxc_uart_revb_regs_t *uart, bool enable)
818 {
819     int n = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
820     MXC_ASSERT(n >= 0);
821 
822     states[n].auto_dma_handlers = enable;
823 
824     return E_NO_ERROR;
825 }
826 
MXC_UART_RevB_DMA_SetupAutoHandlers(unsigned int channel)827 void MXC_UART_RevB_DMA_SetupAutoHandlers(unsigned int channel)
828 {
829 #ifdef __arm__
830     NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(channel));
831     MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(channel), MXC_DMA_Handler);
832 #else
833     // TODO(JC): RISC-V
834 
835 #endif // __arm__
836 }
837 
MXC_UART_RevB_SetTXDMAChannel(mxc_uart_revb_regs_t * uart,unsigned int channel)838 int MXC_UART_RevB_SetTXDMAChannel(mxc_uart_revb_regs_t *uart, unsigned int channel)
839 {
840     int n = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
841 
842     states[n].channelTx = channel;
843 
844     return E_NO_ERROR;
845 }
846 
MXC_UART_RevB_GetTXDMAChannel(mxc_uart_revb_regs_t * uart)847 int MXC_UART_RevB_GetTXDMAChannel(mxc_uart_revb_regs_t *uart)
848 {
849     int n = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
850 
851     return states[n].channelTx;
852 }
853 
MXC_UART_RevB_SetRXDMAChannel(mxc_uart_revb_regs_t * uart,unsigned int channel)854 int MXC_UART_RevB_SetRXDMAChannel(mxc_uart_revb_regs_t *uart, unsigned int channel)
855 {
856     int n = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
857 
858     states[n].channelRx = channel;
859 
860     return E_NO_ERROR;
861 }
862 
MXC_UART_RevB_GetRXDMAChannel(mxc_uart_revb_regs_t * uart)863 int MXC_UART_RevB_GetRXDMAChannel(mxc_uart_revb_regs_t *uart)
864 {
865     int n = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
866 
867     return states[n].channelRx;
868 }
869 
MXC_UART_RevB_ReadRXFIFODMA(mxc_uart_revb_regs_t * uart,unsigned char * bytes,unsigned int len,mxc_uart_dma_complete_cb_t callback,mxc_dma_config_t config)870 int MXC_UART_RevB_ReadRXFIFODMA(mxc_uart_revb_regs_t *uart, unsigned char *bytes, unsigned int len,
871                                 mxc_uart_dma_complete_cb_t callback, mxc_dma_config_t config)
872 {
873     uint8_t channel;
874     mxc_dma_srcdst_t srcdst;
875 
876     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
877 
878     if (bytes == NULL) {
879         return E_NULL_PTR;
880     }
881 
882     if (states[uart_num].auto_dma_handlers && states[uart_num].channelRx < 0) {
883         /* Acquire channel if we don't have one already */
884         channel = MXC_DMA_AcquireChannel();
885         MXC_UART_RevB_SetRXDMAChannel(uart, channel);
886         MXC_UART_RevB_DMA_SetupAutoHandlers(channel);
887     } else {
888         if (states[uart_num].channelRx < 0)
889             return E_BAD_STATE;
890         channel = MXC_UART_RevB_GetRXDMAChannel(uart);
891     }
892 
893     config.ch = channel;
894 
895     config.srcwd = MXC_DMA_WIDTH_BYTE;
896     config.dstwd = MXC_DMA_WIDTH_BYTE;
897 
898     config.srcinc_en = 0;
899     config.dstinc_en = 1;
900 
901     srcdst.ch = channel;
902     srcdst.dest = bytes;
903     srcdst.len = len;
904 
905     states[uart_num].channelRx = channel;
906     MXC_DMA_ConfigChannel(config, srcdst);
907     MXC_DMA_SetCallback(channel, MXC_UART_DMACallback);
908     MXC_DMA_EnableInt(channel);
909     MXC_DMA_Start(channel);
910     //MXC_DMA->ch[channel].ctrl |= MXC_F_DMA_CTRL_CTZ_IE;
911     MXC_DMA_SetChannelInterruptEn(channel, 0, 1);
912     uart->dma |= MXC_F_UART_REVB_DMA_RX_EN;
913 
914     return E_NO_ERROR;
915 }
916 
MXC_UART_RevB_WriteTXFIFODMA(mxc_uart_revb_regs_t * uart,const unsigned char * bytes,unsigned int len,mxc_uart_dma_complete_cb_t callback,mxc_dma_config_t config)917 int MXC_UART_RevB_WriteTXFIFODMA(mxc_uart_revb_regs_t *uart, const unsigned char *bytes,
918                                  unsigned int len, mxc_uart_dma_complete_cb_t callback,
919                                  mxc_dma_config_t config)
920 {
921     uint8_t channel;
922     mxc_dma_srcdst_t srcdst;
923 
924     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
925 
926     if (bytes == NULL) {
927         return E_NULL_PTR;
928     }
929 
930     if (states[uart_num].auto_dma_handlers && states[uart_num].channelTx < 0) {
931         /* Acquire channel if we don't have one already */
932         channel = MXC_DMA_AcquireChannel();
933         MXC_UART_RevB_SetTXDMAChannel(uart, channel);
934         MXC_UART_RevB_DMA_SetupAutoHandlers(channel);
935     } else {
936         if (states[uart_num].channelTx < 0)
937             return E_BAD_STATE;
938         channel = MXC_UART_RevB_GetTXDMAChannel(uart);
939     }
940 
941     config.ch = channel;
942 
943     config.srcwd = MXC_DMA_WIDTH_BYTE;
944     config.dstwd = MXC_DMA_WIDTH_BYTE;
945 
946     config.srcinc_en = 1;
947     config.dstinc_en = 0;
948 
949     srcdst.ch = channel;
950     srcdst.source = (void *)bytes;
951     srcdst.len = len;
952 
953     states[uart_num].channelTx = channel;
954     MXC_DMA_ConfigChannel(config, srcdst);
955     MXC_DMA_SetCallback(channel, MXC_UART_DMACallback);
956     MXC_DMA_EnableInt(channel);
957     MXC_DMA_Start(channel);
958     //MXC_DMA->ch[channel].ctrl |= MXC_F_DMA_CTRL_CTZ_IE;
959     MXC_DMA_SetChannelInterruptEn(channel, 0, 1);
960     uart->dma |= MXC_F_UART_REVB_DMA_TX_EN;
961 
962     return E_NO_ERROR;
963 }
964 
MXC_UART_RevB_TransactionDMA(mxc_uart_revb_req_t * req)965 int MXC_UART_RevB_TransactionDMA(mxc_uart_revb_req_t *req)
966 {
967     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)(req->uart));
968 
969     if (req->txLen) {
970         if (req->txData == NULL) {
971             return E_BAD_PARAM;
972         }
973     }
974 
975     if (req->rxLen) {
976         if (req->rxData == NULL) {
977             return E_BAD_PARAM;
978         }
979     }
980 
981     MXC_UART_DisableInt((mxc_uart_regs_t *)(req->uart), 0xFFFFFFFF);
982     MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart), 0xFFFFFFFF);
983 
984     // Clearing the RX FIFOs here makes RX-only or TX-only
985     // transactions half-duplex.  Commenting out for now.
986     // MXC_UART_ClearTXFIFO((mxc_uart_regs_t *)(req->uart));
987     // MXC_UART_ClearRXFIFO((mxc_uart_regs_t *)(req->uart));
988 
989     //Set DMA FIFO threshold
990     (req->uart)->dma |= (1 << MXC_F_UART_REVB_DMA_RX_THD_VAL_POS);
991     (req->uart)->dma |= (2 << MXC_F_UART_REVB_DMA_TX_THD_VAL_POS);
992 
993     MXC_DMA_Init();
994 
995     // Reset rx/tx counters,
996     req->rxCnt = 0;
997     req->txCnt = 0;
998 
999     //tx
1000     if ((req->txData != NULL) && (req->txLen)) {
1001         /* Save TX req, the DMA handler will use this later. */
1002         states[uart_num].tx_req = req;
1003         if (MXC_UART_WriteTXFIFODMA((mxc_uart_regs_t *)(req->uart), req->txData, req->txLen,
1004                                     NULL) != E_NO_ERROR) {
1005             return E_BAD_PARAM;
1006         }
1007     }
1008 
1009     //rx
1010     if ((req->rxData != NULL) && (req->rxLen)) {
1011         states[uart_num].rx_req = req;
1012         if (MXC_UART_ReadRXFIFODMA((mxc_uart_regs_t *)(req->uart), req->rxData, req->rxLen, NULL) !=
1013             E_NO_ERROR) {
1014             return E_BAD_PARAM;
1015         }
1016     }
1017 
1018     return E_NO_ERROR;
1019 }
1020 
MXC_UART_RevB_DMACallback(int ch,int error)1021 void MXC_UART_RevB_DMACallback(int ch, int error)
1022 {
1023     mxc_uart_revb_req_t *temp_req;
1024 
1025     for (int i = 0; i < MXC_UART_INSTANCES; i++) {
1026         if (states[i].channelTx == ch) {
1027             /* Populate txLen.  The number of "remainder" bytes is what's left on the
1028             DMA channel's count register. */
1029             states[i].tx_req->txCnt = states[i].tx_req->txLen - MXC_DMA->ch[ch].cnt;
1030 
1031             temp_req = states[i].tx_req;
1032 
1033             if (states[i].auto_dma_handlers) {
1034                 /* Release channel _before_ running callback in case
1035                 user wants to start another transaction inside it */
1036                 MXC_DMA_ReleaseChannel(ch);
1037                 states[i].channelTx = -1;
1038             }
1039 
1040             if (temp_req->callback != NULL &&
1041                 ((states[i].tx_req->rxCnt == states[i].tx_req->rxLen) ||
1042                  states[i].tx_req->rxData == NULL)) {
1043                 /* Only call TX callback if RX component is complete/disabled. Note that
1044                 we are checking the request associated with the _channel_ assignment, not
1045                 the other side of the state struct. */
1046                 temp_req->callback((mxc_uart_req_t *)temp_req, E_NO_ERROR);
1047             }
1048             break;
1049         } else if (states[i].channelRx == ch) {
1050             /* Same as above, but for RX */
1051             states[i].rx_req->rxCnt = states[i].rx_req->rxLen - MXC_DMA->ch[ch].cnt;
1052             temp_req = states[i].rx_req;
1053             if (states[i].auto_dma_handlers) {
1054                 MXC_DMA_ReleaseChannel(ch);
1055                 states[i].channelRx = -1;
1056             }
1057 
1058             if (temp_req->callback != NULL &&
1059                 ((states[i].rx_req->txCnt == states[i].rx_req->txLen) ||
1060                  states[i].rx_req->txData == NULL)) {
1061                 temp_req->callback((mxc_uart_req_t *)temp_req, E_NO_ERROR);
1062             }
1063             break;
1064         }
1065     }
1066 }
1067