This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP-EXP432E401Y : UART0 TX interrupt not being serviced

Other Parts Discussed in Thread: MSP-EXP432E401Y

Hello,

              I am developing Uart driver on MSP-EXP432E401Y Launchpad. I have made changes in the example code of Uartecho using freertos. Now I am able to service receive interrupt but my transmit interrupt doesn't get triggered. Below is the snippet I am working on. Please let me know if I am missing anything.

//*****************************************************************************
//
// The UART interrupt handler.
//
//*****************************************************************************
void UART0_IRQHandler(void)
{
uint32_t ui32Status = 0;
uint8_t ui8RxData = 0;

//
// Get the interrupt status.
//
ui32Status = MAP_UARTIntStatus(UART0_BASE, true);

if((ui32Status & UART_INT_RX || ui32Status & UART_INT_RT) && MAP_UARTCharsAvail(UART0_BASE))
{
//
// Clear the asserted interrupts.
//
MAP_UARTIntClear(UART0_BASE, UART_INT_RX);

//Read the data
ui8RxData = (unsigned char)MAP_UARTCharGetNonBlocking(UART0_BASE);

//global data structure to be added here
}
if(ui32Status & UART_INT_TX)
{
MAP_UARTIntClear(UART0_BASE, UART_INT_TX);
if(TxBuf.ui16NbCharToSend > 0)
{
MAP_UARTCharPutNonBlocking(UART0_BASE, TxBuf.ui8DatBuf[TxBuf.ui16NbCharToSend]);
TxBuf.ui16NbCharToSend--;
}
else
{
//MAX485 direction pin RX operation set
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, 0);
MAP_UARTIntDisable(UART0_BASE, UART_INT_TX);
}
}
}

void UART0_Init(uint32_t ui32baud)
{
UART_Handle uart;
UART_Params uartParams;

/* Call driver init functions */
UART_init();

/* Configure the LED pin as transceiver - PN1*/
GPIO_setConfig(Board_GPIO_LED0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);

/* 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 = ui32baud;

uart = UART_open(Board_UART0, &uartParams);

if (uart == NULL) {
/* UART_open() failed */
while (1);
}

IntRegister(INT_UART0, UART0_IRQHandler);
MAP_IntEnable(INT_UART0);
MAP_UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
}

//*****************************************************************************
//
// Send a string to the UART.
//
//*****************************************************************************
void UARTSend(const uint8_t *pui8Buffer, uint16_t ui16Count)
{
uint16_t ui16Cnt;

//Disable global interrupts
MAP_IntMasterDisable();

//MAX485 direction pin TX operation set
GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, 2);

for(ui16Cnt = 0;ui16Cnt < ui16Count; ui16Cnt++)
{
TxBuf.ui8DatBuf[ui16Cnt] = *pui8Buffer++;
}
TxBuf.ui16NbCharToSend = ui16Count;

//Enable Uart transmit interrupt
MAP_UARTIntEnable(UART0_BASE, UART_INT_TX);

//Enable processor interrupts
MAP_IntMasterEnable();
}

  • Hello Zoheb,

    When using the TI Drivers, you must not enable the Interrupts outside the scope of the drivers. Rather you must use callback functions provided by the handler
  • Will have to remove TI drivers I believe. Can you provide me with uart source files which do not use TI drivers?

    Thank you.

  • Hello Zoheb,

    If you are using RTOS (FreeRTOS or TI-RTOS) in the SDK then you must use TI Drivers. We do not support mixing driverlib and TI Drivers call as it causes the scheduler and interrupt functions to go out of sync.

    To be able to get an interrupt for writing, you need to have the uart parameter for writeCallback set. And then call UART_write to send the data. When the data is sent the callback function is called.
  • The logic for your code doesn't make sense to me.

    For tx interrupts, I often use a pointer, and load the tx buffer and enable the isr. In the tx isr, test if the end of the string has been reached.

    If yes, disable the tx interrupt.
    Otherwise, load the next char and advance the pointer.

    It becomes a little bit more complicated on so e chips where the flag is only set if the buffer is depleted sufficiently.

    I can post a piece of my code if you want. It's implementation varies but the logic is the same.
  • Ok, Got it.

    Thank you.

  • Well, I have used a TX global structure which is specifically used for transmission. In the Tx isr, I check for length of the frame (TxBuf.ui16NbCharToSend) which is being transmitted. Once the last byte has been sent, I also disable teh TX interrupt and go in receive mode.
    Please do share your code as I am in the implementation phase and it would help me to compare designs.
    Thank you
  • here is what I do: github.com/.../MSP432

    the relevant files are uartnisr.h/.c, n=0..3

    the logic follows what I laid out earlier. the routine uartn_puts(), n=0..3, sends a null-terminated string via the TX isr.

    you can find similar files / approaches in other folders for other mcus but the logic is the same.

**Attention** This is a public forum