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