I observed this latest SensorTag app/RTOS/BLE Stack (TI-RTOS 2.13.0.06 and BLE-Stack 2.1).
Also observed with prior versions. Using latest CCS 6.1.0.00104
Using CC2650 SensorTag with Debug DevPack
My first step was to import the existing uartecho app, and I verified that it worked perfectly
( ... after changed outlined in https://e2e.ti.com/support/wireless_connectivity/f/538/p/441616/1591077#1591077 )
Echo worked perfectly. I took the exact same code, and integrated a new task (task_UART) into the unmodified, working SensorTag application.
Compiles, and runs properly. But when my task_UART starts to execute, it has the following code:
static void uartTaskFxn(UArg a0, UArg a1) { char input; UART_Handle uart; UART_Params uartParams; const char echoPrompt[] = "\fEchoing characters:\r\n"; /* Create a UART with data processing off. */ UART_Params_init(&uartParams); uartParams.writeDataMode = UART_DATA_BINARY; uartParams.readDataMode = UART_DATA_BINARY; uartParams.readReturnMode = UART_RETURN_FULL; uartParams.readEcho = UART_ECHO_OFF; uartParams.baudRate = 9600; uart = UART_open(CC2650_UART0, &uartParams); if (uart == NULL) { //System_abort("Error opening the UART"); } UART_write(uart, echoPrompt, sizeof(echoPrompt)); /* Task Loop forever echoing */ while (1) { UART_read(uart, &input, 1); UART_write(uart, &input, 1); // Put out a second time, so easy to verify on scope UART_write(uart, &input, 1); } }
On my PC UART terminal, I see the text string "Echoing characters" come out as expected.
But in UARTCC26XX_write, it waits upon a semaphore after the TX FIFO has been emptied.
see 1st statement: if (!Semaphore_pend(Semaphore_handle(&(object->writeSem)), object->writeTimeout))
The semaphore never gets posted, and my UART_task is suspended at this point. See UARTCC26XX_write below,
int UARTCC26XX_write(UART_Handle handle, const void *buffer, size_t size) { unsigned int key; UARTCC26XX_Object *object; UARTCC26XX_HWAttrs const *hwAttrs; /* Get the pointer to the object */ object = handle->object; hwAttrs = handle->hwAttrs; /* Check that there is data to write */ Assert_isTrue(size != 0, NULL); /* Disable preemption while checking if the UART is in use. */ key = Hwi_disable(); if (object->writeSize) { Hwi_restore(key); Log_warning1("UART:(%p) Could not write data, uart in use.", ((UARTCC26XX_HWAttrs const *)(handle->hwAttrs))->baseAddr); return (UART_ERROR); } /* Stop the txFifoEmpty clock in case it was running due to a previous write operation */ Clock_stop((Clock_Handle) &(object->txFifoEmptyClk)); /* Update the status of the UART module */ object->status = UART_OK; /* Save the data to be written and restore interrupts. */ object->writeBuf = buffer; object->writeCount = 0; Hwi_restore(key); /* Set constraints to guarantee transaction */ threadSafeStdbyDisSet(); /* Enable TX */ HWREG(UART0_BASE + UART_O_CTL) |= UART_CTL_TXE; uint32_t writtenLast = size; /* Fill up TX FIFO */ if (!(object->writeSize = writeData(handle, size))) { /* No more data to transmit - Write is finished but all bytes * may not have been shifted out. */ startTxFifoEmptyClk((UART_Handle)handle, writtenLast); /* If writeMode is blocking, block and get the status. */ if (object->writeMode == UART_MODE_BLOCKING) { /* Pend on semaphore and wait for Hwi to finish. */ if (!Semaphore_pend(Semaphore_handle(&(object->writeSem)), object->writeTimeout)) { /* Reset writeSize */ object->writeSize = 0; /* Set status to TIMED_OUT */ object->status = UART_TIMED_OUT; /* Workaround for flushing the TX FIFO */ writeTxFifoFlush(object, hwAttrs); /* Release constraint */ threadSafeStdbyDisRelease(); Log_print2(Diags_USER1, "UART:(%p) Write timed out, %d bytes written", ((UARTCC26XX_HWAttrs const *)(handle->hwAttrs))->baseAddr, object->writeCount); /* Return UART_ERROR to indicate something went wrong, object->status set to UART_TIMED_OUT*/ return UART_ERROR; } return (object->writeCount); } } else { /* Enable TX interrupts */ UARTIntEnable(hwAttrs->baseAddr, UART_INT_TX); /* If writeMode is blocking, block and get the status. */ if (object->writeMode == UART_MODE_BLOCKING) { /* Pend on semaphore and wait for Hwi to finish. */ if (!Semaphore_pend(Semaphore_handle(&(object->writeSem)), object->writeTimeout)) { /* Semaphore timed out, make the write empty and log the write. */ /* Starting a timer to enable the posting of semaphore used in writeTxFifoFlush. * writtenLast in this case is equal to full TX FIFO. This is a conservative number as * some of the data might have been sent. */ startTxFifoEmptyClk((UART_Handle)handle, writtenLast); /* Reset writeSize */ object->writeSize = 0; /* Set status to TIMED_OUT */ object->status = UART_TIMED_OUT; /* Workaround for flushing the TX FIFO */ writeTxFifoFlush(object, hwAttrs); /* Release constraint */ threadSafeStdbyDisRelease(); Log_print2(Diags_USER1, "UART:(%p) Write timed out, %d bytes written", ((UARTCC26XX_HWAttrs const *)(handle->hwAttrs))->baseAddr, object->writeCount); /* Return UART_ERROR to indicate something went wrong (object->status set to UART_TIMED_OUT)*/ return UART_ERROR; } /* Return the numbers of samples written */ return (object->writeCount); } } /* This return will only be active in UART_MODE_CALLBACK mode. */ return (0); }
On an oscilloscope, I can see characters being received by the CC2650, and as mentioned, the CC2650 has successfully transmitted the "Echoing characters" string.
Other notes.
- In project properties Build->ARM Compiler->Advanced Options->Predefined Symbols, I added TI_DRIVERS_UART_INCLUDED ... but not sure if it is needed
- In project, I had to manually add the UART drivers alongside the existing I2C/PIN/SPI/UDMA drivers.
- Note that the original uartecho app does not run with a BLE Stack. Possibly this is a difference that may be of interest
- I have some suspicion it has something to do with ROM libraries. On my app, I don't think ROM libraries are involved, because I can single-step through the UARTCC26XX.code.
- On uartecho, I can' t step through the UART code because I believe it is using some ROM libraries.