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.

MSP430FR5969: Issues with UART

Part Number: MSP430FR5969

I am using the MSP430FR5969 on my board. My UART configuration is :

// Setting for 16 MHz clock (230400)
EUSCI_A_UART_initParam param = {0};
param.selectClockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK;
param.clockPrescalar = 4;
param.firstModReg = 5;
param.secondModReg = 0x55;
param.parity = EUSCI_A_UART_NO_PARITY;
param.msborLsbFirst = EUSCI_A_UART_LSB_FIRST;
param.numberofStopBits = EUSCI_A_UART_ONE_STOP_BIT;
param.uartMode = EUSCI_A_UART_MODE;
param.overSampling = EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;
if (STATUS_FAIL == EUSCI_A_UART_init(EUSCI_A0_BASE, &param))
        return;
EUSCI_A_UART_enable(EUSCI_A0_BASE);
EUSCI_A_UART_clearInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);
// Enable USCI_A0 RX interrupt
EUSCI_A_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);        // Enable interrupt

I have unknow packet size on the UART RX hence I start out by using UART in interrupt mode for receiving the first byte and then disabling the interrupt till all the bytes have been received. I cannot discuss the framing technique I am using but assume it works. 

Once the complete packet is received I enable the UART interrupt again. For polling the UART data I am using 

inline char UART_getChar (void)
{
    while (!(UCA0IFG&UCRXIFG));     // RX buffer got data ?
    return UCA0RXBUF;
}

The MSP gets the packet every 1 sec. The issue I am having is that randomly (could be 10 packets or 2000+ packets later) the code gets stuck and spins on the while loop  "while (!(UCA0IFG&UCRXIFG));     // RX buffer got data ? ". I know for a fact that the board is receiving a packet every second continuously. I checked the  UCA0IFG and it is stuck at 0. Can you please help with this issue? Is there something with the code or is this an issue with the microprocessor ? I cannot share my full code. TIA

  • RXIFG will always be set when RXBUF has data available. So its not being set demonstrates that no data was received.

    A blocking receive like that is not very robust and will leave your program stuck in the event of an error. Inclusion of some sort of timeout mechanism is highly recommended.

    It is possible that the ISR is fielding (and clearing) the RXIFG interrupt so that your spin loop never sees it. Depending on the code you refuse to show. The problem is almost certainly with your code.

  • Hi Atma,

    You might also consider checking how you are enabling and disabling your interrupts. We have code on UART that could help you on our TI resource explorer. Here is a UART example, there are 3 other examples found in the left hand table of contents as well.

  • My ISR

    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=USCI_A0_VECTOR
    __interrupt
    #elif defined(__GNUC__)
    __attribute__((interrupt(USCI_A0_VECTOR)))
    #endif
    void USCI_A0_ISR(void)
    {
      switch(__even_in_range(UCA0IV,USCI_UART_UCTXCPTIFG))
      {
        case USCI_NONE: break;
        case USCI_UART_UCRXIFG:
            startFlag = UCA0RXBUF; // Global variable
            readBytes();
    
          break;
        case USCI_UART_UCTXIFG: break;
        case USCI_UART_UCSTTIFG: break;
        case USCI_UART_UCTXCPTIFG: break;
      }
    }

    Here is my readBytes function :

    inline char UART_getChar (void)
    {
        while (!(UCA0IFG & UCRXIFG));     // RX buffer got data ?
        return UCA0RXBUF;
    }
    
    
    void readBytes(void){
    
        int i;
    
        EUSCI_A_UART_disableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);        // Disable interrupt
        if (startFlag == <startFrame Char>)
        {
            for (i = 0; i <16; i++)
            {
                packet[i] = UART_getChar();
            }
            UART_getChar(); // ignore end of frame char
    
            // Do something here
            
            EUSCI_A_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);        // Enable interrupt
            
        }
        else // Not startFrame char
            EUSCI_A_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);        // Enable interrupt
    }

    I am not sure how the ISR can clear the RXIFG if the UART interrupt is disabled. Since the packet is being sent (verified) every 1 second at some point it should see the UCA0IFG change. 

    The reason for not going for a pure ISR or DMA based (1 byte per DMA interrupt) UART is that I see random dropped bytes. As for timeout I tried that as well and it seems it looses packets - I cannot afford to loose any packet. Any ideas?

  • Yikes.

    Disabling the receive interrupt doesn't really do anything here. You call readBytes() from within the ISR. GIE is cleared by hardware when responding to any interrupt so no interrupts can happen until you set GIE or return from the ISR.

    Receiving the rest of the bytes from inside the ISR is really bad practice as nothing else can happen while that process completes.

    Exactly what is the program state when the loop hangs waiting for RXIFG? Is there data in the buffer? Is it error free?

  • When the code hangs - The data in UCA0RXBUF is 0x0005CC (I am not transmitting 0xCC char) and UCA0IFG is 0x0005DC. Other registers are:

    UCA0IE = 0x0005DA

    UCA0IV = 0x0005DE

    UCA0STATW = 0x0005CA

    UCA0CTLW1 = 0x0005C2

    UCA0CTLW1 = 0x0005C0

    UCA0BRW = 0x0005C6

    UCA0MCTLW = 0x0005C8

    Maybe this sheds some light

  • Hi Atma, let me take a closer look at this and get back to you.

  • You do need to clear the interrupt in your ISR. Can you try disabling and enabling interrupts in your main loop?

**Attention** This is a public forum