1 /*
2  * Copyright (c) 2020, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  *  ======== UART2CC32XX.c ========
35  */
36 
37 #include <stdint.h>
38 #include <stdbool.h>
39 
40 #include <ti/drivers/dpl/ClockP.h>
41 #include <ti/drivers/dpl/HwiP.h>
42 #include <ti/drivers/dpl/SemaphoreP.h>
43 #include <ti/drivers/Power.h>
44 #include <ti/drivers/power/PowerCC32XX.h>
45 #include <ti/drivers/dma/UDMACC32XX.h>
46 
47 #include <ti/drivers/uart2/UART2CC32XX.h>
48 
49 /* driverlib header files */
50 #include <ti/devices/cc32xx/inc/hw_memmap.h>
51 #include <ti/devices/cc32xx/inc/hw_ocp_shared.h>
52 #include <ti/devices/cc32xx/inc/hw_ints.h>
53 #include <ti/devices/cc32xx/inc/hw_types.h>
54 #include <ti/devices/cc32xx/inc/hw_uart.h>
55 #include <ti/devices/cc32xx/driverlib/rom.h>
56 #include <ti/devices/cc32xx/driverlib/rom_map.h>
57 #include <ti/devices/cc32xx/driverlib/uart.h>
58 #include <ti/devices/cc32xx/driverlib/pin.h>
59 #include <ti/devices/cc32xx/driverlib/udma.h>
60 
61 /* Pad configuration defines */
62 #define PAD_CONFIG_BASE (OCP_SHARED_BASE + OCP_SHARED_O_GPIO_PAD_CONFIG_0)
63 #define PAD_RESET_STATE 0xC61
64 
65 #if defined(__IAR_SYSTEMS_ICC__)
66 #include <intrinsics.h>
67 #endif
68 
69 #define MIN(a,b) (((a)<(b))?(a):(b))
70 
71 /* Mazimum number of bytes that DMA can transfer */
72 #define MAX_SIZE 1024
73 
74 /* Options for DMA write and read */
75 #define TX_CONTROL_OPTS  (UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | \
76                           UDMA_ARB_4)
77 #define RX_CONTROL_OPTS  (UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | \
78                           UDMA_ARB_4)
79 
80 /* Static functions */
81 static void configDmaRx(UART2_Handle handle);
82 static void configDmaTx(UART2_Handle handle);
83 static void UART2CC32XX_hwiIntFxn(uintptr_t arg);
84 static uint_fast16_t getPowerMgrId(uint32_t baseAddr);
85 static void initHw(UART2_Handle handle);
86 static int  postNotifyFxn(unsigned int eventType, uintptr_t eventArg,
87         uintptr_t clientArg);
88 static void cancelDmaRx(UART2_Handle handle);
89 static int32_t readData(UART2_Handle handle, int32_t size);
90 static void readSemCallback(UART2_Handle handle, void *buffer, size_t count,
91         void *userArg, int_fast16_t status);
92 static void readDone(UART2_Handle handle);
93 static void writeSemCallback(UART2_Handle handle, void *buffer, size_t count,
94         void *userArg, int_fast16_t status);
95 
96 /* UART function table for UART2CC32XX implementation */
97 const UART2_FxnTable UART2CC32XX_fxnTable = {
98     UART2CC32XX_close,
99     UART2CC32XX_open,
100     UART2CC32XX_read,
101     UART2CC32XX_readCancel,
102     UART2CC32XX_write,
103     UART2CC32XX_writeCancel,
104     UART2CC32XX_flushRx,
105 };
106 
107 /* Map UART2 data length to driverlib data length */
108 static const uint32_t dataLength[] = {
109     UART_CONFIG_WLEN_5,     /* UART2_DataLen_5 */
110     UART_CONFIG_WLEN_6,     /* UART2_DataLen_6 */
111     UART_CONFIG_WLEN_7,     /* UART2_DataLen_7 */
112     UART_CONFIG_WLEN_8      /* UART2_DataLen_8 */
113 };
114 
115 /* Map UART2 stop bits to driverlib stop bits */
116 static const uint32_t stopBits[] = {
117     UART_CONFIG_STOP_ONE,   /* UART2_StopBits_1 */
118     UART_CONFIG_STOP_TWO    /* UART2_StopBits_2 */
119 };
120 
121 /* Map UART2 parity type to driverlib parity type */
122 static const uint32_t parityType[] = {
123     UART_CONFIG_PAR_NONE,   /* UART2_Parity_NONE */
124     UART_CONFIG_PAR_EVEN,   /* UART2_Parity_EVEN */
125     UART_CONFIG_PAR_ODD,    /* UART2_Parity_ODD */
126     UART_CONFIG_PAR_ZERO,   /* UART2_Parity_ZERO */
127     UART_CONFIG_PAR_ONE     /* UART2_Parity_ONE */
128 };
129 
130 /*
131  *  Map UART2CC32XX FIFO threshold types to driverlib TX FIFO threshold
132  *  defines.
133  */
134 static const uint8_t txFifoThreshold[5] = {
135     UART_FIFO_TX1_8, /* UART2CC32XX_FIFO_THRESHOLD_1_8     */
136     UART_FIFO_TX2_8, /* UART2CC32XX_FIFO_THRESHOLD_2_8     */
137     UART_FIFO_TX4_8, /* UART2CC32XX_FIFO_THRESHOLD_4_8     */
138     UART_FIFO_TX6_8, /* UART2CC32XX_FIFO_THRESHOLD_6_8     */
139     UART_FIFO_TX7_8  /* UART2CC32XX_FIFO_THRESHOLD_7_8     */
140 };
141 
142 /*
143  *  Map UART2CC32XXFIFO threshold types to driverlib RX FIFO threshold
144  *  defines.
145  */
146 static const uint8_t rxFifoThreshold[5] = {
147     UART_FIFO_RX1_8, /* UART2CC32XX_FIFO_THRESHOLD_1_8     */
148     UART_FIFO_RX2_8, /* UART2CC32XX_FIFO_THRESHOLD_2_8     */
149     UART_FIFO_RX4_8, /* UART2CC32XX_FIFO_THRESHOLD_4_8     */
150     UART_FIFO_RX6_8, /* UART2CC32XX_FIFO_THRESHOLD_6_8     */
151     UART_FIFO_RX7_8  /* UART2CC32XX_FIFO_THRESHOLD_7_8     */
152 };
153 
154 /* Number of bytes in the RX FIFO at the corresponding FIFO threshold level */
155 static const uint8_t rxFifoBytes[6] = {
156      2,   /* UART2CC26X2_FIFO_THRESHOLD_1_8     */
157      4,   /* UART2CC26X2_FIFO_THRESHOLD_2_8     */
158      8,   /* UART2CC26X2_FIFO_THRESHOLD_4_8     */
159     12,   /* UART2CC26X2_FIFO_THRESHOLD_6_8     */
160     14    /* UART2CC26X2_FIFO_THRESHOLD_7_8     */
161 };
162 
163 /*
164  *  ======== uartDmaEnable ========
165  *  Atomic version of DriverLib UARTDMAEnable()
166  */
uartDmaEnable(uint32_t ui32Base,uint32_t ui32DMAFlags)167 static inline void uartDmaEnable(uint32_t ui32Base, uint32_t ui32DMAFlags)
168 {
169     uintptr_t key;
170 
171     key = HwiP_disable();
172     /* Set the requested bits in the UART DMA control register. */
173     HWREG(ui32Base + UART_O_DMACTL) |= ui32DMAFlags;
174 
175     HwiP_restore(key);
176 }
177 
178 /*
179  *  ======== uartDmaDisable ========
180  *  Atomic version of DriverLib UARTDMADisable()
181  */
uartDmaDisable(uint32_t ui32Base,uint32_t ui32DMAFlags)182 static inline void uartDmaDisable(uint32_t ui32Base, uint32_t ui32DMAFlags)
183 {
184     uintptr_t key;
185 
186     key = HwiP_disable();
187     /* Clear the requested bits in the UART DMA control register. */
188     HWREG(ui32Base + UART_O_DMACTL) &= ~ui32DMAFlags;
189 
190     HwiP_restore(key);
191 }
192 
193 /*
194  *  ======== getRxStatus ========
195  *  Get the left-most bit set in the RX error status (OE, BE, PE, FE)
196  *  read from the RSR register:
197  *      bit#   3   2   1   0
198  *             OE  BE  PE  FE
199  *  e.g., if OE and FE are both set, OE wins.  This will make it easier
200  *  to convert an RX error status to a UART2 error code.
201  */
getRxStatus(uint32_t x)202 static inline uint32_t getRxStatus(uint32_t x)
203 {
204 #if defined(__TI_COMPILER_VERSION__)
205     return ((uint32_t) (x & (0x80000000 >> __clz(x))));
206 #elif defined(__GNUC__)
207     return ((uint32_t) (x & (0x80000000 >> __builtin_clz(x))));
208 #elif defined(__IAR_SYSTEMS_ICC__)
209     return ((uint32_t) (x & (0x80000000 >>  __CLZ(x))));
210 #else
211     #error "Unsupported compiler"
212 #endif
213 }
214 
215 /*
216  *  ======== rxStatus2ErrorCode ========
217  *  Convert RX status (OE, BE, PE, FE) to a UART2 error code.
218  */
rxStatus2ErrorCode(uint32_t x)219 static inline int_fast16_t rxStatus2ErrorCode(uint32_t x)
220 {
221     uint32_t status;
222 
223     status = getRxStatus(x);
224     return (-((int_fast16_t)status));
225 }
226 
227 /*
228  * Function for checking whether flow control is enabled.
229  */
isFlowControlEnabled(UART2CC32XX_HWAttrs const * hwAttrs)230 static inline bool isFlowControlEnabled(UART2CC32XX_HWAttrs const *hwAttrs) {
231     return (hwAttrs->flowControl == UART2CC32XX_FLOWCTRL_HARDWARE);
232 }
233 
234 /*
235  *  ======== UART2CC32XX_close ========
236  */
UART2CC32XX_close(UART2_Handle handle)237 void UART2CC32XX_close(UART2_Handle handle)
238 {
239     UART2CC32XX_Object        *object = handle->object;
240     UART2CC32XX_HWAttrs const *hwAttrs = handle->hwAttrs;
241     uint32_t                   padRegister;
242 
243     /* Disable UART and interrupts. */
244     UARTIntDisable(hwAttrs->baseAddr, UART_INT_RX | UART_INT_RT | UART_INT_OE |
245                    UART_INT_BE | UART_INT_PE | UART_INT_FE | UART_INT_EOT);
246 
247     /* Disable UART and interrupts. */
248     uartDmaDisable(hwAttrs->baseAddr, UART_DMA_TX | UART_DMA_RX);
249     MAP_UARTDisable(hwAttrs->baseAddr);
250 
251     if (object->hwi) {
252         HwiP_delete(object->hwi);
253     }
254     if (object->writeSem) {
255         SemaphoreP_delete(object->writeSem);
256     }
257     if (object->readSem) {
258         SemaphoreP_delete(object->readSem);
259     }
260     if (object->udmaHandle) {
261         UDMACC32XX_close(object->udmaHandle);
262     }
263 
264     Power_unregisterNotify(&object->postNotify);
265     Power_releaseDependency(object->powerMgrId);
266 
267     if (object->txPin != (uint16_t)-1) {
268         PowerCC32XX_restoreParkState((PowerCC32XX_Pin)object->txPin,
269                                      object->prevParkTX);
270         object->txPin = (uint16_t)-1;
271     }
272 
273     if (object->rtsPin != (uint16_t)-1) {
274         PowerCC32XX_restoreParkState((PowerCC32XX_Pin)object->rtsPin,
275                                      object->prevParkRTS);
276         object->rtsPin = (uint16_t)-1;
277     }
278 
279     /* Restore pin pads to their reset states */
280     padRegister = (PinToPadGet((hwAttrs->rxPin) & 0xff)<<2) + PAD_CONFIG_BASE;
281     HWREG(padRegister) = PAD_RESET_STATE;
282     padRegister = (PinToPadGet((hwAttrs->txPin) & 0xff)<<2) + PAD_CONFIG_BASE;
283     HWREG(padRegister) = PAD_RESET_STATE;
284     if (isFlowControlEnabled(hwAttrs)) {
285         if (hwAttrs->ctsPin != UART2CC32XX_PIN_UNASSIGNED) {
286             padRegister = (PinToPadGet((hwAttrs->ctsPin) & 0xff)<<2)
287                                        + PAD_CONFIG_BASE;
288             HWREG(padRegister) = PAD_RESET_STATE;
289         }
290 
291         if (hwAttrs->rtsPin != UART2CC32XX_PIN_UNASSIGNED) {
292             padRegister = (PinToPadGet((hwAttrs->rtsPin) & 0xff)<<2)
293                                        + PAD_CONFIG_BASE;
294             HWREG(padRegister) = PAD_RESET_STATE;
295         }
296     }
297 
298     object->state.opened = false;
299 }
300 
301 /*
302  *  ======== UART2CC32XX_flushRx ========
303  */
UART2CC32XX_flushRx(UART2_Handle handle)304 void UART2CC32XX_flushRx(UART2_Handle handle)
305 {
306     UART2CC32XX_HWAttrs const *hwAttrs = handle->hwAttrs;
307 
308     /* Clear any read errors */
309     MAP_UARTRxErrorClear(hwAttrs->baseAddr);
310 
311     /* Read RX FIFO until empty */
312     while (((int32_t)MAP_UARTCharGetNonBlocking(hwAttrs->baseAddr)) != -1);
313 }
314 
315 /*
316  *  ======== UART2CC32XX_hwiIntFxn ========
317  *  Hwi function that processes UART interrupts.
318  */
UART2CC32XX_hwiIntFxn(uintptr_t arg)319 static void UART2CC32XX_hwiIntFxn(uintptr_t arg)
320 {
321     uint32_t                   status;
322     uint32_t                   errStatus = 0;
323     uint32_t                   bytesToRead;
324     uint32_t                   fifoThresholdBytes;
325     UART2_Handle               handle = (UART2_Handle)arg;
326     UART2CC32XX_HWAttrs const *hwAttrs = handle->hwAttrs;
327     UART2CC32XX_Object        *object = handle->object;
328 
329     /* Clear interrupts */
330     status = MAP_UARTIntStatus(hwAttrs->baseAddr, true);
331     MAP_UARTIntClear(hwAttrs->baseAddr, status);
332 
333     if (status & (UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE)) {
334         /* Handle the error */
335         if (object->state.readReturnMode != UART2_ReadReturnMode_PARTIAL) {
336             UARTDMADisable(hwAttrs->baseAddr, UART_DMA_RX);
337 
338             /* Number of bytes not yet transferred by the DMA */
339             bytesToRead = uDMAChannelSizeGet(hwAttrs->rxDmaChannel);
340             object->bytesRead += (object->readCount - bytesToRead);
341         }
342 
343         errStatus = UARTRxErrorGet(hwAttrs->baseAddr);
344         object->rxStatus = rxStatus2ErrorCode(errStatus);
345 
346         readDone(handle);
347     }
348     else if (status & UART_INT_RT) {
349         if ((object->state.readReturnMode == UART2_ReadReturnMode_PARTIAL) &&
350                 object->readCount > 0) {
351             readData(handle, object->readCount);
352 
353             readDone(handle);
354         }
355     }
356     else if ((status & UART_INT_RX) &&
357              (object->state.readReturnMode == UART2_ReadReturnMode_PARTIAL)) {
358         /* Must leave at least one byte in the fifo to get read timeout */
359         fifoThresholdBytes = rxFifoBytes[hwAttrs->rxIntFifoThr];
360         bytesToRead = MIN(fifoThresholdBytes - 1, object->readCount);
361         readData(handle, bytesToRead);
362 
363         if (object->readCount == 0) {
364             readDone(handle);
365         }
366     }
367 
368     /* Read data if characters are available. */
369     if ((object->state.readReturnMode != UART2_ReadReturnMode_PARTIAL) &&
370         object->readSize && !uDMAChannelIsEnabled(hwAttrs->rxDmaChannel)) {
371         UARTDMADisable(hwAttrs->baseAddr, UART_DMA_RX);
372 
373         errStatus = MAP_UARTRxErrorGet(hwAttrs->baseAddr);
374         object->rxStatus = rxStatus2ErrorCode(errStatus);
375         MAP_UARTRxErrorClear(hwAttrs->baseAddr);
376 
377         UARTIntDisable(hwAttrs->baseAddr, UART_INT_DMARX);
378         UARTIntClear(hwAttrs->baseAddr, UART_INT_DMARX);
379 
380         if (object->readCount != 0) {
381             object->bytesRead += object->rxSize;
382             object->readCount -= object->rxSize;
383 
384             if (--object->nReadTransfers == 0) {
385                 readDone(handle);
386             }
387             else {
388                 /* Start a new DMA transfer */
389                 configDmaRx(handle);
390             }
391         }
392     }
393 
394     /* Write completed. */
395     if (object->writeCount && !MAP_uDMAChannelIsEnabled(hwAttrs->txDmaChannel)) {
396         /*
397          * Cannot clear DMATXRIS in the UART_RIS register without disabling
398          * DMA
399          */
400         UARTDMADisable(hwAttrs->baseAddr, UART_DMA_TX);
401 
402         UARTIntDisable(hwAttrs->baseAddr, UART_INT_DMATX);
403         UARTIntClear(hwAttrs->baseAddr, UART_INT_DMATX);
404 
405         object->bytesWritten += object->txSize;
406         object->writeCount -= object->txSize;
407 
408         if ((object->writeCount) && (--object->nWriteTransfers > 0)) {
409             configDmaTx(handle);
410         }
411     }
412 
413     /* EOT interrupt received */
414     if (status & (UART_INT_EOT)) {
415         /* Check txEnabled in case writeCancel was called */
416         if ((object->writeCount == 0) && object->state.txEnabled) {
417             Power_releaseConstraint(PowerCC32XX_DISALLOW_LPDS);
418 
419             object->state.txEnabled = false;
420             object->writeSize = 0;
421             object->writeCallback(handle, (void *)object->writeBuf,
422                     object->bytesWritten, object->userArg, object->txStatus);
423         }
424     }
425 }
426 
427 /*
428  *  ======== UART2CC32XX_open ========
429  */
UART2CC32XX_open(uint_least8_t index,UART2_Params * params)430 UART2_Handle UART2CC32XX_open(uint_least8_t index, UART2_Params *params)
431 {
432     UART2_Handle               handle = NULL;
433     UART2CC32XX_Object        *object;
434     UART2CC32XX_HWAttrs const *hwAttrs;
435     HwiP_Params                hwiParams;
436     uintptr_t                  key;
437     uint16_t                   pin;
438     uint16_t                   mode;
439 
440     if (index < UART2_count) {
441         handle = (UART2_Handle)&(UART2_config[index]);
442         hwAttrs = handle->hwAttrs;
443         object = handle->object;
444     }
445     else {
446         return (NULL);
447     }
448 
449     /* Check for callback when in UART2_Mode_CALLBACK */
450     if (((params->readMode == UART2_Mode_CALLBACK) &&
451         (params->readCallback == NULL)) ||
452          ((params->writeMode == UART2_Mode_CALLBACK) &&
453           (params->writeCallback == NULL))) {
454         return (NULL);
455     }
456 
457     key = HwiP_disable();
458 
459     if (object->state.opened) {
460         HwiP_restore(key);
461         return (NULL);
462     }
463     object->state.opened = true;
464 
465     HwiP_restore(key);
466 
467     object->state.txEnabled      = false;
468     object->state.readMode       = params->readMode;
469     object->state.writeMode      = params->writeMode;
470     object->state.readReturnMode = params->readReturnMode;
471     object->readCallback         = params->readCallback;
472     object->writeCallback        = params->writeCallback;
473     object->baudRate             = params->baudRate;
474     object->stopBits             = params->stopBits;
475     object->dataLength           = params->dataLength;
476     object->parityType           = params->parityType;
477     object->userArg              = params->userArg;
478 
479     /* Set UART transaction variables to defaults. */
480     object->writeBuf             = NULL;
481     object->readBuf              = NULL;
482     object->writeCount           = 0;
483     object->readCount            = 0;
484     object->writeSize            = 0;
485     object->readSize             = 0;
486     object->nWriteTransfers      = 0;
487     object->nReadTransfers       = 0;
488     object->rxStatus             = 0;
489     object->txStatus             = 0;
490     object->state.txEnabled      = false;
491     object->txPin                = (uint16_t)-1;
492     object->rtsPin               = (uint16_t)-1;
493 
494     object->readSem = NULL;
495     object->writeSem = NULL;
496     object->hwi = NULL;
497 
498     /* Determine the Power resource Id from the UART base address */
499     object->powerMgrId = getPowerMgrId(hwAttrs->baseAddr);
500     if (object->powerMgrId >= PowerCC32XX_NUMRESOURCES) {
501         object->state.opened = false;
502         return (NULL);
503     }
504 
505     /*
506      *  Register power dependency. Keeps the clock running in SLP
507      *  and DSLP modes.
508      */
509     Power_setDependency(object->powerMgrId);
510 
511     /* Do a software reset of the peripheral */
512     PowerCC32XX_reset(object->powerMgrId);
513 
514     pin = (hwAttrs->rxPin) & 0xff;
515     mode = (hwAttrs->rxPin >> 8) & 0xff;
516 
517     MAP_PinTypeUART((unsigned long)pin, (unsigned long)mode);
518 
519     pin = (hwAttrs->txPin) & 0xff;
520     mode = (hwAttrs->txPin >> 8) & 0xff;
521 
522     MAP_PinTypeUART((unsigned long)pin, (unsigned long)mode);
523 
524     /*
525      * Read and save TX pin park state; set to "don't park" while UART is
526      * open as device default is logic '1' during LPDS
527      */
528     object->prevParkTX =
529         (PowerCC32XX_ParkState) PowerCC32XX_getParkState((PowerCC32XX_Pin)pin);
530     PowerCC32XX_setParkState((PowerCC32XX_Pin)pin, ~1);
531     object->txPin = pin;
532 
533     if (isFlowControlEnabled(hwAttrs)) {
534         if (hwAttrs->ctsPin != UART2CC32XX_PIN_UNASSIGNED) {
535             pin = (hwAttrs->ctsPin) & 0xff;
536             mode = (hwAttrs->ctsPin >> 8) & 0xff;
537             MAP_PinTypeUART((unsigned long)pin, (unsigned long)mode);
538         }
539 
540         if (hwAttrs->rtsPin != UART2CC32XX_PIN_UNASSIGNED) {
541             pin = (hwAttrs->rtsPin) & 0xff;
542             mode = (hwAttrs->rtsPin >> 8) & 0xff;
543             MAP_PinTypeUART((unsigned long)pin, (unsigned long)mode);
544 
545             /*
546              * Read and save RTS pin park state; set to "don't park" while UART is
547              * open as device default is logic '1' during LPDS
548              */
549             object->prevParkRTS = (PowerCC32XX_ParkState)PowerCC32XX_getParkState(
550                 (PowerCC32XX_Pin)pin);
551             PowerCC32XX_setParkState((PowerCC32XX_Pin)pin, ~1);
552             object->rtsPin = pin;
553         }
554 
555         /* Flow control will be enabled in initHw() */
556     }
557 
558     Power_registerNotify(&object->postNotify, PowerCC32XX_AWAKE_LPDS,
559                          postNotifyFxn, (uintptr_t)handle);
560 
561     /* DMA first */
562     UDMACC32XX_init();
563     object->udmaHandle = UDMACC32XX_open();
564     if (object->udmaHandle == NULL) {
565         UART2CC32XX_close(handle);
566         return (NULL);
567     }
568 
569     /* Initialize the hardware */
570     initHw(handle);
571 
572     HwiP_clearInterrupt(hwAttrs->intNum);
573 
574     HwiP_Params_init(&hwiParams);
575     hwiParams.arg = (uintptr_t)handle;
576     hwiParams.priority = hwAttrs->intPriority;
577 
578     object->hwi = HwiP_create(hwAttrs->intNum, UART2CC32XX_hwiIntFxn,
579                               &hwiParams);
580 
581     if (object->hwi == NULL) {
582         UART2CC32XX_close(handle);
583         return (NULL);
584     }
585 
586     /* If write mode is blocking create a semaphore and set callback. */
587     if (object->state.writeMode == UART2_Mode_BLOCKING) {
588         object->writeSem = SemaphoreP_createBinary(0);
589         if (object->writeSem == NULL) {
590             UART2CC32XX_close(handle);
591             return (NULL);
592         }
593         object->writeCallback = &writeSemCallback;
594     }
595 
596     /* If read mode is blocking create a semaphore and set callback. */
597     if (object->state.readMode == UART2_Mode_BLOCKING) {
598         object->readSem = SemaphoreP_createBinary(0);
599         if (object->readSem == NULL) {
600             UART2CC32XX_close(handle);
601             return (NULL);
602         }
603         object->readCallback = &readSemCallback;
604     }
605 
606     return (handle);
607 }
608 
609 /*
610  *  ======== UART2CC32XX_read ========
611  */
UART2CC32XX_read(UART2_Handle handle,void * buffer,size_t size,size_t * bytesRead,uint32_t timeout)612 int_fast16_t UART2CC32XX_read(UART2_Handle handle, void *buffer,
613         size_t size, size_t *bytesRead, uint32_t timeout)
614 {
615     UART2CC32XX_Object        *object = handle->object;
616     UART2CC32XX_HWAttrs const *hwAttrs = handle->hwAttrs;
617     int                        status = UART2_STATUS_SUCCESS;
618     unsigned char             *buf = (unsigned char *)buffer;
619     int32_t                    data;
620     uintptr_t                  key;
621     size_t                     nBytesRead;
622     size_t                    *pNBytesRead;
623     uint32_t                   errStatus;
624 
625     pNBytesRead = (bytesRead == NULL) ? &nBytesRead : bytesRead;
626     *pNBytesRead = 0;
627 
628     /* Check for Rx error since the last read */
629     errStatus = UARTRxErrorGet(hwAttrs->baseAddr);
630     status = rxStatus2ErrorCode(errStatus);
631     UARTRxErrorClear(hwAttrs->baseAddr);
632 
633     if (status != UART2_STATUS_SUCCESS) {
634         object->readSize = 0;
635         return (status);
636     }
637 
638 	key = HwiP_disable();
639 
640     if (object->readSize) {
641         HwiP_restore(key);
642         return (UART2_STATUS_EINUSE);
643     }
644 
645     /* Save the data to be read and restore interrupts. */
646     object->readBuf = (unsigned char *)buffer;
647     object->readSize = size;
648     object->readCount = size; /* Number remaining to be read */
649     object->bytesRead = 0;    /* Number of bytes read */
650     object->rxStatus = 0;     /* Clear receive errors */
651 
652     HwiP_restore(key);
653 
654     if (object->state.readMode == UART2_Mode_POLLING) {
655         while (size) {
656             data = UARTCharGetNonBlocking(hwAttrs->baseAddr);
657             if (data == -1) {
658                 break;
659             }
660             /* Convert error code in upper bytes of data to a UART2 status */
661             status = rxStatus2ErrorCode((data >> 8) & 0xF);
662             if (status < 0) {
663                 break;
664             }
665             *buf++ = data & 0xFF;
666             size--;
667         }
668         *pNBytesRead = object->readSize - size;
669 
670         /* Set readSize to 0 to allow another read */
671         object->readCount = 0;
672         object->readSize = 0;
673 
674         return (status);
675     }
676 
677     /* Set constraints to guarantee transaction */
678     Power_setConstraint(PowerCC32XX_DISALLOW_LPDS);
679 
680     /*
681      *  Don't use DMA for return partial mode, since we have to leave
682      *  one byte in the FIFO to get the read timeout.
683      */
684     if (object->state.readReturnMode != UART2_ReadReturnMode_PARTIAL) {
685         /* Can transfer maximum of 1024 bytes in one DMA transfer */
686         object->nReadTransfers = (object->readSize + MAX_SIZE - 1) / MAX_SIZE;
687         configDmaRx(handle);
688     }
689 
690     if (object->state.readMode == UART2_Mode_BLOCKING) {
691         if (SemaphoreP_OK != SemaphoreP_pend(object->readSem, timeout)) {
692             key = HwiP_disable();
693             if (object->readSize == 0) {
694                 /* Interrupt occurred just after SemaphoreP_pend() timeout */
695                 status = object->rxStatus;
696                 SemaphoreP_pend(object->readSem, SemaphoreP_NO_WAIT);
697                 HwiP_restore(key);
698             }
699             else {
700                 status = UART2_STATUS_ETIMEOUT;
701 
702                 /* Set readCount to 0 to prevent ISR from doing more work */
703                 object->readCount = 0;
704                 HwiP_restore(key);
705 
706                 cancelDmaRx(handle);
707 
708                 /* Release the power constraint */
709                 Power_releaseConstraint(PowerCC32XX_DISALLOW_LPDS);
710             }
711         }
712         else {
713             status = object->rxStatus;
714         }
715 
716         *pNBytesRead = object->bytesRead;
717         object->readSize = 0;  /* Allow the next read */
718     }
719     else {
720         /* ISR will do the work */
721     }
722 
723     return (status);
724 }
725 
726 /*
727  *  ======== UART2CC32XX_readCancel ========
728  */
UART2CC32XX_readCancel(UART2_Handle handle)729 void UART2CC32XX_readCancel(UART2_Handle handle)
730 {
731     UART2CC32XX_Object *object = handle->object;
732     uintptr_t           key;
733 
734     if (object->state.readMode == UART2_Mode_POLLING) {
735         return;
736     }
737 
738     key = HwiP_disable();
739 
740     if (object->readSize == 0) {
741         HwiP_restore(key);
742         return;
743     }
744 
745     cancelDmaRx(handle);
746 
747     object->readSize = 0;
748     object->rxStatus = UART2_STATUS_ECANCELLED;
749 
750     HwiP_restore(key);
751 
752     object->readCallback(handle, object->readBuf, object->bytesRead,
753                          object->userArg, UART2_STATUS_ECANCELLED);
754 }
755 
756 /*
757  *  ======== UART2CC32XX_write ========
758  */
UART2CC32XX_write(UART2_Handle handle,const void * buffer,size_t size,size_t * bytesWritten,uint32_t timeout)759 int_fast16_t UART2CC32XX_write(UART2_Handle handle, const void *buffer,
760         size_t size, size_t *bytesWritten, uint32_t timeout)
761 {
762     UART2CC32XX_Object        *object = handle->object;
763     UART2CC32XX_HWAttrs const *hwAttrs = handle->hwAttrs;
764     uintptr_t                  key;
765     int                        status = UART2_STATUS_SUCCESS;
766     uint32_t                   writeCount;
767     unsigned char             *buf = (unsigned char *)buffer;
768     size_t                     nBytesWritten;
769     size_t                    *pNBytesWritten;
770 
771     if (size == 0) {
772         return (UART2_STATUS_EINVALID);
773     }
774 
775     pNBytesWritten = (bytesWritten == NULL) ? &nBytesWritten : bytesWritten;
776 
777     key = HwiP_disable();
778 
779     if (!object->state.opened) {
780         HwiP_restore(key);
781         return (UART2_STATUS_EINVALID);
782     }
783 
784     /*
785      *  Make sure any previous write has finished.
786      *  In blocking mode, UART2_cancel() may have posted the semaphore,
787      *  so we use writeSize to ensure that there are no on-going writes.
788      *  This ensures that we can return the txStatus to the caller without
789      *  it having been reset to 0 by a pre-empting thread.
790      */
791     if (object->state.txEnabled ||
792         (object->writeSize &&
793          (object->state.writeMode == UART2_Mode_BLOCKING))) {
794         HwiP_restore(key);
795         return (UART2_STATUS_EINUSE);
796     }
797 
798     /* Save the data to be written and restore interrupts. */
799     object->writeBuf = buffer;
800     object->writeSize = size;
801     object->writeCount = size;
802     object->bytesWritten = 0;
803     object->state.txEnabled = true;
804 
805     object->txStatus = UART2_STATUS_SUCCESS;
806 
807     HwiP_restore(key);
808 
809     if (object->state.writeMode == UART2_Mode_POLLING) {
810         writeCount = 0;
811         while (size) {
812             if (!UARTCharPutNonBlocking(hwAttrs->baseAddr, *buf)) {
813                 break;
814             }
815             buf++;
816             writeCount++;
817             size--;
818         }
819         *pNBytesWritten = writeCount;
820         object->state.txEnabled = false;
821         return (status);
822     }
823 
824     Power_setConstraint(PowerCC32XX_DISALLOW_LPDS);
825 
826     object->nWriteTransfers = (object->writeSize + MAX_SIZE - 1) / MAX_SIZE;
827     configDmaTx(handle);
828 
829     /* If writeMode is blocking, block and get the state. */
830     if (object->state.writeMode == UART2_Mode_BLOCKING) {
831         /* Pend on semaphore and wait for Hwi to finish. */
832         if (SemaphoreP_OK != SemaphoreP_pend(object->writeSem, timeout)) {
833             /* Disable the TX interrupt and clear in case it's pending */
834             key = HwiP_disable();
835 
836             UARTIntDisable(hwAttrs->baseAddr, UART_INT_TX);
837             UARTIntClear(hwAttrs->baseAddr, UART_INT_TX);
838 
839             object->state.txEnabled = false;
840             object->txStatus = UART2_STATUS_ETIMEOUT;
841 
842             HwiP_restore(key);
843         }
844         status = object->txStatus; /* UART2_cancel() may have posted semaphore */
845         *pNBytesWritten = object->bytesWritten;
846         object->writeSize = 0;  /* Allow the next UART2_write */
847         object->state.txEnabled = false;
848     }
849 
850     return (status);
851 }
852 
853 /*
854  *  ======== UART2CC32XX_writeCancel ========
855  */
UART2CC32XX_writeCancel(UART2_Handle handle)856 void UART2CC32XX_writeCancel(UART2_Handle handle)
857 {
858     UART2CC32XX_Object        *object = handle->object;
859     UART2CC32XX_HWAttrs const *hwAttrs = handle->hwAttrs;
860     uint32_t                   bytesRemaining;
861     uintptr_t                  key;
862 
863     key = HwiP_disable();
864 
865     MAP_uDMAChannelDisable(hwAttrs->txDmaChannel);
866     uartDmaDisable(hwAttrs->baseAddr, UART_DMA_TX);
867 
868     UARTIntDisable(hwAttrs->baseAddr, UART_INT_DMATX);
869     UARTIntClear(hwAttrs->baseAddr, UART_INT_DMATX);
870 
871     /* Return if there is no write */
872     if ((object->writeSize == 0) && !object->state.txEnabled) {
873         HwiP_restore(key);
874         return;
875     }
876 
877     object->state.txEnabled = false;
878 
879     bytesRemaining = MAP_uDMAChannelSizeGet(hwAttrs->txDmaChannel);
880     object->bytesWritten += object->writeCount - bytesRemaining;
881 
882     /*
883      *  If the transfer didn't complete, the ISR will not run to
884      *  release the Power constraint, so do it here.
885      */
886     if (object->bytesWritten < object->writeCount) {
887         Power_releaseConstraint(PowerCC32XX_DISALLOW_LPDS);
888     }
889 
890     object->writeSize = 0;
891     object->txStatus = UART2_STATUS_ECANCELLED;
892 
893     HwiP_restore(key);
894 
895     object->writeCallback(handle, (void *)object->writeBuf,
896                           object->bytesWritten, object->userArg,
897                           UART2_STATUS_ECANCELLED);
898 }
899 
900 /*
901  *  ======== configDmaRx ========
902  *  Call with interrupts disabled.
903  */
configDmaRx(UART2_Handle handle)904 static void configDmaRx(UART2_Handle handle)
905 {
906     UART2CC32XX_Object        *object = handle->object;
907     UART2CC32XX_HWAttrs const *hwAttrs = handle->hwAttrs;
908     unsigned int               key;
909     uint32_t                   rxSize;
910 
911     rxSize = MIN(object->readCount, MAX_SIZE);
912     object->rxSize = rxSize;
913 
914     /* A lock is needed because we are accessing shared uDMA registers.*/
915     key = HwiP_disable();
916 
917     MAP_uDMAChannelControlSet(hwAttrs->rxDmaChannel, RX_CONTROL_OPTS);
918     MAP_uDMAChannelTransferSet(hwAttrs->rxDmaChannel, UDMA_MODE_BASIC,
919                                (void *)(hwAttrs->baseAddr + UART_O_DR),
920                                (void *)(object->readBuf + object->bytesRead),
921                                rxSize);
922 
923     uartDmaEnable(hwAttrs->baseAddr, UART_DMA_RX);
924 
925     MAP_UARTIntEnable(hwAttrs->baseAddr, UART_INT_DMARX);
926 
927     MAP_uDMAChannelEnable(hwAttrs->rxDmaChannel);
928 
929     HwiP_restore(key);
930 }
931 
932 /*
933  *  ======== configDmaTx ========
934  *  Call with interrupts disabled.
935  */
configDmaTx(UART2_Handle handle)936 static void configDmaTx(UART2_Handle handle)
937 {
938     UART2CC32XX_Object        *object = handle->object;
939     UART2CC32XX_HWAttrs const *hwAttrs = handle->hwAttrs;
940     unsigned int               key;
941     uint32_t                   txSize;
942 
943     /* TransferSize must be <= 1024 */
944     txSize = MIN(object->writeCount, MAX_SIZE);
945     object->txSize = txSize;
946 
947     /* A lock is needed because we are accessing shared uDMA registers.*/
948     key = HwiP_disable();
949 
950     MAP_uDMAChannelControlSet(hwAttrs->txDmaChannel, TX_CONTROL_OPTS);
951     MAP_uDMAChannelTransferSet(hwAttrs->txDmaChannel, UDMA_MODE_BASIC,
952                                (void *)(object->writeBuf + object->bytesWritten),
953                                (void *)(hwAttrs->baseAddr + UART_O_DR), txSize);
954 
955     uartDmaEnable(hwAttrs->baseAddr, UART_DMA_TX);
956 
957     MAP_UARTIntEnable(hwAttrs->baseAddr, UART_INT_DMATX);
958 
959     MAP_uDMAChannelEnable(hwAttrs->txDmaChannel);
960 
961     HwiP_restore(key);
962 }
963 
964 /*
965  *  ======== getPowerMgrId ========
966  */
getPowerMgrId(uint32_t baseAddr)967 static uint_fast16_t getPowerMgrId(uint32_t baseAddr)
968 {
969     switch (baseAddr) {
970         case UARTA0_BASE:
971             return (PowerCC32XX_PERIPH_UARTA0);
972         case UARTA1_BASE:
973             return (PowerCC32XX_PERIPH_UARTA1);
974         default:
975             return ((uint_fast16_t)(~0U));
976     }
977 }
978 
979 /*
980  *  ======== initHw ========
981  */
initHw(UART2_Handle handle)982 static void initHw(UART2_Handle handle)
983 {
984     UART2CC32XX_Object        *object = handle->object;
985     UART2CC32XX_HWAttrs const *hwAttrs = handle->hwAttrs;
986     ClockP_FreqHz              freq;
987     unsigned long              mode = UART_FLOWCONTROL_NONE;
988 
989     ClockP_getCpuFreq(&freq);
990     MAP_UARTConfigSetExpClk(hwAttrs->baseAddr, freq.lo, object->baudRate,
991                             dataLength[object->dataLength] |
992                             stopBits[object->stopBits] |
993                             parityType[object->parityType]);
994 
995     /* Clear all UART interrupts */
996     UARTIntClear(hwAttrs->baseAddr, UART_INT_OE | UART_INT_BE | UART_INT_PE |
997                                     UART_INT_FE | UART_INT_RT | UART_INT_TX |
998                                     UART_INT_RX | UART_INT_CTS | UART_INT_EOT);
999 
1000     UARTEnable(hwAttrs->baseAddr);
1001 
1002     UARTIntEnable(hwAttrs->baseAddr, UART_INT_RX | UART_INT_RT | UART_INT_OE |
1003                   UART_INT_BE | UART_INT_PE | UART_INT_FE | UART_INT_EOT);
1004 
1005     MAP_UARTFIFOLevelSet(hwAttrs->baseAddr, txFifoThreshold[hwAttrs->txIntFifoThr],
1006                          rxFifoThreshold[hwAttrs->rxIntFifoThr]);
1007 
1008     if (isFlowControlEnabled(hwAttrs)) {
1009         /* Set flow control */
1010         if (hwAttrs->ctsPin != UART2CC32XX_PIN_UNASSIGNED) {
1011             mode = UART_FLOWCONTROL_TX;
1012         }
1013 
1014         if (hwAttrs->rtsPin != UART2CC32XX_PIN_UNASSIGNED) {
1015             mode |= UART_FLOWCONTROL_RX;
1016         }
1017     }
1018     MAP_UARTFlowControlSet(hwAttrs->baseAddr, mode);
1019 
1020     if (hwAttrs->rxPin != UART2CC32XX_PIN_UNASSIGNED) {
1021         MAP_uDMAChannelAssign(hwAttrs->rxDmaChannel);
1022 
1023         uDMAChannelAttributeDisable(hwAttrs->rxDmaChannel, (UDMA_ATTR_ALTSELECT |
1024                                                             UDMA_ATTR_USEBURST |
1025                                                             UDMA_ATTR_REQMASK));
1026     }
1027 
1028     if (hwAttrs->txPin != UART2CC32XX_PIN_UNASSIGNED) {
1029         MAP_uDMAChannelAssign(hwAttrs->txDmaChannel);
1030 
1031         uDMAChannelAttributeDisable(hwAttrs->txDmaChannel, (UDMA_ATTR_ALTSELECT |
1032                                                             UDMA_ATTR_USEBURST |
1033                                                             UDMA_ATTR_REQMASK));
1034     }
1035 }
1036 
1037 /*
1038  *  ======== postNotifyFxn ========
1039  *  Called by Power module when waking up from LPDS.
1040  */
postNotifyFxn(unsigned int eventType,uintptr_t eventArg,uintptr_t clientArg)1041 static int postNotifyFxn(unsigned int eventType, uintptr_t eventArg,
1042         uintptr_t clientArg)
1043 {
1044     /* Reconfigure the hardware if returning from sleep */
1045     initHw((UART2_Handle) clientArg);
1046 
1047     return (Power_NOTIFYDONE);
1048 }
1049 
1050 /*
1051  *  ======== cancelDmaRx ========
1052  *  Stop the current DMA receive transfer.
1053  */
cancelDmaRx(UART2_Handle handle)1054 static void cancelDmaRx(UART2_Handle handle)
1055 {
1056     UART2CC32XX_Object        *object = handle->object;
1057     UART2CC32XX_HWAttrs const *hwAttrs = handle->hwAttrs;
1058     uint32_t                   bytesRemaining;
1059     uintptr_t                  key;
1060 
1061     if ((object->state.readReturnMode == UART2_ReadReturnMode_PARTIAL) ||
1062         (object->state.readMode == UART2_Mode_POLLING)) {
1063         return;
1064     }
1065 
1066     /* Disable interrupts to avoid reading data while changing state. */
1067     key = HwiP_disable();
1068 
1069     MAP_uDMAChannelDisable(hwAttrs->rxDmaChannel);
1070     uartDmaDisable(hwAttrs->baseAddr, UART_DMA_RX);
1071 
1072     UARTIntDisable(hwAttrs->baseAddr, UART_INT_DMARX);
1073     UARTIntClear(hwAttrs->baseAddr, UART_INT_DMARX);
1074 
1075     /* Return if there is no read. */
1076     if (object->readSize == 0) {
1077         HwiP_restore(key);
1078         return;
1079     }
1080 
1081     bytesRemaining = MAP_uDMAChannelSizeGet(hwAttrs->rxDmaChannel);
1082     object->bytesRead += object->readCount - bytesRemaining;
1083 
1084     /*
1085      *  Since object->readSize != 0, the ISR has not run and released
1086      *  the Power constraint.  Release the constraint here.  Setting
1087      *  object->readSize to 0 will prevent the ISR from releasing the
1088      *  constraint in case it is pending.
1089      */
1090     Power_releaseConstraint(PowerCC32XX_DISALLOW_LPDS);
1091 
1092     HwiP_restore(key);
1093 }
1094 
1095 /*
1096  *  ======== readData ========
1097  */
readData(UART2_Handle handle,int32_t size)1098 static int32_t readData(UART2_Handle handle, int32_t size)
1099 {
1100     UART2CC32XX_Object        *object = handle->object;
1101     UART2CC32XX_HWAttrs const *hwAttrs = handle->hwAttrs;
1102     int32_t                    data;
1103 
1104     if (size > object->readCount) {
1105         size = object->readCount;
1106     }
1107 
1108     while (size) {
1109         data = UARTCharGetNonBlocking(hwAttrs->baseAddr);
1110         if (data == -1) {
1111             break;
1112         }
1113         *(object->readBuf + object->bytesRead) = (uint8_t)(data & 0xFF);
1114         object->bytesRead++;
1115         object->readCount--;
1116         size--;
1117     }
1118 
1119     return (size);
1120 }
1121 
1122 /*
1123  *  ======== readDone ========
1124  *  Called from the ISR only.
1125  */
readDone(UART2_Handle handle)1126 static void readDone(UART2_Handle handle)
1127 {
1128     UART2CC32XX_Object *object = handle->object;
1129     size_t              count;
1130 
1131     /* Return if no ongoing read */
1132     if (object->readSize == 0) {
1133         return;
1134     }
1135 
1136     count = object->bytesRead;
1137 
1138     Power_releaseConstraint(PowerCC32XX_DISALLOW_LPDS);
1139 
1140     /* Set readSize to 0 to allow UART2_read() to be called */
1141     object->readSize = 0;
1142 
1143     object->readCallback(handle, object->readBuf, count, object->userArg,
1144                          object->rxStatus);
1145 }
1146 
1147 /*
1148  *  ======== readSemCallback ========
1149  *  Simple callback to post a semaphore for the blocking mode.
1150  */
readSemCallback(UART2_Handle handle,void * buffer,size_t count,void * userArg,int_fast16_t status)1151 static void readSemCallback(UART2_Handle handle, void *buffer, size_t count,
1152         void *userArg, int_fast16_t status)
1153 {
1154     UART2CC32XX_Object *object = handle->object;
1155 
1156     SemaphoreP_post(object->readSem);
1157 }
1158 
1159 /*
1160  *  ======== writeSemCallback ========
1161  *  Simple callback to post a semaphore for the blocking mode.
1162  */
writeSemCallback(UART2_Handle handle,void * buffer,size_t count,void * userArg,int_fast16_t status)1163 static void writeSemCallback(UART2_Handle handle, void *buffer, size_t count,
1164         void *userArg, int_fast16_t status)
1165 {
1166     UART2CC32XX_Object *object = handle->object;
1167 
1168     SemaphoreP_post(object->writeSem);
1169 }
1170