1 /*
2 * Copyright (c) 2014-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 #include <stdint.h>
34 #include <stdbool.h>
35 #include <ti/drivers/Power.h>
36 #include <ti/drivers/power/PowerCC32XX.h>
37
38 /*
39 * By default disable both asserts and log for this module.
40 * This must be done before DebugP.h is included.
41 */
42 #ifndef DebugP_ASSERT_ENABLED
43 #define DebugP_ASSERT_ENABLED 0
44 #endif
45 #ifndef DebugP_LOG_ENABLED
46 #define DebugP_LOG_ENABLED 0
47 #endif
48
49 #include <ti/drivers/dpl/ClockP.h>
50 #include <ti/drivers/dpl/DebugP.h>
51 #include <ti/drivers/dpl/HwiP.h>
52 #include <ti/drivers/dpl/SemaphoreP.h>
53
54 #include <ti/drivers/uart/UARTCC32XX.h>
55
56 /* driverlib header files */
57 #include <ti/devices/cc32xx/inc/hw_memmap.h>
58 #include <ti/devices/cc32xx/inc/hw_ocp_shared.h>
59 #include <ti/devices/cc32xx/inc/hw_ints.h>
60 #include <ti/devices/cc32xx/inc/hw_types.h>
61 #include <ti/devices/cc32xx/driverlib/rom.h>
62 #include <ti/devices/cc32xx/driverlib/rom_map.h>
63 #include <ti/devices/cc32xx/driverlib/uart.h>
64 #include <ti/devices/cc32xx/driverlib/pin.h>
65
66 /* Pad configuration defines */
67 #define PAD_CONFIG_BASE (OCP_SHARED_BASE + OCP_SHARED_O_GPIO_PAD_CONFIG_0)
68 #define PAD_RESET_STATE 0xC61
69
70 /* UARTCC32XX functions */
71 void UARTCC32XX_close(UART_Handle handle);
72 int_fast16_t UARTCC32XX_control(UART_Handle handle, uint_fast16_t cmd,
73 void *arg);
74 void UARTCC32XX_init(UART_Handle handle);
75 UART_Handle UARTCC32XX_open(UART_Handle handle, UART_Params *params);
76 int_fast32_t UARTCC32XX_read(UART_Handle handle, void *buffer, size_t size);
77 void UARTCC32XX_readCancel(UART_Handle handle);
78 int_fast32_t UARTCC32XX_readPolling(UART_Handle handle, void *buffer,
79 size_t size);
80 int_fast32_t UARTCC32XX_write(UART_Handle handle, const void *buffer,
81 size_t size);
82 void UARTCC32XX_writeCancel(UART_Handle handle);
83 int_fast32_t UARTCC32XX_writePolling(UART_Handle handle, const void *buffer,
84 size_t size);
85
86 /* Static functions */
87 static unsigned int getPowerMgrId(unsigned int baseAddr);
88 static void initHw(UART_Handle handle);
89 static int postNotifyFxn(unsigned int eventType, uintptr_t eventArg,
90 uintptr_t clientArg);
91 static void readBlockingTimeout(uintptr_t arg);
92 static bool readIsrBinaryBlocking(UART_Handle handle);
93 static bool readIsrBinaryCallback(UART_Handle handle);
94 static bool readIsrTextBlocking(UART_Handle handle);
95 static bool readIsrTextCallback(UART_Handle handle);
96 static void readSemCallback(UART_Handle handle, void *buffer, size_t count);
97 static int readTaskBlocking(UART_Handle handle);
98 static int readTaskCallback(UART_Handle handle);
99 static void releasePowerConstraint(UART_Handle handle);
100 static int ringBufGet(UART_Handle object, unsigned char *data);
101 static void writeData(UART_Handle handle, bool inISR);
102 static void writeSemCallback(UART_Handle handle, void *buffer, size_t count);
103
104 /*
105 * Function for checking whether flow control is enabled.
106 */
isFlowControlEnabled(UARTCC32XX_HWAttrsV1 const * hwAttrs)107 static inline bool isFlowControlEnabled(UARTCC32XX_HWAttrsV1 const *hwAttrs) {
108 return ((hwAttrs->flowControl == UARTCC32XX_FLOWCTRL_HARDWARE) &&
109 (hwAttrs->ctsPin != UARTCC32XX_PIN_UNASSIGNED) &&
110 (hwAttrs->rtsPin != UARTCC32XX_PIN_UNASSIGNED));
111 }
112
113 /* UART function table for UARTCC32XX implementation */
114 const UART_FxnTable UARTCC32XX_fxnTable = {
115 UARTCC32XX_close,
116 UARTCC32XX_control,
117 UARTCC32XX_init,
118 UARTCC32XX_open,
119 UARTCC32XX_read,
120 UARTCC32XX_readPolling,
121 UARTCC32XX_readCancel,
122 UARTCC32XX_write,
123 UARTCC32XX_writePolling,
124 UARTCC32XX_writeCancel
125 };
126
127 static const uint32_t dataLength[] = {
128 UART_CONFIG_WLEN_5, /* UART_LEN_5 */
129 UART_CONFIG_WLEN_6, /* UART_LEN_6 */
130 UART_CONFIG_WLEN_7, /* UART_LEN_7 */
131 UART_CONFIG_WLEN_8 /* UART_LEN_8 */
132 };
133
134 static const uint32_t stopBits[] = {
135 UART_CONFIG_STOP_ONE, /* UART_STOP_ONE */
136 UART_CONFIG_STOP_TWO /* UART_STOP_TWO */
137 };
138
139 static const uint32_t parityType[] = {
140 UART_CONFIG_PAR_NONE, /* UART_PAR_NONE */
141 UART_CONFIG_PAR_EVEN, /* UART_PAR_EVEN */
142 UART_CONFIG_PAR_ODD, /* UART_PAR_ODD */
143 UART_CONFIG_PAR_ZERO, /* UART_PAR_ZERO */
144 UART_CONFIG_PAR_ONE /* UART_PAR_ONE */
145 };
146
147 /*
148 * ======== staticFxnTable ========
149 * This is a function lookup table to simplify the UART driver modes.
150 */
151 static const UARTCC32XX_FxnSet staticFxnTable[2][2] = {
152 {/* UART_MODE_BLOCKING */
153 {/* UART_DATA_BINARY */
154 .readIsrFxn = readIsrBinaryBlocking,
155 .readTaskFxn = readTaskBlocking
156 },
157 {/* UART_DATA_TEXT */
158 .readIsrFxn = readIsrTextBlocking,
159 .readTaskFxn = readTaskBlocking
160 }
161 },
162 {/* UART_MODE_CALLBACK */
163 {/* UART_DATA_BINARY */
164 .readIsrFxn = readIsrBinaryCallback,
165 .readTaskFxn = readTaskCallback
166
167 },
168 {/* UART_DATA_TEXT */
169 .readIsrFxn = readIsrTextCallback,
170 .readTaskFxn = readTaskCallback,
171 }
172 }
173 };
174
175 /*
176 * ======== UARTCC32XX_close ========
177 */
UARTCC32XX_close(UART_Handle handle)178 void UARTCC32XX_close(UART_Handle handle)
179 {
180 UARTCC32XX_Object *object = handle->object;
181 UARTCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
182 uint_fast16_t retVal;
183 uint32_t padRegister;
184
185 /* Disable UART and interrupts. */
186 MAP_UARTIntDisable(hwAttrs->baseAddr, UART_INT_TX | UART_INT_RX |
187 UART_INT_RT | UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE);
188 MAP_UARTDisable(hwAttrs->baseAddr);
189
190 if (object->hwiHandle) {
191 HwiP_delete(object->hwiHandle);
192 }
193 if (object->writeSem) {
194 SemaphoreP_delete(object->writeSem);
195 }
196 if (object->readSem) {
197 SemaphoreP_delete(object->readSem);
198 }
199 if (object->timeoutClk) {
200 ClockP_delete(object->timeoutClk);
201 }
202
203 if (object->state.txEnabled) {
204 retVal = Power_releaseConstraint(PowerCC32XX_DISALLOW_LPDS);
205 DebugP_assert(retVal == Power_SOK);
206 object->state.txEnabled = false;
207 }
208
209 Power_unregisterNotify(&object->postNotify);
210 if (object->state.rxEnabled) {
211 retVal = Power_releaseConstraint(PowerCC32XX_DISALLOW_LPDS);
212 DebugP_assert(retVal == Power_SOK);
213 object->state.rxEnabled = false;
214
215 DebugP_log1("UART:(%p) UART_close released read power constraint",
216 hwAttrs->baseAddr);
217 }
218 Power_releaseDependency(object->powerMgrId);
219
220 if (object->txPin != (uint16_t)-1) {
221 PowerCC32XX_restoreParkState((PowerCC32XX_Pin)object->txPin,
222 object->prevParkTX);
223 object->txPin = (uint16_t)-1;
224 }
225
226 if (object->rtsPin != (uint16_t)-1) {
227 PowerCC32XX_restoreParkState((PowerCC32XX_Pin)object->rtsPin,
228 object->prevParkRTS);
229 object->rtsPin = (uint16_t)-1;
230 }
231
232 /* Restore pin pads to their reset states */
233 padRegister = (PinToPadGet((hwAttrs->rxPin) & 0xff)<<2) + PAD_CONFIG_BASE;
234 HWREG(padRegister) = PAD_RESET_STATE;
235 padRegister = (PinToPadGet((hwAttrs->txPin) & 0xff)<<2) + PAD_CONFIG_BASE;
236 HWREG(padRegister) = PAD_RESET_STATE;
237 if (isFlowControlEnabled(hwAttrs)) {
238 padRegister = (PinToPadGet((hwAttrs->ctsPin) & 0xff)<<2)
239 + PAD_CONFIG_BASE;
240 HWREG(padRegister) = PAD_RESET_STATE;
241 padRegister = (PinToPadGet((hwAttrs->rtsPin) & 0xff)<<2)
242 + PAD_CONFIG_BASE;
243 HWREG(padRegister) = PAD_RESET_STATE;
244 }
245
246 object->state.opened = false;
247
248 DebugP_log1("UART:(%p) closed", hwAttrs->baseAddr);
249
250 (void)retVal;
251 }
252
253 /*
254 * ======== UARTCC32XX_control ========
255 * @pre Function assumes that the handle is not NULL
256 */
UARTCC32XX_control(UART_Handle handle,uint_fast16_t cmd,void * arg)257 int_fast16_t UARTCC32XX_control(UART_Handle handle, uint_fast16_t cmd,
258 void *arg)
259 {
260 UARTCC32XX_Object *object = handle->object;
261 UARTCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
262 unsigned char data;
263 int bufferCount;
264 uint_fast16_t retVal;
265
266 bufferCount = RingBuf_peek(&object->ringBuffer, &data);
267
268 switch (cmd) {
269 /* Common UART CMDs */
270 case (UART_CMD_PEEK):
271 *(int *)arg = (bufferCount) ? data : UART_ERROR;
272 DebugP_log2("UART:(%p) UART_CMD_PEEK: %d", hwAttrs->baseAddr,
273 *(uintptr_t*)arg);
274 return (UART_STATUS_SUCCESS);
275
276 case (UART_CMD_ISAVAILABLE):
277 *(bool *)arg = (bufferCount != 0);
278 DebugP_log2("UART:(%p) UART_CMD_ISAVAILABLE: %d", hwAttrs->baseAddr,
279 *(uintptr_t*)arg);
280 return (UART_STATUS_SUCCESS);
281
282 case (UART_CMD_GETRXCOUNT):
283 *(int *)arg = bufferCount;
284 DebugP_log2("UART:(%p) UART_CMD_GETRXCOUNT: %d", hwAttrs->baseAddr,
285 *(uintptr_t*)arg);
286 return (UART_STATUS_SUCCESS);
287
288 case (UART_CMD_RXENABLE):
289 if (!object->state.rxEnabled) {
290 Power_setConstraint(PowerCC32XX_DISALLOW_LPDS);
291 MAP_UARTIntEnable(hwAttrs->baseAddr, UART_INT_RX | UART_INT_RT |
292 UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE);
293 object->state.rxEnabled = true;
294 DebugP_log1("UART:(%p) UART_CMD_RXENABLE: Enabled",
295 hwAttrs->baseAddr);
296 DebugP_log1("UART:(%p) UART_control set read power constraint",
297 hwAttrs->baseAddr);
298 return (UART_STATUS_SUCCESS);
299 }
300 DebugP_log1("UART:(%p) UART_CMD_RXENABLE: Already enabled",
301 hwAttrs->baseAddr);
302 return (UART_STATUS_ERROR);
303
304 case (UART_CMD_RXDISABLE):
305 if (object->state.rxEnabled) {
306 MAP_UARTIntDisable(hwAttrs->baseAddr, UART_INT_RX | UART_INT_RT |
307 UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE);
308 retVal = Power_releaseConstraint(PowerCC32XX_DISALLOW_LPDS);
309 DebugP_assert(retVal == Power_SOK);
310 object->state.rxEnabled = false;
311 DebugP_log1("UART:(%p) UART_CMD_RXDISABLE: Disabled",
312 hwAttrs->baseAddr);
313 DebugP_log1("UART:(%p) UART_control released read power "
314 "constraint", hwAttrs->baseAddr);
315
316 (void)retVal;
317 return (UART_STATUS_SUCCESS);
318 }
319 DebugP_log1("UART:(%p) UART_CMD_RXDISABLE: Already disabled",
320 hwAttrs->baseAddr);
321 return (UART_STATUS_ERROR);
322
323 /* Specific UART CMDs */
324 case (UARTCC32XX_CMD_IS_BUSY):
325 *(bool *)arg = MAP_UARTBusy(hwAttrs->baseAddr);
326 return (UART_STATUS_SUCCESS);
327
328 case (UARTCC32XX_CMD_IS_RX_DATA_AVAILABLE):
329 *(bool *)arg = MAP_UARTCharsAvail(hwAttrs->baseAddr);
330 return (UART_STATUS_SUCCESS);
331
332 case (UARTCC32XX_CMD_IS_TX_SPACE_AVAILABLE):
333 *(bool *)arg = MAP_UARTSpaceAvail(hwAttrs->baseAddr);
334 return (UART_STATUS_SUCCESS);
335
336 default:
337 DebugP_log2("UART:(%p) UART CMD undefined: %d",
338 hwAttrs->baseAddr, cmd);
339 return (UART_STATUS_UNDEFINEDCMD);
340 }
341 }
342
343 /*
344 * ======== UARTCC32XX_hwiIntFxn ========
345 * Hwi function that processes UART interrupts.
346 *
347 * @param(arg) The UART_Handle for this Hwi.
348 */
UARTCC32XX_hwiIntFxn(uintptr_t arg)349 static void UARTCC32XX_hwiIntFxn(uintptr_t arg)
350 {
351 uint32_t status;
352 UARTCC32XX_Object *object = ((UART_Handle)arg)->object;
353 UARTCC32XX_HWAttrsV1 const *hwAttrs = ((UART_Handle)arg)->hwAttrs;
354 uint32_t rxErrors;
355
356 /* Clear interrupts */
357 status = MAP_UARTIntStatus(hwAttrs->baseAddr, true);
358 MAP_UARTIntClear(hwAttrs->baseAddr, status);
359
360 if (status & (UART_INT_RX | UART_INT_RT | UART_INT_OE | UART_INT_BE |
361 UART_INT_PE | UART_INT_FE)) {
362 object->readFxns.readIsrFxn((UART_Handle)arg);
363 }
364
365 /* Reading the data from the FIFO doesn't mean we caught an overrrun! */
366 rxErrors = MAP_UARTRxErrorGet(hwAttrs->baseAddr);
367 if (rxErrors) {
368 MAP_UARTRxErrorClear(hwAttrs->baseAddr);
369 if (hwAttrs->errorFxn) {
370 hwAttrs->errorFxn((UART_Handle)arg, rxErrors);
371 }
372 }
373
374 if (status & UART_INT_TX) {
375 writeData((UART_Handle)arg, true);
376 }
377 }
378
379 /*
380 * ======== UARTCC32XX_init ========
381 */
UARTCC32XX_init(UART_Handle handle)382 void UARTCC32XX_init(UART_Handle handle)
383 {
384 }
385
386 /*
387 * ======== UARTCC32XX_open ========
388 */
UARTCC32XX_open(UART_Handle handle,UART_Params * params)389 UART_Handle UARTCC32XX_open(UART_Handle handle, UART_Params *params)
390 {
391 uintptr_t key;
392 UARTCC32XX_Object *object = handle->object;
393 UARTCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
394 SemaphoreP_Params semParams;
395 HwiP_Params hwiParams;
396 ClockP_Params clockParams;
397 uint16_t pin;
398 uint16_t mode;
399
400 /* Check for callback when in UART_MODE_CALLBACK */
401 DebugP_assert((params->readMode != UART_MODE_CALLBACK) ||
402 (params->readCallback != NULL));
403 DebugP_assert((params->writeMode != UART_MODE_CALLBACK) ||
404 (params->writeCallback != NULL));
405
406 key = HwiP_disable();
407
408 if (object->state.opened == true) {
409 HwiP_restore(key);
410
411 DebugP_log1("UART:(%p) already in use.", hwAttrs->baseAddr);
412 return (NULL);
413 }
414 object->state.opened = true;
415
416 HwiP_restore(key);
417
418 object->state.readMode = params->readMode;
419 object->state.writeMode = params->writeMode;
420 object->state.readReturnMode = params->readReturnMode;
421 object->state.readDataMode = params->readDataMode;
422 object->state.writeDataMode = params->writeDataMode;
423 object->state.readEcho = params->readEcho;
424 object->readTimeout = params->readTimeout;
425 object->writeTimeout = params->writeTimeout;
426 object->readCallback = params->readCallback;
427 object->writeCallback = params->writeCallback;
428 object->baudRate = params->baudRate;
429 object->stopBits = params->stopBits;
430 object->dataLength = params->dataLength;
431 object->parityType = params->parityType;
432 object->readFxns =
433 staticFxnTable[object->state.readMode][object->state.readDataMode];
434
435 /* Set UART variables to defaults. */
436 object->writeBuf = NULL;
437 object->readBuf = NULL;
438 object->writeCount = 0;
439 object->readCount = 0;
440 object->writeSize = 0;
441 object->readSize = 0;
442 object->state.txEnabled = false;
443 object->txPin = (uint16_t)-1;
444 object->rtsPin = (uint16_t)-1;
445
446 RingBuf_construct(&object->ringBuffer, hwAttrs->ringBufPtr,
447 hwAttrs->ringBufSize);
448
449 /* Get the Power resource Id from the base address */
450 object->powerMgrId = getPowerMgrId(hwAttrs->baseAddr);
451 if (object->powerMgrId == (unsigned int)-1) {
452 DebugP_log1("UART:(%p) Failed to determine Power resource id",
453 hwAttrs->baseAddr);
454 return (NULL);
455 }
456
457 /*
458 * Register power dependency. Keeps the clock running in SLP
459 * and DSLP modes.
460 */
461 Power_setDependency(object->powerMgrId);
462
463 /* Do a software reset of the peripheral */
464 PowerCC32XX_reset(object->powerMgrId);
465
466 pin = (hwAttrs->rxPin) & 0xff;
467 mode = (hwAttrs->rxPin >> 8) & 0xff;
468
469 MAP_PinTypeUART((unsigned long)pin, (unsigned long)mode);
470
471 pin = (hwAttrs->txPin) & 0xff;
472 mode = (hwAttrs->txPin >> 8) & 0xff;
473
474 MAP_PinTypeUART((unsigned long)pin, (unsigned long)mode);
475
476 /*
477 * Read and save TX pin park state; set to "don't park" while UART is
478 * open as device default is logic '1' during LPDS
479 */
480 object->prevParkTX =
481 (PowerCC32XX_ParkState) PowerCC32XX_getParkState((PowerCC32XX_Pin)pin);
482 PowerCC32XX_setParkState((PowerCC32XX_Pin)pin, ~1);
483 object->txPin = pin;
484
485 if (isFlowControlEnabled(hwAttrs)) {
486 pin = (hwAttrs->ctsPin) & 0xff;
487 mode = (hwAttrs->ctsPin >> 8) & 0xff;
488 MAP_PinTypeUART((unsigned long)pin, (unsigned long)mode);
489
490 pin = (hwAttrs->rtsPin) & 0xff;
491 mode = (hwAttrs->rtsPin >> 8) & 0xff;
492 MAP_PinTypeUART((unsigned long)pin, (unsigned long)mode);
493
494 /*
495 * Read and save RTS pin park state; set to "don't park" while UART is
496 * open as device default is logic '1' during LPDS
497 */
498 object->prevParkRTS = (PowerCC32XX_ParkState)PowerCC32XX_getParkState(
499 (PowerCC32XX_Pin)pin);
500 PowerCC32XX_setParkState((PowerCC32XX_Pin)pin, ~1);
501 object->rtsPin = pin;
502
503 /* Flow control will be enabled in initHw() */
504 }
505
506 Power_registerNotify(&object->postNotify, PowerCC32XX_AWAKE_LPDS,
507 postNotifyFxn, (uintptr_t)handle);
508
509 Power_setConstraint(PowerCC32XX_DISALLOW_LPDS);
510 object->state.rxEnabled = true;
511
512 DebugP_log1("UART:(%p) UART_open set read power constraint",
513 hwAttrs->baseAddr);
514
515 HwiP_Params_init(&hwiParams);
516 hwiParams.arg = (uintptr_t)handle;
517 hwiParams.priority = hwAttrs->intPriority;
518 object->hwiHandle = HwiP_create(hwAttrs->intNum, UARTCC32XX_hwiIntFxn,
519 &hwiParams);
520 if (object->hwiHandle == NULL) {
521 DebugP_log1("UART:(%p) HwiP_create() failed", hwAttrs->baseAddr);
522 UARTCC32XX_close(handle);
523 return (NULL);
524 }
525
526 SemaphoreP_Params_init(&semParams);
527 semParams.mode = SemaphoreP_Mode_BINARY;
528
529 /* If write mode is blocking create a semaphore and set callback. */
530 if (object->state.writeMode == UART_MODE_BLOCKING) {
531 if ((object->writeSem = SemaphoreP_create(0, &semParams)) == NULL) {
532 DebugP_log1("UART:(%p) SemaphoreP_create() failed.",
533 hwAttrs->baseAddr);
534 UARTCC32XX_close(handle);
535 return (NULL);
536 }
537 object->writeCallback = &writeSemCallback;
538 }
539
540 ClockP_Params_init(&clockParams);
541 clockParams.arg = (uintptr_t)handle;
542
543 /* If read mode is blocking create a semaphore and set callback. */
544 if (object->state.readMode == UART_MODE_BLOCKING) {
545 object->readSem = SemaphoreP_create(0, &semParams);
546 if (object->readSem == NULL) {
547 DebugP_log1("UART:(%p) SemaphoreP_create() failed.",
548 hwAttrs->baseAddr);
549 UARTCC32XX_close(handle);
550 return (NULL);
551 }
552 object->readCallback = &readSemCallback;
553 object->timeoutClk =
554 ClockP_create((ClockP_Fxn)&readBlockingTimeout,
555 0 /* timeout */, &(clockParams));
556 if (object->timeoutClk == NULL) {
557 DebugP_log1("UART:(%p) ClockP_create() failed.",
558 hwAttrs->baseAddr);
559 UARTCC32XX_close(handle);
560 return (NULL);
561 }
562 }
563 else {
564 object->state.drainByISR = false;
565 }
566
567 /* Initialize the hardware */
568 initHw(handle);
569
570 DebugP_log1("UART:(%p) opened", hwAttrs->baseAddr);
571
572 /* Return the handle */
573 return (handle);
574 }
575
576 /*
577 * ======== UARTCC32XX_read ========
578 */
UARTCC32XX_read(UART_Handle handle,void * buffer,size_t size)579 int_fast32_t UARTCC32XX_read(UART_Handle handle, void *buffer, size_t size)
580 {
581 uintptr_t key;
582 UARTCC32XX_Object *object = handle->object;
583
584 key = HwiP_disable();
585
586 if ((object->state.readMode == UART_MODE_CALLBACK) && object->readSize) {
587 HwiP_restore(key);
588
589 DebugP_log1("UART:(%p) Could not read data, uart in use.",
590 ((UARTCC32XX_HWAttrsV1 const *)(handle->hwAttrs))->baseAddr);
591 return (UART_ERROR);
592 }
593
594 /* Save the data to be read and restore interrupts. */
595 object->readBuf = buffer;
596 object->readSize = size;
597 object->readCount = size;
598
599 HwiP_restore(key);
600
601 return (object->readFxns.readTaskFxn(handle));
602 }
603
604 /*
605 * ======== UARTCC32XX_readCancel ========
606 */
UARTCC32XX_readCancel(UART_Handle handle)607 void UARTCC32XX_readCancel(UART_Handle handle)
608 {
609 uintptr_t key;
610 UARTCC32XX_Object *object = handle->object;
611
612 if ((object->state.readMode != UART_MODE_CALLBACK) ||
613 (object->readSize == 0)) {
614 return;
615 }
616
617 key = HwiP_disable();
618
619 object->state.drainByISR = false;
620 /*
621 * Indicate that what we've currently received is what we asked for so that
622 * the existing logic handles the completion.
623 */
624 object->readSize -= object->readCount;
625 object->readCount = 0;
626
627 HwiP_restore(key);
628
629 object->readFxns.readTaskFxn(handle);
630 }
631
632 /*
633 * ======== UARTCC32XX_readPolling ========
634 */
UARTCC32XX_readPolling(UART_Handle handle,void * buf,size_t size)635 int_fast32_t UARTCC32XX_readPolling(UART_Handle handle, void *buf, size_t size)
636 {
637 int32_t count = 0;
638 UARTCC32XX_Object *object = handle->object;
639 UARTCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
640 unsigned char *buffer = (unsigned char *)buf;
641
642 /* Read characters. */
643 while (size) {
644 /* Grab data from the RingBuf before getting it from the RX data reg */
645 MAP_UARTIntDisable(hwAttrs->baseAddr, UART_INT_RX | UART_INT_RT);
646 if (RingBuf_get(&object->ringBuffer, buffer) == -1) {
647 *buffer = MAP_UARTCharGet(hwAttrs->baseAddr);
648 }
649 if (object->state.rxEnabled) {
650 MAP_UARTIntEnable(hwAttrs->baseAddr, UART_INT_RX | UART_INT_RT);
651 }
652
653 DebugP_log2("UART:(%p) Read character 0x%x", hwAttrs->baseAddr,
654 *buffer);
655 count++;
656 size--;
657
658 if (object->state.readDataMode == UART_DATA_TEXT && *buffer == '\r') {
659 /* Echo character if enabled. */
660 if (object->state.readEcho) {
661 MAP_UARTCharPut(hwAttrs->baseAddr, '\r');
662 }
663 *buffer = '\n';
664 }
665
666 /* Echo character if enabled. */
667 if (object->state.readDataMode == UART_DATA_TEXT &&
668 object->state.readEcho) {
669 MAP_UARTCharPut(hwAttrs->baseAddr, *buffer);
670 }
671
672 /* If read return mode is newline, finish if a newline was received. */
673 if (object->state.readDataMode == UART_DATA_TEXT &&
674 object->state.readReturnMode == UART_RETURN_NEWLINE &&
675 *buffer == '\n') {
676 return (count);
677 }
678
679 buffer++;
680 }
681
682 DebugP_log2("UART:(%p) Read polling finished, %d bytes read",
683 hwAttrs->baseAddr, count);
684
685 return (count);
686 }
687
688 /*
689 * ======== UARTCC32XX_write ========
690 */
UARTCC32XX_write(UART_Handle handle,const void * buffer,size_t size)691 int_fast32_t UARTCC32XX_write(UART_Handle handle, const void *buffer,
692 size_t size)
693 {
694 unsigned int key;
695 UARTCC32XX_Object *object = handle->object;
696 UARTCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
697
698 if (!size) {
699 return 0;
700 }
701
702 key = HwiP_disable();
703
704 if (object->writeCount || UARTBusy(hwAttrs->baseAddr)) {
705 HwiP_restore(key);
706 DebugP_log1("UART:(%p) Could not write data, uart in use.",
707 hwAttrs->baseAddr);
708
709 return (UART_ERROR);
710 }
711
712 /* Save the data to be written and restore interrupts. */
713 object->writeBuf = buffer;
714 object->writeSize = size;
715 object->writeCount = size;
716
717 if (object->state.txEnabled == false){
718 object->state.txEnabled = true;
719 Power_setConstraint(PowerCC32XX_DISALLOW_LPDS);
720 DebugP_log1("UART:(%p) UART_write set write power constraint",
721 hwAttrs->baseAddr);
722 }
723
724 HwiP_restore(key);
725
726 if (!(MAP_UARTIntStatus(hwAttrs->baseAddr, false) & UART_INT_TX)) {
727 /*
728 * Start the transfer going if the raw interrupt status TX bit
729 * is 0. This will cause the ISR to fire when we enable
730 * UART_INT_TX. If the RIS TX bit is not cleared, we don't
731 * need to call writeData(), since the ISR will fire once we
732 * enable the interrupt, causing the transfer to start.
733 */
734 writeData(handle, false);
735 }
736 if (object->writeCount) {
737 MAP_UARTTxIntModeSet(hwAttrs->baseAddr, UART_TXINT_MODE_FIFO);
738 MAP_UARTIntEnable(hwAttrs->baseAddr, UART_INT_TX);
739 }
740
741 /* If writeMode is blocking, block and get the state. */
742 if (object->state.writeMode == UART_MODE_BLOCKING) {
743 /* Pend on semaphore and wait for Hwi to finish. */
744 if (SemaphoreP_OK != SemaphoreP_pend(object->writeSem,
745 object->writeTimeout)) {
746 /* Semaphore timed out, make the write empty and log the write. */
747 MAP_UARTIntDisable(hwAttrs->baseAddr, UART_INT_TX);
748 MAP_UARTIntClear(hwAttrs->baseAddr, UART_INT_TX);
749 object->writeCount = 0;
750
751 DebugP_log2("UART:(%p) Write timed out, %d bytes written",
752 hwAttrs->baseAddr, object->writeCount);
753 }
754 return (object->writeSize - object->writeCount);
755 }
756
757 return (0);
758 }
759
760 /*
761 * ======== UARTCC32XX_writeCancel ========
762 */
UARTCC32XX_writeCancel(UART_Handle handle)763 void UARTCC32XX_writeCancel(UART_Handle handle)
764 {
765 uintptr_t key;
766 UARTCC32XX_Object *object = handle->object;
767 UARTCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
768 unsigned int written;
769 uint_fast16_t retVal;
770
771 key = HwiP_disable();
772
773 /* Return if there is no write. */
774 if (!object->writeCount) {
775 HwiP_restore(key);
776 return;
777 }
778
779 /* Set size = 0 to prevent writing and restore interrupts. */
780 written = object->writeCount;
781 object->writeCount = 0;
782 MAP_UARTIntDisable(hwAttrs->baseAddr, UART_INT_TX);
783 MAP_UARTIntClear(hwAttrs->baseAddr, UART_INT_TX);
784
785 retVal = Power_releaseConstraint(PowerCC32XX_DISALLOW_LPDS);
786 DebugP_assert(retVal == Power_SOK);
787 object->state.txEnabled = false;
788
789 HwiP_restore(key);
790
791 /* Reset the write buffer so we can pass it back */
792 object->writeCallback(handle, (void *)object->writeBuf,
793 object->writeSize - written);
794
795 DebugP_log2("UART:(%p) Write canceled, %d bytes written",
796 hwAttrs->baseAddr, object->writeSize - written);
797
798 (void)retVal;
799 }
800
801 /*
802 * ======== UARTCC32XX_writePolling ========
803 */
UARTCC32XX_writePolling(UART_Handle handle,const void * buf,size_t size)804 int_fast32_t UARTCC32XX_writePolling(UART_Handle handle, const void *buf,
805 size_t size)
806 {
807 int32_t count = 0;
808 UARTCC32XX_Object *object = handle->object;
809 UARTCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
810 unsigned char *buffer = (unsigned char *)buf;
811
812 /* Write characters. */
813 while (size) {
814 if (object->state.writeDataMode == UART_DATA_TEXT && *buffer == '\n') {
815 MAP_UARTCharPut(hwAttrs->baseAddr, '\r');
816 count++;
817 }
818 MAP_UARTCharPut(hwAttrs->baseAddr, *buffer);
819
820 DebugP_log2("UART:(%p) Wrote character 0x%x", hwAttrs->baseAddr,
821 *buffer);
822 buffer++;
823 count++;
824 size--;
825 }
826
827 while (MAP_UARTBusy(hwAttrs->baseAddr)) {
828 ;
829 }
830
831 DebugP_log2("UART:(%p) Write polling finished, %d bytes written",
832 hwAttrs->baseAddr, count);
833
834 return (count);
835 }
836
837 /*
838 * ======== getPowerMgrId ========
839 */
getPowerMgrId(unsigned int baseAddr)840 static unsigned int getPowerMgrId(unsigned int baseAddr)
841 {
842 switch (baseAddr) {
843 case UARTA0_BASE:
844 return (PowerCC32XX_PERIPH_UARTA0);
845 case UARTA1_BASE:
846 return (PowerCC32XX_PERIPH_UARTA1);
847 default:
848 return ((unsigned int)-1);
849 }
850 }
851
852 /*
853 * ======== initHw ========
854 */
initHw(UART_Handle handle)855 static void initHw(UART_Handle handle)
856 {
857 ClockP_FreqHz freq;
858 UARTCC32XX_Object *object = handle->object;
859 UARTCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
860
861 /* Enable UART and its interrupt. */
862 MAP_UARTIntClear(hwAttrs->baseAddr, UART_INT_TX | UART_INT_RX |
863 UART_INT_RT);
864 MAP_UARTEnable(hwAttrs->baseAddr);
865
866 /* Set the FIFO level to 7/8 empty and 4/8 full. */
867 MAP_UARTFIFOLevelSet(hwAttrs->baseAddr, UART_FIFO_TX1_8, UART_FIFO_RX1_8);
868
869 if (isFlowControlEnabled(hwAttrs)) {
870 /* Set flow control */
871 MAP_UARTFlowControlSet(hwAttrs->baseAddr,
872 UART_FLOWCONTROL_TX | UART_FLOWCONTROL_RX);
873 }
874 else {
875 MAP_UARTFlowControlSet(hwAttrs->baseAddr, UART_FLOWCONTROL_NONE);
876 }
877
878 ClockP_getCpuFreq(&freq);
879 MAP_UARTConfigSetExpClk(hwAttrs->baseAddr, freq.lo, object->baudRate,
880 dataLength[object->dataLength] | stopBits[object->stopBits] |
881 parityType[object->parityType]);
882
883 MAP_UARTIntEnable(hwAttrs->baseAddr, UART_INT_RX | UART_INT_RT |
884 UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE);
885 }
886
887 /*
888 * ======== postNotifyFxn ========
889 * Called by Power module when waking up from LPDS.
890 */
postNotifyFxn(unsigned int eventType,uintptr_t eventArg,uintptr_t clientArg)891 static int postNotifyFxn(unsigned int eventType, uintptr_t eventArg,
892 uintptr_t clientArg)
893 {
894 initHw((UART_Handle)clientArg);
895
896 return (Power_NOTIFYDONE);
897 }
898
899 /*
900 * ======== readBlockingTimeout ========
901 */
readBlockingTimeout(uintptr_t arg)902 static void readBlockingTimeout(uintptr_t arg)
903 {
904 UARTCC32XX_Object *object = ((UART_Handle)arg)->object;
905 object->state.bufTimeout = true;
906 SemaphoreP_post(object->readSem);
907 }
908
909 /*
910 * ======== readIsrBinaryBlocking ========
911 * Function that is called by the ISR
912 */
readIsrBinaryBlocking(UART_Handle handle)913 static bool readIsrBinaryBlocking(UART_Handle handle)
914 {
915 UARTCC32XX_Object *object = handle->object;
916 UARTCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
917 int readIn;
918
919 while (MAP_UARTCharsAvail(hwAttrs->baseAddr)) {
920 /*
921 * If the Ring buffer is full, leave the data in the FIFO.
922 * This will allow flow control to work, if it is enabled.
923 */
924 if (RingBuf_isFull(&object->ringBuffer)) {
925 return (false);
926 }
927
928 readIn = MAP_UARTCharGetNonBlocking(hwAttrs->baseAddr);
929 /*
930 * Bits 0-7 contain the data, bits 8-11 are used for error codes.
931 * (Bits 12-31 are reserved and read as 0) If readIn > 0xFF, an
932 * error has occurred.
933 */
934 if (readIn > 0xFF) {
935 if (hwAttrs->errorFxn) {
936 hwAttrs->errorFxn(handle, (uint32_t)((readIn >> 8) & 0xF));
937 }
938 MAP_UARTRxErrorClear(hwAttrs->baseAddr);
939 return (false);
940 }
941
942 RingBuf_put(&object->ringBuffer, (unsigned char)readIn);
943
944 if (object->state.callCallback) {
945 object->state.callCallback = false;
946 object->readCallback(handle, NULL, 0);
947 }
948 }
949 return (true);
950 }
951
952 /*
953 * ======== readIsrBinaryCallback ========
954 */
readIsrBinaryCallback(UART_Handle handle)955 static bool readIsrBinaryCallback(UART_Handle handle)
956 {
957 UARTCC32XX_Object *object = handle->object;
958 UARTCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
959 int readIn;
960 bool ret = true;
961
962 while (MAP_UARTCharsAvail(hwAttrs->baseAddr)) {
963 if (RingBuf_isFull(&object->ringBuffer)) {
964 ret = false;
965 break;
966 }
967
968 readIn = MAP_UARTCharGetNonBlocking(hwAttrs->baseAddr);
969 if (readIn > 0xFF) {
970 if (hwAttrs->errorFxn) {
971 hwAttrs->errorFxn(handle, (uint32_t)((readIn >> 8) & 0xF));
972 }
973 MAP_UARTRxErrorClear(hwAttrs->baseAddr);
974 ret = false;
975 break;
976 }
977
978 RingBuf_put(&object->ringBuffer, (unsigned char)readIn);
979 }
980
981 /*
982 * Check and see if a UART_read in callback mode told use to continue
983 * servicing the user buffer...
984 */
985 if (object->state.drainByISR) {
986 readTaskCallback(handle);
987 }
988
989 return (ret);
990 }
991
992 /*
993 * ======== readIsrTextBlocking ========
994 */
readIsrTextBlocking(UART_Handle handle)995 static bool readIsrTextBlocking(UART_Handle handle)
996 {
997 UARTCC32XX_Object *object = handle->object;
998 UARTCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
999 int readIn;
1000
1001 while (MAP_UARTCharsAvail(hwAttrs->baseAddr)) {
1002 /*
1003 * If the Ring buffer is full, leave the data in the FIFO.
1004 * This will allow flow control to work, if it is enabled.
1005 */
1006 if (RingBuf_isFull(&object->ringBuffer)) {
1007 return (false);
1008 }
1009
1010 readIn = MAP_UARTCharGetNonBlocking(hwAttrs->baseAddr);
1011 if (readIn > 0xFF) {
1012 if (hwAttrs->errorFxn) {
1013 hwAttrs->errorFxn(handle, (uint32_t)((readIn >> 8) & 0xF));
1014 }
1015 MAP_UARTRxErrorClear(hwAttrs->baseAddr);
1016 return (false);
1017 }
1018
1019 if (readIn == '\r') {
1020 /* Echo character if enabled. */
1021 if (object->state.readEcho) {
1022 MAP_UARTCharPut(hwAttrs->baseAddr, '\r');
1023 }
1024 readIn = '\n';
1025 }
1026 RingBuf_put(&object->ringBuffer, (unsigned char)readIn);
1027
1028 if (object->state.readEcho) {
1029 MAP_UARTCharPut(hwAttrs->baseAddr, (unsigned char)readIn);
1030 }
1031 if (object->state.callCallback) {
1032 object->state.callCallback = false;
1033 object->readCallback(handle, NULL, 0);
1034 }
1035 }
1036 return (true);
1037 }
1038
1039 /*
1040 * ======== readIsrTextCallback ========
1041 */
readIsrTextCallback(UART_Handle handle)1042 static bool readIsrTextCallback(UART_Handle handle)
1043 {
1044 UARTCC32XX_Object *object = handle->object;
1045 UARTCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
1046 int readIn;
1047 bool ret = true;
1048
1049 while (MAP_UARTCharsAvail(hwAttrs->baseAddr)) {
1050 /*
1051 * If the Ring buffer is full, leave the data in the FIFO.
1052 * This will allow flow control to work, if it is enabled.
1053 */
1054 if (RingBuf_isFull(&object->ringBuffer)) {
1055 ret = false;
1056 break;
1057 }
1058
1059 readIn = MAP_UARTCharGetNonBlocking(hwAttrs->baseAddr);
1060 if (readIn > 0xFF) {
1061 if (hwAttrs->errorFxn) {
1062 hwAttrs->errorFxn(handle, (uint32_t)((readIn >> 8) & 0xF));
1063 }
1064 MAP_UARTRxErrorClear(hwAttrs->baseAddr);
1065 ret = false;
1066 break;
1067 }
1068
1069 if (readIn == '\r') {
1070 /* Echo character if enabled. */
1071 if (object->state.readEcho) {
1072 MAP_UARTCharPut(hwAttrs->baseAddr, '\r');
1073 }
1074 readIn = '\n';
1075 }
1076 RingBuf_put(&object->ringBuffer, (unsigned char)readIn);
1077
1078 if (object->state.readEcho) {
1079 MAP_UARTCharPut(hwAttrs->baseAddr, (unsigned char)readIn);
1080 }
1081 }
1082
1083 /*
1084 * Check and see if a UART_read in callback mode told use to continue
1085 * servicing the user buffer...
1086 */
1087 if (object->state.drainByISR) {
1088 readTaskCallback(handle);
1089 }
1090
1091 return (ret);
1092 }
1093
1094 /*
1095 * ======== readSemCallback ========
1096 * Simple callback to post a semaphore for the blocking mode.
1097 */
readSemCallback(UART_Handle handle,void * buffer,size_t count)1098 static void readSemCallback(UART_Handle handle, void *buffer, size_t count)
1099 {
1100 UARTCC32XX_Object *object = handle->object;
1101
1102 SemaphoreP_post(object->readSem);
1103 }
1104
1105 /*
1106 * ======== readTaskBlocking ========
1107 */
readTaskBlocking(UART_Handle handle)1108 static int readTaskBlocking(UART_Handle handle)
1109 {
1110 unsigned char readIn;
1111 uintptr_t key;
1112 UARTCC32XX_Object *object = handle->object;
1113 unsigned char *buffer = object->readBuf;
1114
1115 object->state.bufTimeout = false;
1116 object->state.callCallback = false;
1117
1118 /*
1119 * It is possible for the object->timeoutClk and the callback function to
1120 * have posted the object->readSem Semaphore from the previous UART_read
1121 * call (if the code below didn't get to stop the clock object in time).
1122 * To clear this, we simply do a NO_WAIT pend on (binary) object->readSem
1123 * so that it resets the Semaphore count.
1124 */
1125 SemaphoreP_pend(object->readSem, SemaphoreP_NO_WAIT);
1126
1127 if ((object->readTimeout != 0) &&
1128 (object->readTimeout != UART_WAIT_FOREVER)) {
1129 ClockP_setTimeout(object->timeoutClk, object->readTimeout);
1130 ClockP_start(object->timeoutClk);
1131 }
1132
1133 while (object->readCount) {
1134 key = HwiP_disable();
1135
1136 if (ringBufGet(handle, &readIn) < 0) {
1137 object->state.callCallback = true;
1138 HwiP_restore(key);
1139
1140 if (object->readTimeout == 0) {
1141 break;
1142 }
1143
1144 SemaphoreP_pend(object->readSem, SemaphoreP_WAIT_FOREVER);
1145 if (object->state.bufTimeout == true) {
1146 break;
1147 }
1148 ringBufGet(handle, &readIn);
1149 }
1150 else {
1151 HwiP_restore(key);
1152 }
1153
1154 *buffer = readIn;
1155 buffer++;
1156 /* In blocking mode, readCount doesn't not need a lock */
1157 object->readCount--;
1158
1159 if (object->state.readDataMode == UART_DATA_TEXT &&
1160 object->state.readReturnMode == UART_RETURN_NEWLINE &&
1161 readIn == '\n') {
1162 break;
1163 }
1164 }
1165
1166 ClockP_stop(object->timeoutClk);
1167 return (object->readSize - object->readCount);
1168 }
1169
1170 /*
1171 * ======== readTaskCallback ========
1172 * This function is called the first time by the UART_read task and tries to
1173 * get all the data it can get from the ringBuffer. If it finished, it will
1174 * perform the user supplied callback. If it didn't finish, the ISR must handle
1175 * the remaining data. By setting the drainByISR flag, the UART_read function
1176 * handed over the responsibility to get the remaining data to the ISR.
1177 */
readTaskCallback(UART_Handle handle)1178 static int readTaskCallback(UART_Handle handle)
1179 {
1180 unsigned int key;
1181 UARTCC32XX_Object *object = handle->object;
1182 unsigned char readIn;
1183 unsigned char *bufferEnd;
1184 bool makeCallback = false;
1185 size_t tempCount;
1186
1187 object->state.drainByISR = false;
1188 bufferEnd = (unsigned char*) object->readBuf + object->readSize;
1189
1190 while (object->readCount) {
1191 key = HwiP_disable();
1192 if (ringBufGet(handle, &readIn) < 0) {
1193 /* Not all data has been read */
1194 object->state.drainByISR = true;
1195 HwiP_restore(key);
1196 break;
1197 }
1198 HwiP_restore(key);
1199
1200 *(unsigned char *) (bufferEnd - object->readCount *
1201 sizeof(unsigned char)) = readIn;
1202
1203 object->readCount--;
1204
1205 if ((object->state.readDataMode == UART_DATA_TEXT) &&
1206 (object->state.readReturnMode == UART_RETURN_NEWLINE) &&
1207 (readIn == '\n')) {
1208 makeCallback = true;
1209 break;
1210 }
1211 }
1212
1213 if (!object->readCount || makeCallback) {
1214 object->state.readCallbackPending = true;
1215 if (object->state.inReadCallback == false) {
1216 while (object->state.readCallbackPending) {
1217 object->state.readCallbackPending = false;
1218 tempCount = object->readSize;
1219 object->readSize = 0;
1220
1221 object->state.inReadCallback = true;
1222 object->readCallback(handle, object->readBuf,
1223 tempCount - object->readCount);
1224 object->state.inReadCallback = false;
1225 }
1226 }
1227 }
1228
1229 return (0);
1230 }
1231
1232 /*
1233 * ======== releasePowerConstraint ========
1234 */
releasePowerConstraint(UART_Handle handle)1235 static void releasePowerConstraint(UART_Handle handle)
1236 {
1237 UARTCC32XX_Object *object = handle->object;
1238 uint_fast16_t retVal;
1239
1240 retVal = Power_releaseConstraint(PowerCC32XX_DISALLOW_LPDS);
1241 DebugP_assert(retVal == Power_SOK);
1242 object->state.txEnabled = false;
1243
1244 DebugP_log1("UART:(%p) UART released write power constraint",
1245 ((UARTCC32XX_HWAttrsV1 const *)(handle->hwAttrs))->baseAddr);
1246
1247 (void)retVal;
1248 }
1249
1250
1251 /*
1252 * ======== ringBufGet ========
1253 */
ringBufGet(UART_Handle handle,unsigned char * data)1254 static int ringBufGet(UART_Handle handle, unsigned char *data)
1255 {
1256 UARTCC32XX_Object *object = handle->object;
1257 UARTCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
1258 uintptr_t key;
1259 int32_t readIn;
1260 int count;
1261
1262 key = HwiP_disable();
1263
1264 if (RingBuf_isFull(&object->ringBuffer)) {
1265 count = RingBuf_get(&object->ringBuffer, data);
1266
1267 readIn = MAP_UARTCharGetNonBlocking(hwAttrs->baseAddr);
1268 if (readIn != -1) {
1269 RingBuf_put(&object->ringBuffer, (unsigned char)readIn);
1270 count++;
1271 }
1272 HwiP_restore(key);
1273 }
1274 else {
1275 count = RingBuf_get(&object->ringBuffer, data);
1276 HwiP_restore(key);
1277 }
1278
1279 return (count);
1280 }
1281
1282 /*
1283 * ======== writeData ========
1284 */
writeData(UART_Handle handle,bool inISR)1285 static void writeData(UART_Handle handle, bool inISR)
1286 {
1287 UARTCC32XX_Object *object = handle->object;
1288 UARTCC32XX_HWAttrsV1 const *hwAttrs = handle->hwAttrs;
1289 unsigned char *writeOffset;
1290
1291 writeOffset = (unsigned char *)object->writeBuf +
1292 object->writeSize * sizeof(unsigned char);
1293 while (object->writeCount) {
1294 if (!MAP_UARTCharPutNonBlocking(hwAttrs->baseAddr,
1295 *(writeOffset - object->writeCount))) {
1296 /* TX FIFO is FULL */
1297 break;
1298 }
1299 if ((object->state.writeDataMode == UART_DATA_TEXT) &&
1300 (*(writeOffset - object->writeCount) == '\n')) {
1301 MAP_UARTCharPut(hwAttrs->baseAddr, '\r');
1302 }
1303 object->writeCount--;
1304 }
1305
1306 if (!object->writeCount) {
1307 MAP_UARTIntDisable(hwAttrs->baseAddr, UART_INT_TX);
1308 MAP_UARTIntClear(hwAttrs->baseAddr, UART_INT_TX);
1309
1310 /*
1311 * Set TX interrupt for end of transmission mode.
1312 * The TXRIS bit will be set only when all the data
1313 * (including stop bits) have left the serializer.
1314 */
1315 MAP_UARTTxIntModeSet(hwAttrs->baseAddr, UART_TXINT_MODE_EOT);
1316
1317 if (!UARTBusy(hwAttrs->baseAddr)) {
1318 object->writeCallback(handle, (void *)object->writeBuf,
1319 object->writeSize);
1320 releasePowerConstraint(handle);
1321 }
1322 else {
1323 UARTIntEnable(hwAttrs->baseAddr, UART_INT_TX);
1324 }
1325
1326 DebugP_log2("UART:(%p) Write finished, %d bytes written",
1327 hwAttrs->baseAddr, object->writeSize - object->writeCount);
1328 }
1329 }
1330
1331 /*
1332 * ======== writeSemCallback ========
1333 * Simple callback to post a semaphore for the blocking mode.
1334 */
writeSemCallback(UART_Handle handle,void * buffer,size_t count)1335 static void writeSemCallback(UART_Handle handle, void *buffer, size_t count)
1336 {
1337 UARTCC32XX_Object *object = handle->object;
1338
1339 SemaphoreP_post(object->writeSem);
1340 }
1341