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 #ifdef __CC_ARM // Keil
21 #pragma diag_suppress 68 // integer conversion resulted in a change of sign
22 #endif
23 
24 #include "uart.h"
25 #include "mxc_device.h"
26 #include "mxc_pins.h"
27 #include "mxc_assert.h"
28 #include "uart_revb.h"
29 #include "uart_common.h"
30 #include "mcr_regs.h"
31 #include "dma.h"
32 
MXC_UART_DMACallback(int ch,int error)33 void MXC_UART_DMACallback(int ch, int error)
34 {
35     MXC_UART_RevB_DMACallback(ch, error);
36 }
37 
MXC_UART_AsyncCallback(mxc_uart_regs_t * uart,int retVal)38 int MXC_UART_AsyncCallback(mxc_uart_regs_t *uart, int retVal)
39 {
40     return MXC_UART_RevB_AsyncCallback((mxc_uart_revb_regs_t *)uart, retVal);
41 }
42 
MXC_UART_AsyncStop(mxc_uart_regs_t * uart)43 int MXC_UART_AsyncStop(mxc_uart_regs_t *uart)
44 {
45     return MXC_UART_RevB_AsyncStop((mxc_uart_revb_regs_t *)uart);
46 }
47 
MXC_UART_Init(mxc_uart_regs_t * uart,unsigned int baud,mxc_uart_clock_t clock)48 int MXC_UART_Init(mxc_uart_regs_t *uart, unsigned int baud, mxc_uart_clock_t clock)
49 {
50 #ifndef MSDK_NO_GPIO_CLK_INIT
51     int retval, error;
52 
53     retval = MXC_UART_Shutdown(uart);
54     if (retval) {
55         return retval;
56     }
57 
58     switch (clock) {
59     case MXC_UART_EXT_CLK:
60         MXC_GPIO_Config(&gpio_cfg_extclk);
61         break;
62 
63     case MXC_UART_ERTCO_CLK:
64         // UART0 and UART2 doesn't use ERTCO
65         return E_BAD_PARAM;
66         break;
67 
68     case MXC_UART_IBRO_CLK:
69         MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IBRO);
70         break;
71 
72     case MXC_UART_ERFO_CLK:
73         MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_ERFO);
74         break;
75 
76     default:
77         break;
78     }
79 
80     switch (MXC_UART_GET_IDX(uart)) {
81     case 0:
82         MXC_GPIO_Config(&gpio_cfg_uart0);
83         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_UART0);
84         break;
85 
86     case 2: // Can't use UART2 when HART Modem is used for MAX32675.
87         error = MXC_GPIO_Config(&gpio_cfg_uart2);
88         if (error != E_NO_ERROR) {
89             return error;
90         }
91 
92         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_UART2);
93         break;
94 
95     default:
96         return E_NOT_SUPPORTED;
97     }
98 #endif // MSDK_NO_GPIO_CLK_INIT
99 
100     return MXC_UART_RevB_Init((mxc_uart_revb_regs_t *)uart, baud, (mxc_uart_revb_clock_t)clock);
101 }
102 
MXC_UART_Shutdown(mxc_uart_regs_t * uart)103 int MXC_UART_Shutdown(mxc_uart_regs_t *uart)
104 {
105     switch (MXC_UART_GET_IDX(uart)) {
106     case 0:
107         MXC_SYS_Reset_Periph(MXC_SYS_RESET0_UART0);
108         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_UART0);
109         break;
110 
111     case 2: // Make sure UART2 isn't used for HART_Modem
112         MXC_SYS_Reset_Periph(MXC_SYS_RESET0_UART2);
113         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_UART2);
114         break;
115 
116     default:
117         return E_NOT_SUPPORTED;
118     }
119 
120     return E_NO_ERROR;
121 }
122 
MXC_UART_ReadyForSleep(mxc_uart_regs_t * uart)123 int MXC_UART_ReadyForSleep(mxc_uart_regs_t *uart)
124 {
125     return MXC_UART_RevB_ReadyForSleep((mxc_uart_revb_regs_t *)uart);
126 }
127 
MXC_UART_SetFrequency(mxc_uart_regs_t * uart,unsigned int baud,mxc_uart_clock_t clock)128 int MXC_UART_SetFrequency(mxc_uart_regs_t *uart, unsigned int baud, mxc_uart_clock_t clock)
129 {
130     int freq;
131     int mod = 0;
132     int clkdiv = 0;
133     int div = 8;
134 
135     if (MXC_UART_GET_IDX(uart) < 0) {
136         return E_BAD_PARAM;
137     }
138 
139     // check if the uart is LPUART
140     if (uart == MXC_UART3) {
141         // OSR default value
142         uart->osr = 5;
143 
144         switch (clock) {
145         case MXC_UART_APB_CLK:
146             uart->ctrl |= MXC_S_UART_CTRL_BCLKSRC_PERIPHERAL_CLOCK;
147             div = (1 << (MXC_GCR->pclkdiv & MXC_F_GCR_PCLKDIV_AON_CLKDIV)) * 8;
148             clkdiv = ((SystemCoreClock / div) / baud);
149             mod = ((SystemCoreClock / div) % baud);
150             break;
151 
152         case MXC_UART_EXT_CLK:
153             uart->ctrl |= MXC_S_UART_CTRL_BCLKSRC_EXTERNAL_CLOCK;
154             clkdiv = EXTCLK_FREQ / baud;
155             mod = EXTCLK_FREQ % baud;
156             break;
157 
158         case MXC_UART_ERTCO_CLK:
159             uart->ctrl |= MXC_S_UART_CTRL_BCLKSRC_CLK2;
160             uart->ctrl |= MXC_F_UART_CTRL_FDM;
161             clkdiv = ((ERTCO_FREQ * 2) / baud);
162             mod = ((ERTCO_FREQ * 2) % baud);
163 
164             if (baud > 2400) {
165                 uart->osr = 0;
166             } else {
167                 uart->osr = 1;
168             }
169             break;
170 
171         default:
172             return E_BAD_PARAM;
173         }
174 
175         if (!clkdiv || mod > (baud / 2)) {
176             clkdiv++;
177         }
178         uart->clkdiv = clkdiv;
179 
180         freq = MXC_UART_GetFrequency(uart);
181     } else {
182         freq = MXC_UART_RevB_SetFrequency((mxc_uart_revb_regs_t *)uart, baud, clock);
183     }
184 
185     if (freq > 0) {
186         // Enable baud clock and wait for it to become ready.
187         uart->ctrl |= MXC_F_UART_CTRL_BCLKEN;
188         while (((uart->ctrl & MXC_F_UART_CTRL_BCLKRDY) >> MXC_F_UART_CTRL_BCLKRDY_POS) == 0) {}
189     }
190 
191     return freq;
192 }
193 
MXC_UART_GetFrequency(mxc_uart_regs_t * uart)194 int MXC_UART_GetFrequency(mxc_uart_regs_t *uart)
195 {
196     int periphClock = 0;
197     int div = 8;
198 
199     if (MXC_UART_GET_IDX(uart) < 0) {
200         return E_BAD_PARAM;
201     }
202 
203     // check if UARt is LP UART
204     if (uart == MXC_UART3) {
205         if ((uart->ctrl & MXC_F_UART_CTRL_BCLKSRC) == MXC_S_UART_CTRL_BCLKSRC_EXTERNAL_CLOCK) {
206             return EXTCLK_FREQ;
207         } else if ((uart->ctrl & MXC_F_UART_CTRL_BCLKSRC) ==
208                    MXC_S_UART_CTRL_BCLKSRC_PERIPHERAL_CLOCK) {
209             div = (1 << (MXC_GCR->pclkdiv & MXC_F_GCR_PCLKDIV_AON_CLKDIV)) * 8;
210             periphClock = SystemCoreClock / div;
211         } else if ((uart->ctrl & MXC_F_UART_CTRL_BCLKSRC) == MXC_S_UART_CTRL_BCLKSRC_CLK2) {
212             periphClock = ERTCO_FREQ * 2;
213         } else {
214             return E_BAD_PARAM;
215         }
216         return (periphClock / uart->clkdiv);
217     } else {
218         return MXC_UART_RevB_GetFrequency((mxc_uart_revb_regs_t *)uart);
219     }
220 }
221 
MXC_UART_SetDataSize(mxc_uart_regs_t * uart,int dataSize)222 int MXC_UART_SetDataSize(mxc_uart_regs_t *uart, int dataSize)
223 {
224     return MXC_UART_RevB_SetDataSize((mxc_uart_revb_regs_t *)uart, dataSize);
225 }
226 
MXC_UART_SetStopBits(mxc_uart_regs_t * uart,mxc_uart_stop_t stopBits)227 int MXC_UART_SetStopBits(mxc_uart_regs_t *uart, mxc_uart_stop_t stopBits)
228 {
229     return MXC_UART_RevB_SetStopBits((mxc_uart_revb_regs_t *)uart, stopBits);
230 }
231 
MXC_UART_SetParity(mxc_uart_regs_t * uart,mxc_uart_parity_t parity)232 int MXC_UART_SetParity(mxc_uart_regs_t *uart, mxc_uart_parity_t parity)
233 {
234     return MXC_UART_RevB_SetParity((mxc_uart_revb_regs_t *)uart, parity);
235 }
236 
MXC_UART_SetFlowCtrl(mxc_uart_regs_t * uart,mxc_uart_flow_t flowCtrl,int rtsThreshold)237 int MXC_UART_SetFlowCtrl(mxc_uart_regs_t *uart, mxc_uart_flow_t flowCtrl, int rtsThreshold)
238 {
239     if (flowCtrl == MXC_UART_FLOW_EN) {
240         switch (MXC_UART_GET_IDX(uart)) {
241         case 0:
242             MXC_GPIO_Config(&gpio_cfg_uart0_flow);
243             break;
244 
245         case 2:
246             MXC_GPIO_Config(&gpio_cfg_uart2_flow);
247             break;
248 
249         default:
250             return E_BAD_PARAM;
251         }
252     } else {
253         switch (MXC_UART_GET_IDX(uart)) {
254         case 0:
255             MXC_GPIO_Config(&gpio_cfg_uart0_flow_disable);
256             break;
257 
258         case 2:
259             MXC_GPIO_Config(&gpio_cfg_uart2_flow_disable);
260             break;
261 
262         default:
263             return E_BAD_PARAM;
264         }
265     }
266 
267     return MXC_UART_RevB_SetFlowCtrl((mxc_uart_revb_regs_t *)uart, flowCtrl, rtsThreshold);
268 }
269 
MXC_UART_SetClockSource(mxc_uart_regs_t * uart,mxc_uart_clock_t clock)270 int MXC_UART_SetClockSource(mxc_uart_regs_t *uart, mxc_uart_clock_t clock)
271 {
272     return MXC_UART_RevB_SetClockSource((mxc_uart_revb_regs_t *)uart, (mxc_uart_revb_clock_t)clock);
273 }
274 
MXC_UART_GetActive(mxc_uart_regs_t * uart)275 int MXC_UART_GetActive(mxc_uart_regs_t *uart)
276 {
277     return MXC_UART_RevB_GetActive((mxc_uart_revb_regs_t *)uart);
278 }
279 
MXC_UART_AbortTransmission(mxc_uart_regs_t * uart)280 int MXC_UART_AbortTransmission(mxc_uart_regs_t *uart)
281 {
282     return MXC_UART_RevB_AbortTransmission((mxc_uart_revb_regs_t *)uart);
283 }
284 
MXC_UART_ReadCharacterRaw(mxc_uart_regs_t * uart)285 int MXC_UART_ReadCharacterRaw(mxc_uart_regs_t *uart)
286 {
287     return MXC_UART_RevB_ReadCharacterRaw((mxc_uart_revb_regs_t *)uart);
288 }
289 
MXC_UART_WriteCharacterRaw(mxc_uart_regs_t * uart,uint8_t character)290 int MXC_UART_WriteCharacterRaw(mxc_uart_regs_t *uart, uint8_t character)
291 {
292     return MXC_UART_RevB_WriteCharacterRaw((mxc_uart_revb_regs_t *)uart, character);
293 }
294 
MXC_UART_ReadCharacter(mxc_uart_regs_t * uart)295 int MXC_UART_ReadCharacter(mxc_uart_regs_t *uart)
296 {
297     return MXC_UART_Common_ReadCharacter(uart);
298 }
299 
MXC_UART_WriteCharacter(mxc_uart_regs_t * uart,uint8_t character)300 int MXC_UART_WriteCharacter(mxc_uart_regs_t *uart, uint8_t character)
301 {
302     return MXC_UART_Common_WriteCharacter(uart, character);
303 }
304 
MXC_UART_Read(mxc_uart_regs_t * uart,uint8_t * buffer,int * len)305 int MXC_UART_Read(mxc_uart_regs_t *uart, uint8_t *buffer, int *len)
306 {
307     return MXC_UART_RevB_Read((mxc_uart_revb_regs_t *)uart, buffer, len);
308 }
309 
MXC_UART_Write(mxc_uart_regs_t * uart,const uint8_t * byte,int * len)310 int MXC_UART_Write(mxc_uart_regs_t *uart, const uint8_t *byte, int *len)
311 {
312     return MXC_UART_RevB_Write((mxc_uart_revb_regs_t *)uart, byte, len);
313 }
314 
MXC_UART_ReadRXFIFO(mxc_uart_regs_t * uart,unsigned char * bytes,unsigned int len)315 unsigned int MXC_UART_ReadRXFIFO(mxc_uart_regs_t *uart, unsigned char *bytes, unsigned int len)
316 {
317     return MXC_UART_RevB_ReadRXFIFO((mxc_uart_revb_regs_t *)uart, bytes, len);
318 }
319 
MXC_UART_ReadRXFIFODMA(mxc_uart_regs_t * uart,unsigned char * bytes,unsigned int len,mxc_uart_dma_complete_cb_t callback)320 int MXC_UART_ReadRXFIFODMA(mxc_uart_regs_t *uart, unsigned char *bytes, unsigned int len,
321                            mxc_uart_dma_complete_cb_t callback)
322 {
323     mxc_dma_config_t config;
324 
325     int uart_num = MXC_UART_GET_IDX(uart);
326 
327     switch (uart_num) {
328     case 0:
329         config.reqsel = MXC_DMA_REQUEST_UART0RX;
330         break;
331 
332     case 2:
333         config.reqsel = MXC_DMA_REQUEST_UART2RX;
334         break;
335 
336     default:
337         return E_BAD_PARAM;
338         break;
339     }
340 
341     return MXC_UART_RevB_ReadRXFIFODMA((mxc_uart_revb_regs_t *)uart, bytes, len, callback, config);
342 }
343 
MXC_UART_GetRXFIFOAvailable(mxc_uart_regs_t * uart)344 unsigned int MXC_UART_GetRXFIFOAvailable(mxc_uart_regs_t *uart)
345 {
346     return MXC_UART_RevB_GetRXFIFOAvailable((mxc_uart_revb_regs_t *)uart);
347 }
348 
MXC_UART_WriteTXFIFO(mxc_uart_regs_t * uart,const unsigned char * bytes,unsigned int len)349 unsigned int MXC_UART_WriteTXFIFO(mxc_uart_regs_t *uart, const unsigned char *bytes,
350                                   unsigned int len)
351 {
352     return MXC_UART_RevB_WriteTXFIFO((mxc_uart_revb_regs_t *)uart, bytes, len);
353 }
354 
MXC_UART_WriteTXFIFODMA(mxc_uart_regs_t * uart,const unsigned char * bytes,unsigned int len,mxc_uart_dma_complete_cb_t callback)355 int MXC_UART_WriteTXFIFODMA(mxc_uart_regs_t *uart, const unsigned char *bytes, unsigned int len,
356                             mxc_uart_dma_complete_cb_t callback)
357 {
358     mxc_dma_config_t config;
359 
360     int uart_num = MXC_UART_GET_IDX(uart);
361 
362     switch (uart_num) {
363     case 0:
364         config.reqsel = MXC_DMA_REQUEST_UART0TX;
365         break;
366 
367     case 2:
368         config.reqsel = MXC_DMA_REQUEST_UART2TX;
369         break;
370 
371     default:
372         return E_BAD_PARAM;
373         break;
374     }
375 
376     return MXC_UART_RevB_WriteTXFIFODMA((mxc_uart_revb_regs_t *)uart, bytes, len, callback, config);
377 }
378 
MXC_UART_GetTXFIFOAvailable(mxc_uart_regs_t * uart)379 unsigned int MXC_UART_GetTXFIFOAvailable(mxc_uart_regs_t *uart)
380 {
381     return MXC_UART_RevB_GetTXFIFOAvailable((mxc_uart_revb_regs_t *)uart);
382 }
383 
MXC_UART_ClearRXFIFO(mxc_uart_regs_t * uart)384 int MXC_UART_ClearRXFIFO(mxc_uart_regs_t *uart)
385 {
386     return MXC_UART_RevB_ClearRXFIFO((mxc_uart_revb_regs_t *)uart);
387 }
388 
MXC_UART_ClearTXFIFO(mxc_uart_regs_t * uart)389 int MXC_UART_ClearTXFIFO(mxc_uart_regs_t *uart)
390 {
391     return MXC_UART_RevB_ClearTXFIFO((mxc_uart_revb_regs_t *)uart);
392 }
393 
MXC_UART_SetRXThreshold(mxc_uart_regs_t * uart,unsigned int numBytes)394 int MXC_UART_SetRXThreshold(mxc_uart_regs_t *uart, unsigned int numBytes)
395 {
396     return MXC_UART_RevB_SetRXThreshold((mxc_uart_revb_regs_t *)uart, numBytes);
397 }
398 
MXC_UART_GetRXThreshold(mxc_uart_regs_t * uart)399 unsigned int MXC_UART_GetRXThreshold(mxc_uart_regs_t *uart)
400 {
401     return MXC_UART_RevB_GetRXThreshold((mxc_uart_revb_regs_t *)uart);
402 }
403 
MXC_UART_SetTXThreshold(mxc_uart_regs_t * uart,unsigned int numBytes)404 int MXC_UART_SetTXThreshold(mxc_uart_regs_t *uart, unsigned int numBytes)
405 {
406     // TX threshold is fixed at half the length of FIFO
407     return E_NOT_SUPPORTED;
408 }
409 
MXC_UART_GetTXThreshold(mxc_uart_regs_t * uart)410 unsigned int MXC_UART_GetTXThreshold(mxc_uart_regs_t *uart)
411 {
412     // TX threshold is fixed at half the length of FIFO
413     return E_NOT_SUPPORTED;
414 }
415 
MXC_UART_GetFlags(mxc_uart_regs_t * uart)416 unsigned int MXC_UART_GetFlags(mxc_uart_regs_t *uart)
417 {
418     return MXC_UART_RevB_GetFlags((mxc_uart_revb_regs_t *)uart);
419 }
420 
MXC_UART_ClearFlags(mxc_uart_regs_t * uart,unsigned int flags)421 int MXC_UART_ClearFlags(mxc_uart_regs_t *uart, unsigned int flags)
422 {
423     return MXC_UART_RevB_ClearFlags((mxc_uart_revb_regs_t *)uart, flags);
424 }
425 
MXC_UART_EnableInt(mxc_uart_regs_t * uart,unsigned int mask)426 int MXC_UART_EnableInt(mxc_uart_regs_t *uart, unsigned int mask)
427 {
428     return MXC_UART_RevB_EnableInt((mxc_uart_revb_regs_t *)uart, mask);
429 }
430 
MXC_UART_DisableInt(mxc_uart_regs_t * uart,unsigned int mask)431 int MXC_UART_DisableInt(mxc_uart_regs_t *uart, unsigned int mask)
432 {
433     return MXC_UART_RevB_DisableInt((mxc_uart_revb_regs_t *)uart, mask);
434 }
435 
MXC_UART_GetStatus(mxc_uart_regs_t * uart)436 unsigned int MXC_UART_GetStatus(mxc_uart_regs_t *uart)
437 {
438     return MXC_UART_RevB_GetStatus((mxc_uart_revb_regs_t *)uart);
439 }
440 
MXC_UART_Transaction(mxc_uart_req_t * req)441 int MXC_UART_Transaction(mxc_uart_req_t *req)
442 {
443     return MXC_UART_RevB_Transaction((mxc_uart_revb_req_t *)req);
444 }
445 
MXC_UART_TransactionAsync(mxc_uart_req_t * req)446 int MXC_UART_TransactionAsync(mxc_uart_req_t *req)
447 {
448     return MXC_UART_RevB_TransactionAsync((mxc_uart_revb_req_t *)req);
449 }
450 
MXC_UART_TransactionDMA(mxc_uart_req_t * req)451 int MXC_UART_TransactionDMA(mxc_uart_req_t *req)
452 {
453     return MXC_UART_RevB_TransactionDMA((mxc_uart_revb_req_t *)req);
454 }
455 
MXC_UART_AbortAsync(mxc_uart_regs_t * uart)456 int MXC_UART_AbortAsync(mxc_uart_regs_t *uart)
457 {
458     return MXC_UART_RevB_AbortAsync((mxc_uart_revb_regs_t *)uart);
459 }
460 
MXC_UART_AsyncHandler(mxc_uart_regs_t * uart)461 int MXC_UART_AsyncHandler(mxc_uart_regs_t *uart)
462 {
463     return MXC_UART_RevB_AsyncHandler((mxc_uart_revb_regs_t *)uart);
464 }
465 
MXC_UART_GetAsyncTXCount(mxc_uart_req_t * req)466 uint32_t MXC_UART_GetAsyncTXCount(mxc_uart_req_t *req)
467 {
468     return req->txCnt;
469 }
470 
MXC_UART_GetAsyncRXCount(mxc_uart_req_t * req)471 uint32_t MXC_UART_GetAsyncRXCount(mxc_uart_req_t *req)
472 {
473     return req->rxCnt;
474 }
475 
MXC_UART_SetAutoDMAHandlers(mxc_uart_regs_t * uart,bool enable)476 int MXC_UART_SetAutoDMAHandlers(mxc_uart_regs_t *uart, bool enable)
477 {
478     return MXC_UART_RevB_SetAutoDMAHandlers((mxc_uart_revb_regs_t *)uart, enable);
479 }
480 
MXC_UART_SetTXDMAChannel(mxc_uart_regs_t * uart,unsigned int channel)481 int MXC_UART_SetTXDMAChannel(mxc_uart_regs_t *uart, unsigned int channel)
482 {
483     return MXC_UART_RevB_SetTXDMAChannel((mxc_uart_revb_regs_t *)uart, channel);
484 }
485 
MXC_UART_GetTXDMAChannel(mxc_uart_regs_t * uart)486 int MXC_UART_GetTXDMAChannel(mxc_uart_regs_t *uart)
487 {
488     return MXC_UART_RevB_GetTXDMAChannel((mxc_uart_revb_regs_t *)uart);
489 }
490 
MXC_UART_SetRXDMAChannel(mxc_uart_regs_t * uart,unsigned int channel)491 int MXC_UART_SetRXDMAChannel(mxc_uart_regs_t *uart, unsigned int channel)
492 {
493     return MXC_UART_RevB_SetRXDMAChannel((mxc_uart_revb_regs_t *)uart, channel);
494 }
495 
MXC_UART_GetRXDMAChannel(mxc_uart_regs_t * uart)496 int MXC_UART_GetRXDMAChannel(mxc_uart_regs_t *uart)
497 {
498     return MXC_UART_RevB_GetTXDMAChannel((mxc_uart_revb_regs_t *)uart);
499 }
500