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.

MSP432E401Y: UART interrupts not firing

Part Number: MSP432E401Y
Other Parts Discussed in Thread: MSP-EXP432E401Y

Hi,

I'm developing on an MSP-EXP432E401Y dev board, for the MSP432E401.  I'm trying to get a simple UART working, but I can't seem to get the ISR to fire.  I've run the uart_echo demo from the SimpleLink SDK, and that works as expected, but my code doesn't.  The project is based on the empty example in the SDK, and I've compared the starting files in my project with the ones in uart_echo, and the important stuff is the same.  If I copy the uart_echo.c file into my project, and adjust it to run on UART5 (and exclude my own main.c), the demo code works as expected - the ISR is firing to echo the received characters back as expected. 

I'm using DriverLib, SimpleLink v4.20.00.12.  My code looks like this:

#include <stdint.h>
#include <stdbool.h>

#include "ti/devices/msp432e4/driverlib/driverlib.h"

#define UART_BUF_SIZE 32
volatile unsigned char uartBuf[UART_BUF_SIZE] = "System Test\n";
volatile unsigned char uartHead = 12, uartTail = 0, uartCount = 12;

void UART5_IRQHandler(void)
{
    uint32_t ui32Status = UARTIntStatus(UART5_BASE, true);
    UARTIntClear(UART5_BASE, ui32Status);

    if ((ui32Status & UART_INT_TX) && uartCount)
    {
        UARTCharPutNonBlocking(UART5_BASE, uartBuf[uartTail]);
        uartTail = (uartTail + 1) % UART_BUF_SIZE;
        uartCount--;
    }
}

int main(void)
{
    uint32_t SysClock;

    // running from PLL at 120 MHz
    SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);

    // enable main interrupts
    IntMasterEnable();

    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART5);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);

    GPIOPinConfigure(GPIO_PC6_U5RX);
    GPIOPinConfigure(GPIO_PC7_U5TX);
    GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_6 | GPIO_PIN_7);

    UARTConfigSetExpClk(UART5_BASE, SysClock, 115200,
                          (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                           UART_CONFIG_PAR_NONE));

    IntEnable(INT_UART5);
    UARTIntEnable(UART5_BASE, UART_INT_RX | UART_INT_RT | UART_INT_TX);

    // start TX
    uartTail = 1;
    uartCount--;
    UARTCharPutNonBlocking(UART5_BASE, uartBuf[0]);

    while (1)
    {
    
    }
}

With a terminal attached to PC5 and PC7, I can see the first character, but no more.  Debugging, the UART5 ISR is never hit - it seems like the TX interrupt never fires.  I've followed the example, and the documentation, and I'm not sure what I'm missing here - can anyone suggest the really obvious thing I'm doing wrong, please?

  • Hi,

    Your code looks similar to the uart_echo code. Have you tried using UART0 in your code instead of UART5?

    Best regards,

    Cash Hao

  • So, looking at this with fresh eyes this morning, I've found the problem.  The issue is the DriverLib code unexpectedly enabling the FIFOs as a side effect.

    The chain is like this:

    1. The call to UARTConfigSetExpClk disables the UART, does the configuration, then re-enables the UART.  Disabling and Enabling is done via calls to UARTDisable and UARTEnable
    2. UARTEnable also enables the FIFO, regardless of whether it was enabled previously, etc.
    3. As the FIFO has not been set up, it defaults to 1/2 full, or 8 bytes each way
    4. This means the enabled interrupts won't ever fire, as the code is expecting a single byte hardware buffer

    The underlying problem is that UARTEnable also enables the FIFO.  I would suggest that this behaviour is a bug (despite being listed in the API documentation, now that I know what to look for), as it introduces unwanted side-effects.  If the user wants to use the FIFOs, they should explicitly enable them, rather than the general peripheral enable assuming you're always going to want them (requiring extra calls to UARTDisableFIFO by the user to clean up state).

    This also isn't helped by the sample code conveniently working around the problem by never using the TX IRQ and relying on the RT rather than the RX IRQ for receiving bytes.  Actually, it has an undocumented side effect that the way the start-up message is transmitted RELIES on the TX FIFO being enabled, otherwise you'll lose bytes (and never know).  There's also a race condition if you try to use the UARTSend function as written to send more than a FIFO's worth of data before the UART can clock it out (the CPU runs quite a lot faster than the UART); this is acceptable as a side effect of a simple functional demo, but the documentation should make it clear what's going on, otherwise you're just leaving traps for the unwary.

    To answer the question below, this error crops up regardless of which UART you use, if you use the DriverLib.