Part Number: AM5726
Other Parts Discussed in Thread: SYSBIOS
Hello,
I have a task running on IPU, among others, who is responsible to communicate with Input/Output modules through UART driver:
a few subsequent Read/Write requests are sent every 125 ms by the program and are answered by the IO modules.
For an unknown reason and after some time, in which the system is working fine, a call to UART_write never returns (seen from the logs).
Thanks to our debugging sessions, we could also see that the UART ISR (function ti-pdk/packages/ti/drv/uart/src/v1/UART_v1.c:UART_v1_hwiIntFxn) is actually in a never-ending call sequence, i.e.,it is called again and again with the same arguments (e.g., intType = 0, object->txDataSent = 0), I brought the ISR code below:
static void UART_v1_hwiIntFxn(uintptr_t arg)
{
UART_Handle handle = (UART_Handle)arg;
UART_V1_Object *object = (UART_V1_Object*)handle->object;
UART_HwAttrs const *hwAttrs = (UART_HwAttrs*)handle->hwAttrs;
uint32_t intType;
while (TRUE)
{
intType = UARTIntIdentityGet(hwAttrs->baseAddr);
if ((intType & UART_INTID_RX_THRES_REACH) == UART_INTID_RX_THRES_REACH)
{
if ((intType & UART_INTID_RX_LINE_STAT_ERROR) ==
UART_INTID_RX_LINE_STAT_ERROR)
{
/* RX line status error */
UART_procLineStatusErr(handle);
}
else
{
if ((intType & UART_INTID_CHAR_TIMEOUT) == UART_INTID_CHAR_TIMEOUT)
{
/* rx timeout, log the rx timeout errors */
object->rxTimeoutCnt++;
}
/* RX FIFO threshold reached */
if (object->readSize)
{
object->readSize = UART_v1_readData(handle, object->readSize);
if ((object->readSize) == 0U)
{
UARTIntDisable(hwAttrs->baseAddr, UART_INT_RHR_CTI | UART_INT_LINE_STAT);
/* Reset the read buffer so we can pass it back */
object->readBuf = (uint8_t *)object->readBuf - object->readCount;
if (object->readTrans != NULL)
{
object->readTrans->count = object->readCount;
object->readTrans->status = UART_TRANSFER_STATUS_SUCCESS;
}
/* Call back to application if in callback mode */
UART_v1_callback(handle, true);
object->readTrans = NULL;
}
}
}
}
else if ((intType & UART_INTID_TX_THRES_REACH) == UART_INTID_TX_THRES_REACH)
{
/* TX FIFO threshold reached */
if (object->writeSize)
{
object->writeSize = UART_writeData_v1(handle, object->writeSize);
if ((object->writeSize) == 0U)
{
UARTIntDisable(hwAttrs->baseAddr, UART_INT_THR);
/* Reset the write buffer so we can pass it back */
object->writeBuf = (uint8_t *)object->writeBuf - object->writeCount;
if (object->writeTrans != NULL)
{
object->writeTrans->count = object->writeCount;
object->writeTrans->status = UART_TRANSFER_STATUS_SUCCESS;
}
object->txDataSent = TRUE;
UARTInt2Enable(hwAttrs->baseAddr, UART_INT2_TX_EMPTY);
}
}
}
else
{
break;
}
}
if (object->txDataSent == TRUE)
{
intType = UARTInt2StatusGet(hwAttrs->baseAddr);
if (intType & UART_INT2_TX_EMPTY)
{
UARTInt2Disable(hwAttrs->baseAddr, UART_INT2_TX_EMPTY);
/* Call back to application if in callback mode */
UART_v1_callback(handle, false);
object->writeTrans = NULL;
object->txDataSent = FALSE;
}
}
}
The UART initialization code:
UART_Params_init(¶ms);
params.baudRate = DUART_BAUD_RATE; // -> 115200
params.readEcho = UART_ECHO_OFF;
params.readDataMode = UART_DATA_BINARY;
params.writeDataMode = UART_DATA_BINARY;
params.writeMode = UART_MODE_BLOCKING;
params.writeTimeout = DUART_WRITE_TIMEOUT; // -> 100
params.readMode = UART_MODE_BLOCKING;
params.readTimeout = DUART_READ_TIMEOUT; // -> 100
params.readReturnMode = UART_RETURN_FULL;
UART_socGetInitCfg(UART_INSTANCE, &uart_hwAttrs);
uart_hwAttrs.baseAddr = SOC_UART5_BASE + IPC_REGISTER_OFFSET;
uart_hwAttrs.intNum = 48; /* use interrupt #48 */
uart_hwAttrs.txTrigLvl=UART_TXTRIGLVL_8; /* TX FIFO trigger at lowest level */
UART_socSetInitCfg(UART_INSTANCE, &uart_hwAttrs);
/* configure the irq corssbar to route the irq from uart5 to ipu1-core1-irq48 */
DIRQ_voCustomCSL_xbarIpuIrqConfigure(1, CSL_XBAR_INST_IPU1_IRQ_48, CSL_XBAR_UART5_IRQ);
UART_init();
uart_handle = UART_open(UART_INSTANCE, ¶ms);
We already had issues working with the UART_CALLBACK_MODE for write so we opted for the BLOCKING_MODE (pls see the thread below):
Thanks to our logs we could see that everything goes well (no uart_error, no timeout, all the bytes were written successfully) until the very last call to the UART_Write which never returns.
The main question here is, in which circumstances and why, a call to UART_Write with a given timeout, never returns?
Let me know if you need more info.
Thanks,
Reza