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_reva.h"
26 #include "dma.h"
27 #ifdef __arm__
28 #include "nvic_table.h"
29 #endif
30 
31 /* **** Definitions **** */
32 #define MXC_UART_REVA_ERRINT_EN                                                       \
33     (MXC_F_UART_REVA_INT_EN_RX_FRAME_ERROR | MXC_F_UART_REVA_INT_EN_RX_PARITY_ERROR | \
34      MXC_F_UART_REVA_INT_EN_RX_OVERRUN)
35 
36 #define MXC_UART_REVA_ERRINT_FL                                                       \
37     (MXC_F_UART_REVA_INT_FL_RX_FRAME_ERROR | MXC_F_UART_REVA_INT_FL_RX_PARITY_ERROR | \
38      MXC_F_UART_REVA_INT_FL_RX_OVERRUN)
39 
40 /* **** Variable Declaration **** */
41 static void *TxAsyncRequests[MXC_UART_INSTANCES];
42 static void *RxAsyncRequests[MXC_UART_INSTANCES];
43 
44 // Structure to save DMA state
45 typedef struct {
46     mxc_uart_reva_req_t *tx_req;
47     mxc_uart_reva_req_t *rx_req;
48     int channelTx;
49     int channelRx;
50     bool auto_dma_handlers;
51 } uart_reva_req_state_t;
52 
53 uart_reva_req_state_t states[MXC_UART_INSTANCES];
54 
55 /* **** Function Prototypes **** */
56 
57 /* ************************************************************************* */
58 /* Control/Configuration functions                                           */
59 /* ************************************************************************* */
MXC_UART_RevA_Init(mxc_uart_reva_regs_t * uart,unsigned int baud)60 int MXC_UART_RevA_Init(mxc_uart_reva_regs_t *uart, unsigned int baud)
61 {
62     int err;
63 
64     MXC_ASSERT(MXC_UART_GET_IDX((mxc_uart_regs_t *)uart) >= 0)
65 
66     // Initialize UART
67     // Set RX threshold to 1 byte
68     if ((err = (MXC_UART_SetRXThreshold((mxc_uart_regs_t *)uart, 1))) != E_NO_ERROR) {
69         return err;
70     }
71 
72     // Set TX threshold to 2 byte
73     if ((err = (MXC_UART_SetTXThreshold((mxc_uart_regs_t *)uart, 2))) != E_NO_ERROR) {
74         return err;
75     }
76 
77     // Set Datasize to 8 bits
78     if ((err = (MXC_UART_SetDataSize((mxc_uart_regs_t *)uart, 8))) != E_NO_ERROR) {
79         return err;
80     }
81 
82     if ((err = (MXC_UART_SetParity((mxc_uart_regs_t *)uart, MXC_UART_PARITY_DISABLE))) !=
83         E_NO_ERROR) {
84         return err;
85     }
86 
87     if ((err = (MXC_UART_SetStopBits((mxc_uart_regs_t *)uart, MXC_UART_STOP_1))) != E_NO_ERROR) {
88         return err;
89     }
90 
91     uart->ctrl |= MXC_F_UART_REVA_CTRL_ENABLE;
92 
93     MXC_UART_SetFrequency((mxc_uart_regs_t *)uart, baud);
94 
95     // Initialize state struct
96     unsigned int i = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
97     states[i].channelRx = -1;
98     states[i].channelTx = -1;
99     states[i].tx_req = NULL;
100     states[i].rx_req = NULL;
101     states[i].auto_dma_handlers = false;
102 
103     return E_NO_ERROR;
104 }
105 
MXC_UART_RevA_ReadyForSleep(mxc_uart_reva_regs_t * uart)106 int MXC_UART_RevA_ReadyForSleep(mxc_uart_reva_regs_t *uart)
107 {
108     if (TxAsyncRequests[MXC_UART_GET_IDX((mxc_uart_regs_t *)uart)] != NULL) {
109         return E_BUSY;
110     }
111 
112     /* We can sleep if waiting for RX Async */
113 
114     return MXC_UART_GetActive((mxc_uart_regs_t *)uart);
115 }
116 
MXC_UART_RevA_SetFrequency(mxc_uart_reva_regs_t * uart,unsigned int baud)117 int MXC_UART_RevA_SetFrequency(mxc_uart_reva_regs_t *uart, unsigned int baud)
118 {
119     float uartDiv;
120     int periphClock;
121     int prescale;
122     int decimalDiv;
123 
124     if (uart->ctrl & MXC_F_UART_REVA_CTRL_CLKSEL) {
125 #ifdef IBRO_FREQ
126         periphClock = IBRO_FREQ;
127 #else
128         return E_BAD_PARAM;
129 #endif
130     } else {
131         periphClock = PeripheralClock;
132     }
133 
134     uartDiv = (float)periphClock / baud;
135 
136     // Find the largest value of prescale that keeps div > 1
137     for (prescale = 8; prescale <= 128; prescale = prescale << 1) {
138         if (uartDiv / (float)prescale < 1) {
139             prescale = prescale >> 1;
140             break;
141         }
142     }
143 
144     if (prescale > 128) {
145         prescale = 128;
146     }
147 
148     if (prescale < 8) {
149         return E_BAD_PARAM;
150     }
151 
152     uartDiv /= prescale;
153     decimalDiv = (int)((uartDiv - (int)uartDiv) * 128);
154 
155     // Work around for Jira Bug: ME10-650
156     if (decimalDiv > 3) {
157         decimalDiv -= 3;
158     } else {
159         decimalDiv += 3;
160     }
161 
162     switch (prescale) {
163     case 8:
164         prescale = 4;
165         break;
166 
167     case 16:
168         prescale = 3;
169         break;
170 
171     case 32:
172         prescale = 2;
173         break;
174 
175     case 64:
176         prescale = 1;
177         break;
178 
179     case 128:
180         prescale = 0;
181         break;
182 
183     default:
184         return E_UNKNOWN;
185         break;
186     }
187 
188     prescale <<= MXC_F_UART_REVA_BAUD0_FACTOR_POS;
189     decimalDiv <<= MXC_F_UART_REVA_BAUD1_DBAUD_POS;
190 
191     MXC_SETFIELD(uart->baud0, MXC_F_UART_REVA_BAUD0_FACTOR, prescale);
192     MXC_SETFIELD(uart->baud0, MXC_F_UART_REVA_BAUD0_IBAUD,
193                  (((int)uartDiv) << MXC_F_UART_REVA_BAUD0_IBAUD_POS));
194     MXC_SETFIELD(uart->baud1, MXC_F_UART_REVA_BAUD1_DBAUD, decimalDiv);
195 
196     return MXC_UART_GetFrequency((mxc_uart_regs_t *)uart);
197 }
198 
MXC_UART_RevA_GetFrequency(mxc_uart_reva_regs_t * uart)199 int MXC_UART_RevA_GetFrequency(mxc_uart_reva_regs_t *uart)
200 {
201     int periphClock = 0;
202     float uartDiv = 0;
203     float decimalDiv = 0;
204 
205     if (uart->ctrl & MXC_F_UART_REVA_CTRL_CLKSEL) {
206 #ifdef IBRO_FREQ
207         periphClock = IBRO_FREQ;
208 #else
209         return E_BAD_PARAM;
210 #endif
211     } else {
212         periphClock = PeripheralClock;
213     }
214 
215     uartDiv += uart->baud0 & MXC_F_UART_REVA_BAUD0_IBAUD;
216     decimalDiv = uart->baud1 & MXC_F_UART_REVA_BAUD1_DBAUD;
217 
218     // Based on work around for Jira Bug: ME10-650
219     // No way to tell if the SetFrequency function added or
220     //      subtracted 3 in this range
221     if (decimalDiv > 3 && decimalDiv <= 6) {
222         decimalDiv -= 3;
223     } else {
224         decimalDiv += 3;
225     }
226 
227     uartDiv += decimalDiv / (float)128;
228     uartDiv *= (1 << (7 - (uart->baud0 & MXC_F_UART_REVA_BAUD0_FACTOR)));
229 
230     return (int)((float)periphClock / uartDiv);
231 }
232 
MXC_UART_RevA_SetDataSize(mxc_uart_reva_regs_t * uart,int dataSize)233 int MXC_UART_RevA_SetDataSize(mxc_uart_reva_regs_t *uart, int dataSize)
234 {
235     if (dataSize < 5 || dataSize > 8) {
236         return E_BAD_PARAM;
237     }
238 
239     dataSize = (dataSize - 5) << MXC_F_UART_REVA_CTRL_CHAR_SIZE_POS;
240 
241     MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_CHAR_SIZE, dataSize);
242 
243     return E_NO_ERROR;
244 }
245 
MXC_UART_RevA_SetStopBits(mxc_uart_reva_regs_t * uart,mxc_uart_stop_t stopBits)246 int MXC_UART_RevA_SetStopBits(mxc_uart_reva_regs_t *uart, mxc_uart_stop_t stopBits)
247 {
248     switch (stopBits) {
249     case MXC_UART_STOP_1:
250         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_STOPBITS,
251                      0 << MXC_F_UART_REVA_CTRL_STOPBITS_POS);
252         break;
253 
254     case MXC_UART_STOP_2:
255         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_STOPBITS,
256                      1 << MXC_F_UART_REVA_CTRL_STOPBITS_POS);
257         break;
258 
259     default:
260         return E_BAD_PARAM;
261         break;
262     }
263 
264     return E_NO_ERROR;
265 }
266 
MXC_UART_RevA_SetParity(mxc_uart_reva_regs_t * uart,mxc_uart_parity_t parity)267 int MXC_UART_RevA_SetParity(mxc_uart_reva_regs_t *uart, mxc_uart_parity_t parity)
268 {
269     switch (parity) {
270     case MXC_UART_PARITY_DISABLE:
271         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARITY_EN,
272                      0 << MXC_F_UART_REVA_CTRL_PARITY_EN_POS);
273         break;
274 
275     case MXC_UART_PARITY_EVEN:
276     case MXC_UART_PARITY_EVEN_0:
277         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARITY_EN,
278                      1 << MXC_F_UART_REVA_CTRL_PARITY_EN_POS);
279         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARITY, MXC_S_UART_REVA_CTRL_PARITY_EVEN);
280         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARMD, 0 << MXC_F_UART_REVA_CTRL_PARMD_POS);
281         break;
282 
283     case MXC_UART_PARITY_EVEN_1:
284         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARITY_EN,
285                      1 << MXC_F_UART_REVA_CTRL_PARITY_EN_POS);
286         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARITY, MXC_S_UART_REVA_CTRL_PARITY_EVEN);
287         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARMD, 1 << MXC_F_UART_REVA_CTRL_PARMD_POS);
288         break;
289 
290     case MXC_UART_PARITY_ODD:
291     case MXC_UART_PARITY_ODD_0:
292         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARITY_EN,
293                      1 << MXC_F_UART_REVA_CTRL_PARITY_EN_POS);
294         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARITY, MXC_S_UART_REVA_CTRL_PARITY_ODD);
295         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARMD, 0 << MXC_F_UART_REVA_CTRL_PARMD_POS);
296         break;
297 
298     case MXC_UART_PARITY_ODD_1:
299         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARITY_EN,
300                      1 << MXC_F_UART_REVA_CTRL_PARITY_EN_POS);
301         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARITY, MXC_S_UART_REVA_CTRL_PARITY_ODD);
302         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARMD, 1 << MXC_F_UART_REVA_CTRL_PARMD_POS);
303         break;
304 
305     case MXC_UART_PARITY_MARK:
306     case MXC_UART_PARITY_MARK_0:
307         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARITY_EN,
308                      1 << MXC_F_UART_REVA_CTRL_PARITY_EN_POS);
309         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARITY, MXC_S_UART_REVA_CTRL_PARITY_MARK);
310         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARMD, 0 << MXC_F_UART_REVA_CTRL_PARMD_POS);
311         break;
312 
313     case MXC_UART_PARITY_MARK_1:
314         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARITY_EN,
315                      1 << MXC_F_UART_REVA_CTRL_PARITY_EN_POS);
316         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARITY, MXC_S_UART_REVA_CTRL_PARITY_MARK);
317         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARMD, 1 << MXC_F_UART_REVA_CTRL_PARMD_POS);
318         break;
319 
320     case MXC_UART_PARITY_SPACE:
321     case MXC_UART_PARITY_SPACE_0:
322         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARITY_EN,
323                      1 << MXC_F_UART_REVA_CTRL_PARITY_EN_POS);
324         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARITY, MXC_S_UART_REVA_CTRL_PARITY_SPACE);
325         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARMD, 0 << MXC_F_UART_REVA_CTRL_PARMD_POS);
326         break;
327 
328     case MXC_UART_PARITY_SPACE_1:
329         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARITY_EN,
330                      1 << MXC_F_UART_REVA_CTRL_PARITY_EN_POS);
331         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARITY, MXC_S_UART_REVA_CTRL_PARITY_SPACE);
332         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_PARMD, 1 << MXC_F_UART_REVA_CTRL_PARMD_POS);
333         break;
334 
335     default:
336         return E_BAD_PARAM;
337         break;
338     }
339 
340     return E_NO_ERROR;
341 }
342 
MXC_UART_RevA_SetFlowCtrl(mxc_uart_reva_regs_t * uart,mxc_uart_flow_t flowCtrl,int rtsThreshold)343 int MXC_UART_RevA_SetFlowCtrl(mxc_uart_reva_regs_t *uart, mxc_uart_flow_t flowCtrl,
344                               int rtsThreshold)
345 {
346     switch (flowCtrl) {
347     case MXC_UART_FLOW_DIS:
348         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_FLOW_CTRL,
349                      0 << MXC_F_UART_REVA_CTRL_FLOW_CTRL_POS);
350         break;
351 
352     case MXC_UART_FLOW_EN_LOW:
353         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_FLOW_CTRL,
354                      1 << MXC_F_UART_REVA_CTRL_FLOW_CTRL_POS);
355         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_FLOW_POL,
356                      0 << MXC_F_UART_REVA_CTRL_FLOW_POL_POS);
357         break;
358 
359     case MXC_UART_FLOW_EN_HIGH:
360         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_FLOW_CTRL,
361                      1 << MXC_F_UART_REVA_CTRL_FLOW_CTRL_POS);
362         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_FLOW_POL,
363                      1 << MXC_F_UART_REVA_CTRL_FLOW_POL_POS);
364         break;
365 
366     default:
367         return E_BAD_PARAM;
368         break;
369     }
370 
371     if (rtsThreshold < 1 || rtsThreshold > MXC_UART_FIFO_DEPTH) {
372         return E_BAD_PARAM;
373     }
374 
375     rtsThreshold <<= MXC_F_UART_REVA_THRESH_CTRL_RTS_FIFO_THRESH_POS;
376     MXC_SETFIELD(uart->thresh_ctrl, MXC_F_UART_REVA_THRESH_CTRL_RTS_FIFO_THRESH, rtsThreshold);
377 
378     return E_NO_ERROR;
379 }
380 
MXC_UART_RevA_SetClockSource(mxc_uart_reva_regs_t * uart,int usePCLK)381 int MXC_UART_RevA_SetClockSource(mxc_uart_reva_regs_t *uart, int usePCLK)
382 {
383     int baudRate;
384 
385     baudRate = MXC_UART_GetFrequency((mxc_uart_regs_t *)uart);
386     if (baudRate < 0) { // return error code
387         return baudRate;
388     }
389 
390     if (usePCLK) {
391         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_CLKSEL, 0 << MXC_F_UART_REVA_CTRL_CLKSEL_POS);
392     } else {
393         MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_CLKSEL, 1 << MXC_F_UART_REVA_CTRL_CLKSEL_POS);
394     }
395 
396     return MXC_UART_SetFrequency((mxc_uart_regs_t *)uart, baudRate);
397 }
398 
MXC_UART_RevA_SetNullModem(mxc_uart_reva_regs_t * uart,int nullModem)399 int MXC_UART_RevA_SetNullModem(mxc_uart_reva_regs_t *uart, int nullModem)
400 {
401     nullModem = (nullModem > 0) << MXC_F_UART_REVA_CTRL_NULL_MODEM_POS;
402 
403     MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_NULL_MODEM, nullModem);
404 
405     return E_NO_ERROR;
406 }
407 
MXC_UART_RevA_SendBreak(mxc_uart_reva_regs_t * uart)408 int MXC_UART_RevA_SendBreak(mxc_uart_reva_regs_t *uart)
409 {
410     MXC_SETFIELD(uart->ctrl, MXC_F_UART_REVA_CTRL_BREAK, 1 << MXC_F_UART_REVA_CTRL_BREAK_POS);
411 
412     return E_NO_ERROR;
413 }
414 
MXC_UART_RevA_GetActive(mxc_uart_reva_regs_t * uart)415 int MXC_UART_RevA_GetActive(mxc_uart_reva_regs_t *uart)
416 {
417     if (uart->status & (MXC_F_UART_REVA_STATUS_TX_BUSY | MXC_F_UART_REVA_STATUS_RX_BUSY)) {
418         return E_BUSY;
419     }
420 
421     return E_NO_ERROR;
422 }
423 
MXC_UART_RevA_AbortTransmission(mxc_uart_reva_regs_t * uart)424 int MXC_UART_RevA_AbortTransmission(mxc_uart_reva_regs_t *uart)
425 {
426     MXC_UART_ClearTXFIFO((mxc_uart_regs_t *)uart);
427     return E_NO_ERROR;
428 }
429 
MXC_UART_RevA_ReadCharacterRaw(mxc_uart_reva_regs_t * uart)430 int MXC_UART_RevA_ReadCharacterRaw(mxc_uart_reva_regs_t *uart)
431 {
432     if (uart->status & MXC_F_UART_REVA_STATUS_RX_EMPTY) {
433         return E_UNDERFLOW;
434     }
435 
436     return uart->fifo;
437 }
438 
MXC_UART_RevA_WriteCharacterRaw(mxc_uart_reva_regs_t * uart,uint8_t character)439 int MXC_UART_RevA_WriteCharacterRaw(mxc_uart_reva_regs_t *uart, uint8_t character)
440 {
441     // Return error if the FIFO is full
442     if (uart->status & MXC_F_UART_REVA_STATUS_TX_FULL) {
443         return E_OVERFLOW;
444     }
445 
446     uart->fifo = character;
447 
448     return E_NO_ERROR;
449 }
450 
MXC_UART_RevA_Read(mxc_uart_reva_regs_t * uart,uint8_t * buffer,int * len)451 int MXC_UART_RevA_Read(mxc_uart_reva_regs_t *uart, uint8_t *buffer, int *len)
452 {
453     int read = 0;
454     int retVal;
455 
456     for (; read < *len; read++) {
457         retVal = MXC_UART_ReadCharacter((mxc_uart_regs_t *)uart);
458 
459         if (retVal < 0) {
460             *len = read;
461             return retVal;
462         } else {
463             buffer[read] = retVal;
464         }
465     }
466 
467     *len = read;
468     return E_NO_ERROR;
469 }
470 
MXC_UART_RevA_Write(mxc_uart_reva_regs_t * uart,uint8_t * byte,int * len)471 int MXC_UART_RevA_Write(mxc_uart_reva_regs_t *uart, uint8_t *byte, int *len)
472 {
473     int written = 0;
474     int retVal;
475 
476     for (; written < *len; written++) {
477         retVal = MXC_UART_WriteCharacter((mxc_uart_regs_t *)uart, byte[written]);
478 
479         if (retVal != E_NO_ERROR) {
480             *len = written;
481             return retVal;
482         }
483     }
484 
485     *len = written;
486     return E_NO_ERROR;
487 }
488 
MXC_UART_RevA_ReadRXFIFO(mxc_uart_reva_regs_t * uart,unsigned char * bytes,unsigned int len)489 unsigned int MXC_UART_RevA_ReadRXFIFO(mxc_uart_reva_regs_t *uart, unsigned char *bytes,
490                                       unsigned int len)
491 {
492     unsigned int read = 0;
493 
494     for (; read < len; read++) {
495         if (uart->status & MXC_F_UART_REVA_STATUS_RX_EMPTY) {
496             break;
497         }
498 
499         bytes[read] = uart->fifo;
500     }
501 
502     return read;
503 }
504 
505 #if MXC_DMA_INSTANCES > 1
506 
MXC_UART_RevA_DMA0_Handler(void)507 void MXC_UART_RevA_DMA0_Handler(void)
508 {
509     MXC_DMA_Handler(MXC_DMA0);
510 }
511 
MXC_UART_RevA_DMA1_Handler(void)512 void MXC_UART_RevA_DMA1_Handler(void)
513 {
514     MXC_DMA_Handler(MXC_DMA1);
515 }
516 
517 #endif
518 
519 /* "Auto" handlers just need to call MXC_DMA_Handler with the correct
520 DMA instance.
521 */
MXC_UART_RevA_DMA_SetupAutoHandlers(mxc_dma_regs_t * dma_instance,unsigned int channel)522 void MXC_UART_RevA_DMA_SetupAutoHandlers(mxc_dma_regs_t *dma_instance, unsigned int channel)
523 {
524 #ifdef __arm__
525     NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(channel));
526 
527 #if MXC_DMA_INSTANCES > 1
528     /* (JC): This is not the cleanest or most scalable way to do this,
529         but I tried defining default handler's in the system file.
530         Some complications make this the most attractive short-term
531         option.  We could handle multiple DMA instances better in the DMA API (See the mismatch between the size of "dma_resource" array and the number of channels per instance, to start)*/
532     if (dma_instance == MXC_DMA0) {
533         MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(channel), MXC_UART_RevA_DMA0_Handler);
534     } else if (dma_instance == MXC_DMA1) {
535         MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(channel), MXC_UART_RevA_DMA1_Handler);
536     }
537 #else
538     // Only one DMA instance, we can point direct to MXC_DMA_Handler
539     MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(channel), MXC_DMA_Handler);
540 #endif // MXC_DMA_INSTANCES > 1
541 
542 #else
543     // TODO(JC): RISC-V
544 
545 #endif // __arm__
546 }
547 
MXC_UART_RevA_ReadRXFIFODMA(mxc_uart_reva_regs_t * uart,mxc_dma_regs_t * dma,unsigned char * bytes,unsigned int len,mxc_uart_dma_complete_cb_t callback,mxc_dma_config_t config)548 int MXC_UART_RevA_ReadRXFIFODMA(mxc_uart_reva_regs_t *uart, mxc_dma_regs_t *dma,
549                                 unsigned char *bytes, unsigned int len,
550                                 mxc_uart_dma_complete_cb_t callback, mxc_dma_config_t config)
551 {
552     uint8_t channel;
553     mxc_dma_srcdst_t srcdst;
554 
555     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
556 
557     if (bytes == NULL) {
558         return E_NULL_PTR;
559     }
560 
561     if (states[uart_num].auto_dma_handlers && states[uart_num].channelRx < 0) {
562         /* Acquire channel if we don't have one already */
563 #if MXC_DMA_INSTANCES > 1
564         channel = MXC_DMA_AcquireChannel(dma);
565 #else
566         channel = MXC_DMA_AcquireChannel();
567 #endif
568         MXC_UART_RevA_SetRXDMAChannel(uart, channel);
569         /* (JC) Since we're automatically acquiring a channel here, we need the ISR for that channel to call MXC_DMA_Handler. */
570         MXC_UART_RevA_DMA_SetupAutoHandlers(dma, channel);
571     } else {
572         /* Rely on application-defined handlers. */
573         if (states[uart_num].channelRx < 0)
574             return E_BAD_STATE;
575         channel = states[uart_num].channelRx;
576     }
577 
578     // states[uart_num].channelRx = channel;
579 
580     config.ch = channel;
581 
582     config.srcwd = MXC_DMA_WIDTH_BYTE;
583     config.dstwd = MXC_DMA_WIDTH_BYTE;
584 
585     config.srcinc_en = 0;
586     config.dstinc_en = 1;
587 
588     srcdst.ch = channel;
589     srcdst.dest = bytes;
590     srcdst.len = len;
591 
592     MXC_DMA_ConfigChannel(config, srcdst);
593     MXC_DMA_SetCallback(channel, MXC_UART_DMACallback);
594     MXC_DMA_EnableInt(channel);
595     MXC_DMA_Start(channel);
596     //MXC_DMA->ch[channel].ctrl |= MXC_F_DMA_CTRL_CTZ_IE;
597     MXC_DMA_SetChannelInterruptEn(channel, 0, 1);
598     uart->dma |= MXC_F_UART_REVA_DMA_RXDMA_EN;
599 
600     return E_NO_ERROR;
601 }
602 
MXC_UART_RevA_GetRXFIFOAvailable(mxc_uart_reva_regs_t * uart)603 unsigned int MXC_UART_RevA_GetRXFIFOAvailable(mxc_uart_reva_regs_t *uart)
604 {
605     return (uart->status & MXC_F_UART_REVA_STATUS_RX_FIFO_CNT) >>
606            MXC_F_UART_REVA_STATUS_RX_FIFO_CNT_POS;
607 }
608 
MXC_UART_RevA_WriteTXFIFO(mxc_uart_reva_regs_t * uart,unsigned char * bytes,unsigned int len)609 unsigned int MXC_UART_RevA_WriteTXFIFO(mxc_uart_reva_regs_t *uart, unsigned char *bytes,
610                                        unsigned int len)
611 {
612     unsigned int written = 0;
613 
614     for (; written < len; written++) {
615         if (uart->status & MXC_F_UART_REVA_STATUS_TX_FULL) {
616             break;
617         }
618 
619         uart->fifo = bytes[written];
620     }
621 
622     return written;
623 }
624 
MXC_UART_RevA_SetAutoDMAHandlers(mxc_uart_reva_regs_t * uart,bool enable)625 int MXC_UART_RevA_SetAutoDMAHandlers(mxc_uart_reva_regs_t *uart, bool enable)
626 {
627     int n = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
628 
629     states[n].auto_dma_handlers = enable;
630 
631     return E_NO_ERROR;
632 }
633 
MXC_UART_RevA_SetTXDMAChannel(mxc_uart_reva_regs_t * uart,unsigned int channel)634 int MXC_UART_RevA_SetTXDMAChannel(mxc_uart_reva_regs_t *uart, unsigned int channel)
635 {
636     int n = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
637 
638     states[n].channelTx = channel;
639 
640     return E_NO_ERROR;
641 }
642 
MXC_UART_RevA_GetTXDMAChannel(mxc_uart_reva_regs_t * uart)643 int MXC_UART_RevA_GetTXDMAChannel(mxc_uart_reva_regs_t *uart)
644 {
645     int n = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
646 
647     return states[n].channelTx;
648 }
649 
MXC_UART_RevA_SetRXDMAChannel(mxc_uart_reva_regs_t * uart,unsigned int channel)650 int MXC_UART_RevA_SetRXDMAChannel(mxc_uart_reva_regs_t *uart, unsigned int channel)
651 {
652     int n = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
653 
654     states[n].channelRx = channel;
655 
656     return E_NO_ERROR;
657 }
658 
MXC_UART_RevA_GetRXDMAChannel(mxc_uart_reva_regs_t * uart)659 int MXC_UART_RevA_GetRXDMAChannel(mxc_uart_reva_regs_t *uart)
660 {
661     int n = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
662 
663     return states[n].channelRx;
664 }
665 
MXC_UART_RevA_WriteTXFIFODMA(mxc_uart_reva_regs_t * uart,mxc_dma_regs_t * dma,unsigned char * bytes,unsigned int len,mxc_uart_dma_complete_cb_t callback,mxc_dma_config_t config)666 unsigned int MXC_UART_RevA_WriteTXFIFODMA(mxc_uart_reva_regs_t *uart, mxc_dma_regs_t *dma,
667                                           unsigned char *bytes, unsigned int len,
668                                           mxc_uart_dma_complete_cb_t callback,
669                                           mxc_dma_config_t config)
670 {
671     int channel = -1;
672     mxc_dma_srcdst_t srcdst;
673 
674     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
675 
676     if (bytes == NULL) {
677         return E_NULL_PTR;
678     }
679 
680     if (states[uart_num].auto_dma_handlers && states[uart_num].channelTx < 0) {
681         /* Acquire channel if we don't have one already */
682 #if TARGET_NUM == 32665
683         channel = MXC_DMA_AcquireChannel(dma);
684 #else
685         channel = MXC_DMA_AcquireChannel();
686 #endif
687         MXC_UART_RevA_SetTXDMAChannel(uart, channel); // Set state variable
688         /* (JC) Since we're automatically acquiring a channel here, we need the ISR for that channel to call MXC_DMA_Handler.*/
689         MXC_UART_RevA_DMA_SetupAutoHandlers(dma, channel);
690     } else {
691         /* Rely on application-defined handlers (from SetTXDMAChannel) */
692         if (states[uart_num].channelTx < 0)
693             return E_BAD_STATE;
694         channel = MXC_UART_RevA_GetTXDMAChannel(uart);
695     }
696 
697     config.ch = channel;
698 
699     config.srcwd = MXC_DMA_WIDTH_BYTE;
700     config.dstwd = MXC_DMA_WIDTH_BYTE;
701 
702     config.srcinc_en = 1;
703     config.dstinc_en = 0;
704 
705     srcdst.ch = channel;
706     srcdst.source = bytes;
707     srcdst.len = len;
708 
709     MXC_DMA_ConfigChannel(config, srcdst);
710     MXC_DMA_SetCallback(channel, MXC_UART_DMACallback);
711     MXC_DMA_EnableInt(channel);
712     MXC_DMA_Start(channel);
713     //MXC_DMA->ch[channel].ctrl |= MXC_F_DMA_CTRL_CTZ_IE;
714     MXC_DMA_SetChannelInterruptEn(channel, 0, 1);
715 
716     uart->dma |= MXC_F_UART_REVA_DMA_TXDMA_EN;
717 
718     return E_NO_ERROR;
719 }
720 
MXC_UART_RevA_GetTXFIFOAvailable(mxc_uart_reva_regs_t * uart)721 unsigned int MXC_UART_RevA_GetTXFIFOAvailable(mxc_uart_reva_regs_t *uart)
722 {
723     int txCnt = (uart->status & MXC_F_UART_REVA_STATUS_TX_FIFO_CNT) >>
724                 MXC_F_UART_REVA_STATUS_TX_FIFO_CNT_POS;
725     return MXC_UART_FIFO_DEPTH - txCnt;
726 }
727 
MXC_UART_RevA_ClearRXFIFO(mxc_uart_reva_regs_t * uart)728 int MXC_UART_RevA_ClearRXFIFO(mxc_uart_reva_regs_t *uart)
729 {
730     uart->ctrl |= MXC_F_UART_REVA_CTRL_RX_FLUSH;
731 
732     while (uart->ctrl & MXC_F_UART_REVA_CTRL_RX_FLUSH) {}
733 
734     return E_NO_ERROR;
735 }
736 
MXC_UART_RevA_ClearTXFIFO(mxc_uart_reva_regs_t * uart)737 int MXC_UART_RevA_ClearTXFIFO(mxc_uart_reva_regs_t *uart)
738 {
739     uart->ctrl |= MXC_F_UART_REVA_CTRL_TX_FLUSH;
740 
741     while (uart->ctrl & MXC_F_UART_REVA_CTRL_TX_FLUSH) {}
742 
743     return E_NO_ERROR;
744 }
745 
MXC_UART_RevA_SetRXThreshold(mxc_uart_reva_regs_t * uart,unsigned int numBytes)746 int MXC_UART_RevA_SetRXThreshold(mxc_uart_reva_regs_t *uart, unsigned int numBytes)
747 {
748     if (numBytes < 1 || numBytes > MXC_UART_FIFO_DEPTH) {
749         return E_BAD_PARAM;
750     }
751 
752     numBytes <<= MXC_F_UART_REVA_THRESH_CTRL_RX_FIFO_THRESH_POS;
753     MXC_SETFIELD(uart->thresh_ctrl, MXC_F_UART_REVA_THRESH_CTRL_RX_FIFO_THRESH, numBytes);
754 
755     return E_NO_ERROR;
756 }
757 
MXC_UART_RevA_GetRXThreshold(mxc_uart_reva_regs_t * uart)758 unsigned int MXC_UART_RevA_GetRXThreshold(mxc_uart_reva_regs_t *uart)
759 {
760     return (uart->thresh_ctrl & MXC_F_UART_REVA_THRESH_CTRL_RX_FIFO_THRESH) >>
761            MXC_F_UART_REVA_THRESH_CTRL_RX_FIFO_THRESH_POS;
762 }
763 
MXC_UART_RevA_SetTXThreshold(mxc_uart_reva_regs_t * uart,unsigned int numBytes)764 int MXC_UART_RevA_SetTXThreshold(mxc_uart_reva_regs_t *uart, unsigned int numBytes)
765 {
766     if (numBytes < 1 || numBytes > MXC_UART_FIFO_DEPTH) {
767         return E_BAD_PARAM;
768     }
769 
770     numBytes <<= MXC_F_UART_REVA_THRESH_CTRL_TX_FIFO_THRESH_POS;
771     MXC_SETFIELD(uart->thresh_ctrl, MXC_F_UART_REVA_THRESH_CTRL_TX_FIFO_THRESH, numBytes);
772 
773     return E_NO_ERROR;
774 }
775 
MXC_UART_RevA_GetTXThreshold(mxc_uart_reva_regs_t * uart)776 unsigned int MXC_UART_RevA_GetTXThreshold(mxc_uart_reva_regs_t *uart)
777 {
778     return (uart->thresh_ctrl & MXC_F_UART_REVA_THRESH_CTRL_TX_FIFO_THRESH) >>
779            MXC_F_UART_REVA_THRESH_CTRL_TX_FIFO_THRESH_POS;
780 }
781 
MXC_UART_RevA_GetFlags(mxc_uart_reva_regs_t * uart)782 unsigned int MXC_UART_RevA_GetFlags(mxc_uart_reva_regs_t *uart)
783 {
784     return uart->int_fl;
785 }
786 
MXC_UART_RevA_ClearFlags(mxc_uart_reva_regs_t * uart,unsigned int flags)787 int MXC_UART_RevA_ClearFlags(mxc_uart_reva_regs_t *uart, unsigned int flags)
788 {
789     uart->int_fl = flags;
790 
791     return E_NO_ERROR;
792 }
793 
MXC_UART_RevA_EnableInt(mxc_uart_reva_regs_t * uart,unsigned int intEn)794 int MXC_UART_RevA_EnableInt(mxc_uart_reva_regs_t *uart, unsigned int intEn)
795 {
796     uart->int_en |= intEn;
797 
798     return E_NO_ERROR;
799 }
800 
MXC_UART_RevA_DisableInt(mxc_uart_reva_regs_t * uart,unsigned int intDis)801 int MXC_UART_RevA_DisableInt(mxc_uart_reva_regs_t *uart, unsigned int intDis)
802 {
803     uart->int_en &= ~intDis;
804 
805     return E_NO_ERROR;
806 }
807 
MXC_UART_RevA_GetStatus(mxc_uart_reva_regs_t * uart)808 unsigned int MXC_UART_RevA_GetStatus(mxc_uart_reva_regs_t *uart)
809 {
810     return uart->status;
811 }
812 
MXC_UART_RevA_Busy(mxc_uart_reva_regs_t * uart)813 int MXC_UART_RevA_Busy(mxc_uart_reva_regs_t *uart)
814 {
815     int uart_num =
816         MXC_UART_GET_IDX((mxc_uart_regs_t *)uart); // Holds the current index of tx_states
817     if ((uart->status & MXC_F_UART_REVA_STATUS_TX_BUSY) ||
818         (uart->status & MXC_F_UART_REVA_STATUS_RX_BUSY)) {
819         return E_BUSY;
820     }
821     // Check to see if there are any ongoing transactions and the UART has room in its FIFO
822     if ((states[uart_num].tx_req == NULL) && (states[uart_num].rx_req == NULL) &&
823         !(uart->status & MXC_F_UART_REVA_STATUS_TX_FULL)) {
824         return E_NO_ERROR;
825     }
826 
827     return E_BUSY;
828 }
829 
MXC_UART_RevA_Transaction(mxc_uart_reva_req_t * req)830 int MXC_UART_RevA_Transaction(mxc_uart_reva_req_t *req)
831 {
832     unsigned int numToWrite, numToRead;
833 
834     if (MXC_UART_GET_IDX((mxc_uart_regs_t *)(req->uart)) < 0) {
835         return E_BAD_PARAM;
836     }
837 
838     MXC_UART_DisableInt((mxc_uart_regs_t *)(req->uart), 0xFFFFFFFF);
839     MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart), 0xFFFFFFFF);
840 
841     MXC_UART_ClearRXFIFO((mxc_uart_regs_t *)(req->uart));
842     MXC_UART_ClearTXFIFO((mxc_uart_regs_t *)(req->uart));
843 
844     req->txCnt = 0;
845     req->rxCnt = 0;
846 
847     if (req->rxLen) {
848         if (req->rxData == NULL) {
849             return E_BAD_PARAM;
850         }
851     }
852 
853     if (req->txLen) {
854         if (req->txData == NULL) {
855             return E_BAD_PARAM;
856         }
857 
858         numToWrite = MXC_UART_GetTXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
859         numToWrite = numToWrite > (req->txLen - req->txCnt) ? req->txLen - req->txCnt : numToWrite;
860         req->txCnt += MXC_UART_WriteTXFIFO((mxc_uart_regs_t *)(req->uart), &req->txData[req->txCnt],
861                                            numToWrite);
862 
863         while (req->txCnt < req->txLen) {
864             while (!(MXC_UART_GetFlags((mxc_uart_regs_t *)(req->uart)) &
865                      MXC_F_UART_REVA_INT_FL_TX_FIFO_THRESH)) {}
866 
867             numToWrite = MXC_UART_GetTXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
868             numToWrite = numToWrite > (req->txLen - req->txCnt) ? req->txLen - req->txCnt :
869                                                                   numToWrite;
870             req->txCnt += MXC_UART_WriteTXFIFO((mxc_uart_regs_t *)(req->uart),
871                                                &req->txData[req->txCnt], numToWrite);
872             MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart),
873                                 MXC_F_UART_REVA_INT_FL_TX_FIFO_THRESH);
874         }
875     }
876 
877     if (req->rxLen) {
878         numToRead = MXC_UART_GetRXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
879         numToRead = numToRead > (req->rxLen - req->rxCnt) ? req->rxLen - req->rxCnt : numToRead;
880         req->rxCnt += MXC_UART_ReadRXFIFO((mxc_uart_regs_t *)(req->uart), &req->rxData[req->rxCnt],
881                                           numToRead);
882 
883         while (req->rxCnt < req->rxLen) {
884             while (!(MXC_UART_GetFlags((mxc_uart_regs_t *)(req->uart)) &
885                      MXC_F_UART_REVA_INT_FL_RX_FIFO_THRESH)) {}
886 
887             numToRead = MXC_UART_GetRXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
888             numToRead = numToRead > (req->rxLen - req->rxCnt) ? req->rxLen - req->rxCnt : numToRead;
889             req->rxCnt += MXC_UART_ReadRXFIFO((mxc_uart_regs_t *)(req->uart),
890                                               &req->rxData[req->rxCnt], numToRead);
891             MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart),
892                                 MXC_F_UART_REVA_INT_FL_RX_FIFO_THRESH);
893         }
894     }
895 
896     return E_NO_ERROR;
897 }
898 
MXC_UART_RevA_TransactionAsync(mxc_uart_reva_req_t * req)899 int MXC_UART_RevA_TransactionAsync(mxc_uart_reva_req_t *req)
900 {
901     unsigned int numToWrite, numToRead;
902     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)(req->uart));
903 
904     if (req->txLen) {
905         if (TxAsyncRequests[uart_num] != NULL) {
906             return E_BAD_STATE;
907         } else if (req->txData == NULL) {
908             return E_BAD_PARAM;
909         }
910 
911         req->txCnt = 0;
912         TxAsyncRequests[uart_num] = (void *)req;
913 
914         // Enable TX Threshold interrupt
915         MXC_UART_EnableInt((mxc_uart_regs_t *)(req->uart), MXC_F_UART_REVA_INT_EN_TX_FIFO_THRESH);
916 
917         numToWrite = MXC_UART_GetTXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
918         numToWrite = numToWrite > (req->txLen - req->txCnt) ? req->txLen - req->txCnt : numToWrite;
919         req->txCnt += MXC_UART_WriteTXFIFO((mxc_uart_regs_t *)(req->uart), &req->txData[req->txCnt],
920                                            numToWrite);
921     }
922 
923     if (req->rxLen) {
924         if (RxAsyncRequests[uart_num] != NULL) {
925             return E_BAD_STATE;
926         } else if (req->rxData == NULL) {
927             MXC_UART_DisableInt((mxc_uart_regs_t *)(req->uart), 0xFFFFFFFF);
928             return E_BAD_PARAM;
929         }
930 
931         req->rxCnt = 0;
932         RxAsyncRequests[uart_num] = (void *)req;
933 
934         // All error interrupts are related to RX
935         MXC_UART_EnableInt((mxc_uart_regs_t *)(req->uart), MXC_UART_REVA_ERRINT_EN);
936 
937         // Enable RX Threshold interrupt
938         MXC_UART_EnableInt((mxc_uart_regs_t *)(req->uart), MXC_F_UART_REVA_INT_EN_RX_FIFO_THRESH);
939 
940         numToRead = MXC_UART_GetRXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
941         numToRead = numToRead > (req->rxLen - req->rxCnt) ? req->rxLen - req->rxCnt : numToRead;
942         req->rxCnt += MXC_UART_ReadRXFIFO((mxc_uart_regs_t *)(req->uart), &req->rxData[req->rxCnt],
943                                           numToRead);
944         MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart), MXC_F_UART_REVA_INT_FL_RX_FIFO_THRESH);
945     }
946 
947     return E_NO_ERROR;
948 }
949 
MXC_UART_RevA_TransactionDMA(mxc_uart_reva_req_t * req,mxc_dma_regs_t * dma)950 int MXC_UART_RevA_TransactionDMA(mxc_uart_reva_req_t *req, mxc_dma_regs_t *dma)
951 {
952     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)(req->uart));
953 
954     if (req->txLen) {
955         if (req->txData == NULL) {
956             return E_BAD_PARAM;
957         }
958     }
959 
960     if (req->rxLen) {
961         if (req->rxData == NULL) {
962             return E_BAD_PARAM;
963         }
964     }
965 
966     MXC_UART_DisableInt((mxc_uart_regs_t *)(req->uart), 0xFFFFFFFF);
967     MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart), 0xFFFFFFFF);
968 
969     /* Clearing the RX FIFOs here makes RX-only or TX-only transactions half-duplex...
970     Commenting out for now.*/
971     // MXC_UART_ClearRXFIFO((mxc_uart_regs_t *)(req->uart));
972     // MXC_UART_ClearTXFIFO((mxc_uart_regs_t *)(req->uart));
973 
974     (req->uart)->dma |=
975         (1 << MXC_F_UART_REVA_DMA_RXDMA_LEVEL_POS); // Set RX DMA threshold to 1 byte
976     (req->uart)->dma |=
977         (2 << MXC_F_UART_REVA_DMA_TXDMA_LEVEL_POS); // Set TX DMA threshold to 2 bytes
978 
979 #if TARGET_NUM == 32665
980     MXC_DMA_Init(dma);
981 #else
982     MXC_DMA_Init();
983 #endif
984 
985     // Reset rx/tx counters
986     req->rxCnt = 0;
987     req->txCnt = 0;
988 
989     //tx
990     if ((req->txData != NULL) && (req->txLen)) {
991         /* Save TX req, the DMA handler will use this later. */
992         states[uart_num].tx_req = req;
993 #if TARGET_NUM == 32665
994         if (MXC_UART_WriteTXFIFODMA((mxc_uart_regs_t *)(req->uart), dma, req->txData, req->txLen,
995                                     NULL) != E_NO_ERROR) {
996             return E_BAD_PARAM;
997         }
998 #else
999         if (MXC_UART_WriteTXFIFODMA((mxc_uart_regs_t *)(req->uart), req->txData, req->txLen,
1000                                     NULL) != E_NO_ERROR) {
1001             return E_BAD_PARAM;
1002         }
1003 #endif
1004     }
1005 
1006     if ((req->rxData != NULL) && (req->rxLen)) {
1007         states[uart_num].rx_req = req;
1008 #if TARGET_NUM == 32665
1009         if (MXC_UART_ReadRXFIFODMA((mxc_uart_regs_t *)(req->uart), dma, req->rxData, req->rxLen,
1010                                    NULL) != E_NO_ERROR) {
1011             return E_BAD_PARAM;
1012         }
1013 #else
1014         if (MXC_UART_ReadRXFIFODMA((mxc_uart_regs_t *)(req->uart), req->rxData, req->rxLen, NULL) !=
1015             E_NO_ERROR) {
1016             return E_BAD_PARAM;
1017         }
1018 #endif
1019     }
1020 
1021     return E_NO_ERROR;
1022 }
1023 
MXC_UART_RevA_DMACallback(int ch,int error)1024 void MXC_UART_RevA_DMACallback(int ch, int error)
1025 {
1026     mxc_uart_reva_req_t *temp_req = NULL;
1027 
1028     for (int i = 0; i < MXC_UART_INSTANCES; i++) {
1029         if (states[i].channelTx == ch) {
1030             /* Populate txLen.  The number of "remainder" bytes is what's left on the
1031             DMA channel's count register. */
1032             states[i].tx_req->txCnt = states[i].tx_req->txLen - MXC_DMA->ch[ch].cnt;
1033 
1034             temp_req = states[i].tx_req;
1035 
1036             if (states[i].auto_dma_handlers) {
1037                 /* Release channel _before_ running callback in case
1038                 user wants to start another transaction inside it */
1039                 MXC_DMA_ReleaseChannel(ch);
1040                 states[i].channelTx = -1;
1041             }
1042 
1043             if (temp_req->callback != NULL &&
1044                 ((states[i].tx_req->rxCnt == states[i].tx_req->rxLen) ||
1045                  states[i].tx_req->rxData == NULL)) {
1046                 /* Only call TX callback if RX component is complete/disabled. Note that
1047                 we are checking the request associated with the _channel_ assignment, not
1048                 the other side of the state struct. */
1049                 temp_req->callback((mxc_uart_req_t *)temp_req, E_NO_ERROR);
1050             }
1051             break;
1052         } else if (states[i].channelRx == ch) {
1053             /* Same as above, but for RX */
1054             states[i].rx_req->rxCnt = states[i].rx_req->rxLen - MXC_DMA->ch[ch].cnt;
1055             temp_req = states[i].rx_req;
1056             if (states[i].auto_dma_handlers) {
1057                 MXC_DMA_ReleaseChannel(ch);
1058                 states[i].channelRx = -1;
1059             }
1060 
1061             if (temp_req->callback != NULL &&
1062                 ((states[i].rx_req->txCnt == states[i].rx_req->txLen) ||
1063                  states[i].rx_req->txData == NULL)) {
1064                 temp_req->callback((mxc_uart_req_t *)temp_req, E_NO_ERROR);
1065             }
1066             break;
1067         }
1068     }
1069 }
1070 
MXC_UART_RevA_RxAsyncCallback(mxc_uart_reva_regs_t * uart,int retVal)1071 int MXC_UART_RevA_RxAsyncCallback(mxc_uart_reva_regs_t *uart, int retVal)
1072 {
1073     mxc_uart_reva_req_t *req;
1074     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
1075 
1076     if (RxAsyncRequests[uart_num] == NULL) {
1077         return E_BAD_STATE;
1078     }
1079 
1080     req = (mxc_uart_reva_req_t *)RxAsyncRequests[uart_num];
1081 
1082     if (req->callback != NULL) {
1083         req->callback((mxc_uart_req_t *)req, retVal);
1084     }
1085 
1086     return E_NO_ERROR;
1087 }
1088 
MXC_UART_RevA_TxAsyncCallback(mxc_uart_reva_regs_t * uart,int retVal)1089 int MXC_UART_RevA_TxAsyncCallback(mxc_uart_reva_regs_t *uart, int retVal)
1090 {
1091     mxc_uart_reva_req_t *req;
1092     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
1093 
1094     if (TxAsyncRequests[uart_num] == NULL) {
1095         return E_BAD_STATE;
1096     }
1097 
1098     req = (mxc_uart_reva_req_t *)TxAsyncRequests[uart_num];
1099 
1100     if (req->callback != NULL) {
1101         req->callback((mxc_uart_req_t *)req, retVal);
1102     }
1103 
1104     return E_NO_ERROR;
1105 }
1106 
MXC_UART_RevA_AsyncCallback(mxc_uart_reva_regs_t * uart,int retVal)1107 int MXC_UART_RevA_AsyncCallback(mxc_uart_reva_regs_t *uart, int retVal)
1108 {
1109     int err;
1110 
1111     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
1112 
1113     // Call TX callback
1114     err = MXC_UART_TxAsyncCallback((mxc_uart_regs_t *)uart, retVal);
1115     if (err != E_NO_ERROR) {
1116         return err;
1117     }
1118 
1119     // Call RX callback if the TX and RX requests are not the same request
1120     if (TxAsyncRequests[uart_num] != RxAsyncRequests[uart_num]) {
1121         err = MXC_UART_RxAsyncCallback((mxc_uart_regs_t *)uart, retVal);
1122     }
1123 
1124     return err;
1125 }
1126 
MXC_UART_RevA_TxAsyncStop(mxc_uart_reva_regs_t * uart)1127 int MXC_UART_RevA_TxAsyncStop(mxc_uart_reva_regs_t *uart)
1128 {
1129     MXC_UART_DisableInt((mxc_uart_regs_t *)uart, MXC_F_UART_REVA_INT_EN_TX_FIFO_THRESH);
1130     TxAsyncRequests[MXC_UART_GET_IDX((mxc_uart_regs_t *)uart)] = NULL;
1131 
1132     return E_NO_ERROR;
1133 }
1134 
MXC_UART_RevA_RxAsyncStop(mxc_uart_reva_regs_t * uart)1135 int MXC_UART_RevA_RxAsyncStop(mxc_uart_reva_regs_t *uart)
1136 {
1137     MXC_UART_DisableInt((mxc_uart_regs_t *)uart,
1138                         (MXC_UART_REVA_ERRINT_EN | MXC_F_UART_REVA_INT_EN_RX_FIFO_THRESH));
1139     RxAsyncRequests[MXC_UART_GET_IDX((mxc_uart_regs_t *)uart)] = NULL;
1140 
1141     return E_NO_ERROR;
1142 }
1143 
MXC_UART_RevA_AsyncStop(mxc_uart_reva_regs_t * uart)1144 int MXC_UART_RevA_AsyncStop(mxc_uart_reva_regs_t *uart)
1145 {
1146     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
1147     mxc_uart_reva_req_t *req;
1148 
1149     req = (mxc_uart_reva_req_t *)TxAsyncRequests[uart_num];
1150     if (req != NULL) {
1151         MXC_UART_TxAsyncStop((mxc_uart_regs_t *)uart);
1152     }
1153 
1154     req = (mxc_uart_reva_req_t *)RxAsyncRequests[uart_num];
1155     if (req != NULL) {
1156         MXC_UART_RxAsyncStop((mxc_uart_regs_t *)uart);
1157     }
1158 
1159     return E_NO_ERROR;
1160 }
1161 
MXC_UART_RevA_TxAbortAsync(mxc_uart_reva_regs_t * uart)1162 int MXC_UART_RevA_TxAbortAsync(mxc_uart_reva_regs_t *uart)
1163 {
1164     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
1165 
1166     mxc_uart_reva_req_t *req = (mxc_uart_reva_req_t *)TxAsyncRequests[uart_num];
1167 
1168     if (req != NULL) {
1169         MXC_UART_TxAsyncCallback((mxc_uart_regs_t *)uart, E_ABORT);
1170         MXC_UART_TxAsyncStop((mxc_uart_regs_t *)uart);
1171     }
1172 
1173     return E_NO_ERROR;
1174 }
1175 
MXC_UART_RevA_RxAbortAsync(mxc_uart_reva_regs_t * uart)1176 int MXC_UART_RevA_RxAbortAsync(mxc_uart_reva_regs_t *uart)
1177 {
1178     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
1179 
1180     mxc_uart_reva_req_t *req = (mxc_uart_reva_req_t *)RxAsyncRequests[uart_num];
1181 
1182     if (req != NULL) {
1183         MXC_UART_RxAsyncCallback((mxc_uart_regs_t *)uart, E_ABORT);
1184         MXC_UART_RxAsyncStop((mxc_uart_regs_t *)uart);
1185     }
1186 
1187     return E_NO_ERROR;
1188 }
1189 
MXC_UART_RevA_AbortAsync(mxc_uart_reva_regs_t * uart)1190 int MXC_UART_RevA_AbortAsync(mxc_uart_reva_regs_t *uart)
1191 {
1192     int err;
1193 
1194     if (MXC_UART_GET_IDX((mxc_uart_regs_t *)uart) < 0) {
1195         return E_BAD_PARAM;
1196     }
1197 
1198     // Call appropriate callback
1199     err = MXC_UART_AsyncCallback((mxc_uart_regs_t *)uart, E_ABORT);
1200     if (err != E_NO_ERROR) {
1201         return err;
1202     }
1203 
1204     // Disable interrupts and clear async request
1205     return MXC_UART_AsyncStop((mxc_uart_regs_t *)uart);
1206 }
1207 
MXC_UART_RevA_AsyncHandler(mxc_uart_reva_regs_t * uart)1208 int MXC_UART_RevA_AsyncHandler(mxc_uart_reva_regs_t *uart)
1209 {
1210     int uart_num = MXC_UART_GET_IDX((mxc_uart_regs_t *)uart);
1211     unsigned int flags, numToWrite, numToRead;
1212     mxc_uart_reva_req_t *req;
1213 
1214     flags = MXC_UART_GetFlags((mxc_uart_regs_t *)uart);
1215 
1216     if (flags & MXC_UART_REVA_ERRINT_FL & uart->int_en) {
1217         MXC_UART_DisableInt((mxc_uart_regs_t *)uart,
1218                             (MXC_F_UART_REVA_INT_EN_TX_FIFO_THRESH | MXC_UART_REVA_ERRINT_EN |
1219                              MXC_F_UART_REVA_INT_EN_RX_FIFO_THRESH));
1220 
1221         MXC_UART_AsyncCallback((mxc_uart_regs_t *)uart, E_COMM_ERR);
1222 
1223         RxAsyncRequests[uart_num] = NULL;
1224         TxAsyncRequests[uart_num] = NULL;
1225 
1226         return E_INVALID;
1227     }
1228 
1229     req = (mxc_uart_reva_req_t *)TxAsyncRequests[uart_num];
1230 
1231     if ((flags & MXC_F_UART_REVA_INT_FL_TX_FIFO_THRESH) && (req != NULL) && (req->txLen)) {
1232         numToWrite = MXC_UART_GetTXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
1233         numToWrite = numToWrite > (req->txLen - req->txCnt) ? req->txLen - req->txCnt : numToWrite;
1234         req->txCnt += MXC_UART_WriteTXFIFO((mxc_uart_regs_t *)(req->uart), &req->txData[req->txCnt],
1235                                            numToWrite);
1236         MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart), MXC_F_UART_REVA_INT_FL_TX_FIFO_THRESH);
1237     }
1238 
1239     req = (mxc_uart_reva_req_t *)RxAsyncRequests[uart_num];
1240 
1241     if ((flags & MXC_F_UART_REVA_INT_FL_RX_FIFO_THRESH) && (req != NULL) && (req->rxLen)) {
1242         numToRead = MXC_UART_GetRXFIFOAvailable((mxc_uart_regs_t *)(req->uart));
1243         numToRead = numToRead > (req->rxLen - req->rxCnt) ? req->rxLen - req->rxCnt : numToRead;
1244         req->rxCnt += MXC_UART_ReadRXFIFO((mxc_uart_regs_t *)(req->uart), &req->rxData[req->rxCnt],
1245                                           numToRead);
1246         MXC_UART_ClearFlags((mxc_uart_regs_t *)(req->uart), MXC_F_UART_REVA_INT_FL_RX_FIFO_THRESH);
1247     }
1248 
1249     if (RxAsyncRequests[uart_num] == TxAsyncRequests[uart_num]) {
1250         if ((req != NULL) && (req->rxCnt == req->rxLen) && (req->txCnt == req->txLen)) {
1251             MXC_UART_DisableInt((mxc_uart_regs_t *)uart,
1252                                 (MXC_F_UART_REVA_INT_EN_TX_FIFO_THRESH | MXC_UART_REVA_ERRINT_EN |
1253                                  MXC_F_UART_REVA_INT_EN_RX_FIFO_THRESH));
1254 
1255             RxAsyncRequests[uart_num] = NULL;
1256             TxAsyncRequests[uart_num] = NULL;
1257 
1258             if (req->callback != NULL) {
1259                 req->callback((mxc_uart_req_t *)req, E_NO_ERROR);
1260             }
1261         }
1262 
1263         return E_NO_ERROR;
1264     }
1265 
1266     req = TxAsyncRequests[uart_num];
1267     if (req != NULL && req->txCnt == req->txLen) {
1268         MXC_UART_DisableInt((mxc_uart_regs_t *)uart, MXC_F_UART_REVA_INT_EN_TX_FIFO_THRESH);
1269         TxAsyncRequests[uart_num] = NULL;
1270 
1271         if (req->callback != NULL) {
1272             req->callback((mxc_uart_req_t *)req, E_NO_ERROR);
1273         }
1274 
1275         return E_NO_ERROR;
1276     }
1277 
1278     req = RxAsyncRequests[uart_num];
1279     if (req != NULL && req->rxCnt == req->rxLen) {
1280         MXC_UART_DisableInt((mxc_uart_regs_t *)uart,
1281                             (MXC_UART_REVA_ERRINT_EN | MXC_F_UART_REVA_INT_EN_RX_FIFO_THRESH));
1282         RxAsyncRequests[uart_num] = NULL;
1283 
1284         if (req->callback != NULL) {
1285             req->callback((mxc_uart_req_t *)req, E_NO_ERROR);
1286         }
1287 
1288         return E_NO_ERROR;
1289     }
1290 
1291     return E_NO_ERROR;
1292 }
1293