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