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