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-EXP430FR5994: Uart receive overrun error flag

Part Number: MSP-EXP430FR5994
Other Parts Discussed in Thread: BQ79616, BQ79600EVM,

I have the UART loopback example working at 1Mbps baud rate with no problems. I used a 4MHz SMCLK for the UART clock. These results are using an eternal clock on the MSP430 EVM.

When interfaced with the BQ79600EVM and the a custom BQ79616, the uart receive interrupt is firing soon after I try a single device read command. I can see the UCOE flag is set. Is there anything wrong in the setup/use of the UART driver?

I have setup a 100 bit delay for the BQ79600 chip to respond so the MSP430 has time to switch from uart transmit to uart receive. Is there an ideal number for the MSP430 for this to happen?

I am using the external clock in this setup. 

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#define BQUART EUSCI_A1_BASE
#define BQUART_DISABLE EUSCI_A_UART_disable
#define BQUART_CLOCKSOURCE EUSCI_A_UART_CLOCKSOURCE_SMCLK
#define BQUART_PARITY EUSCI_A_UART_NO_PARITY
#define BQUART_BITORDER EUSCI_A_UART_LSB_FIRST
#define BQUART_STOPBIT EUSCI_A_UART_ONE_STOP_BIT
#define BQUART_MODE EUSCI_A_UART_MODE
#define BQUART_OVERSAMPLING EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION
#define BQUART_INIT EUSCI_A_UART_init
#define BQUART_initParam EUSCI_A_UART_initParam
#define BQUART_enable EUSCI_A_UART_enable
#define BQUART_disable EUSCI_A_UART_disable
#define BQUART_REG P2OUT
#define BQUART_TX_PORT GPIO_PORT_P2
#define BQUART_RX_PORT GPIO_PORT_P2
#define BQUART_RX_PIN GPIO_PIN6
#define BQUART_TX_PIN GPIO_PIN5
#define BQUART_SELECT_FUNCTION GPIO_SECONDARY_MODULE_FUNCTION
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • 1) Using UCBUSY for receive is just flat out wrong. If a steady stream of data is being received then the time between when the receiver state machine finishes up (somewhere in the final stop bit) and the next start bit is short. Really short at  1Mbps.

    2) Reading the IV register will have reset RXIFG so no need to do that again in the ISR.

    3) Waking up the main task to handle the data is not going to work. The usual method is to put the data into a queue. The main task can then check to see if there is data in the queue.

    4) Even with a 16Mhz clock you don't have a lot of time to deal with each byte of data.

    5) It takes no time at all for the MSP430 to switch the UART from transmit to receive. In fact they work simultaneously. Which means you could get a receive interrupt before the transmit code is finished.

  • I looked at the loopback example and I see the only processing done in the receive ISR is assigning 

    EUSCI_A_UART_receiveData(EUSCI_A0_BASE).

    I eliminated other things I had in the ISR. 

    My setup is MSP-EXP430FR5994 -> BQ79600EVM -> custom BQ79616

    When reading from the BQ79600EVM, a read command is issued for the specific register.

    Then a ReadFrameReq is sent out. This involves a write message through the UART.

    Here is where you say that the receive can happen even before the transmit ends. Can you explain more about the transmit and receive working simultaneously? I see Figure 30-1 in SLAU367P on page 769.

    I don’t have RTOS in the firmware, there is a main loop. Here is what I tried to restructure the uart receive, I don’t have uartReceive anymore. This still does not work. I can use some more pointers.

    1. ReadReg
    2. ReadFrameReq
      1. Set idx, rxComplete = 0; assign uartRxLen
      2. Compile and transmit the write frame through UART.

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #pragma vector=BQUART_VECTOR
    /*******************************************************************************
    USCI_B1_ISR ******************************************************************
    *******************************************************************************
    * Function: B1 Interrupt Routine
    ********************************************************************************/
    __interrupt void BQUART_ISR(void)
    {
    switch(__even_in_range(BQUART_IV, USCI_UART_UCTXCPTIFG))
    {
    case USCI_NONE: break;
    case USCI_UART_UCRXIFG:
    RXData[idx] = EUSCI_A_UART_receiveData(BQUART);
    idx++;
    if (idx == uartRxLen)
    rxComplete = 1;
    break;
    case USCI_UART_UCTXIFG: break;
    case USCI_UART_UCSTTIFG: break;
    case USCI_UART_UCTXCPTIFG: break;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • The receiver and transmitter are independent. Sharing a bit rate generator and not much else. So if data arrives while the transmitter is sending something, the receiver is going to handle it.

    You say it doesn't work. How doesn't it work? Is there no data at all in the receive buffer? Data that looks wrong? Not enough data? All of these are clues to the problem. (Too much data would cause trouble and a likely buffer overrun.)

  • I have a breakpoint at the first step ReadReg. If I step into this, it goes straight into the UART ISR, overrun flag is set. Instead of stepping in, I put a breakpoint at WriteFrame and run the program until here. Then I put a breakpoint in the ISR and run the program until here. I find one byte is received (not the one expected), the idx increments and then the ISR does not continue triggering until the uartRxLen.

    Even if I wait to enable the receive interrupt until uartSend, somehow the UART ISR is firing. How can this be? If all of uartRxLen is received, I disable the receive interrupt.

  • Did you try using DMA to your UART receive and Transmit operation? 

    As David suggested, use queue to push data using DMA and check the queue once the DMA transfer is complete

**Attention** This is a public forum