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.

MSP430FR5994: Send UART data using interrupt with DriverLib

Part Number: MSP430FR5994

Hello,

I working with the MSP430FR5994 for a while.

I know how to receive data using an interrupt and usually used the main loop in order to send UART data using the 'EUSCI_A_UART_transmitData' function.

Now, in order to improve performance we want to test sending data using the UART Tx interrupt.

May you have an example of that?

At the DriverLib examples, I saw example to receive via interrupt but not to send.

Thanks.

  • Yeah, usually you have to roll your own. Here is a brain-dead one I wrote that can be improved by adding a circular buffer:

    /*
     * Program to control two pass transistors, one to charge the caps and one to dump it.
     *
     * Ports used:
     * Port J: Pins 2 &3 - Crystal
     * Port 1: Pin 0: Red LED
     * Port 1: Pins 2&3 Back Channel UART
     * Port4: Pin 0 Control to Charge Caps
     * Port 3: Pin 0 : Control to Dump Caps
     *
     *
     */
    /* DriverLib Includes */
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
    
    /* Standard Includes */
    #include <stdint.h>
    #include <stdbool.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    void executeCommand(char *cmd);
    int getData(char *cmd, char *name);
    void waitForSerial(void);
    void Delay(int msec);
    
    /* UART Configuration Parameter. These are the configuration parameters to
     * make the eUSCI A UART module to operate with a 115200 baud rate. These
     * values were calculated using the online calculator that TI provides
     * at:
     * http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP430BaudRateConverter/index.html
     */
    const eUSCI_UART_ConfigV1 uartConfig =
    {
     EUSCI_A_UART_CLOCKSOURCE_SMCLK,          // SMCLK Clock Source
     156,                                      // BRDIV =
     4,                                       // UCxBRF =
     0,                                      // UCxBRS =
     EUSCI_A_UART_NO_PARITY,                  // No Parity
     EUSCI_A_UART_LSB_FIRST,                  // LSB First
     EUSCI_A_UART_ONE_STOP_BIT,               // One stop bit
     EUSCI_A_UART_MODE,                       // UART mode
     EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION  // Oversampling
    };
    
    /* Other Rates
     *  9600
     *  BRDIV: 156
     *  UCXBRF: 4
     *  UCXBRS: 0
     *  Oversample: 1
     *
     *  38400
     *  BRDIV: 39
     *  UCXBRF: 1
     *  UCXBRS: 0
     *  Oversample: 1
     *
     *  115200
     *  BRDIV: 13
     *  UCXBRF: 1
     *  UCXBRS: 37
     *  Oversample: 1
     *
     */
    
    char TXData[256];
    volatile int TXIdx = -1; // No transmission
    
    
    uint8_t RXData;
    uint8_t RXIdx = 0;
    char RXLine[64];
    
    // Systick timer
    volatile unsigned int Tick;
    
    int main(void)
    {
        int index;
    
        /* Halting the Watchdog */
        MAP_WDT_A_holdTimer();
    
        //![Simple CS Config]
        /* Configuring pins for peripheral/crystal usage and LED for output */
        MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ,
                                                        GPIO_PIN3 | GPIO_PIN2, GPIO_PRIMARY_MODULE_FUNCTION);
    
        MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
                                                       GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION); // UART
    
        MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0); // Main Red LED
        MAP_GPIO_setAsOutputPin(GPIO_PORT_P3, GPIO_PIN0); // Dump
        MAP_GPIO_setAsOutputPin(GPIO_PORT_P4, GPIO_PIN0); // Capacitor Charging
    
        MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0); // Follows the gate drive
        MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P3, GPIO_PIN0);
        MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P4, GPIO_PIN0);
    
        /* Just in case the user wants to use the getACLK, getMCLK, etc. functions,
         * let's set the clock frequency in the code. 
         */
        CS_setExternalClockSourceFrequency(32000,48000000);
    
        /* Starting HFXT in non-bypass mode without a timeout. Before we start
         * we have to change VCORE to 1 to support the 48MHz frequency */
        MAP_PCM_setCoreVoltageLevel(PCM_VCORE1);
        MAP_FlashCtl_setWaitState(FLASH_BANK0, 1);
        MAP_FlashCtl_setWaitState(FLASH_BANK1, 1);
        CS_startHFXT(false);
    
        /* Initializing MCLK to HFXT (effectively 48MHz) */
        MAP_CS_initClockSignal(CS_MCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
        // The UART is limited to 24 MHz...
        MAP_CS_initClockSignal(CS_SMCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_2);
    
        // Configure SysTick
        MAP_SysTick_enableModule();
        // 48M = 1 sec, 4.8M = 100ms, 480000 = 10ms...
        MAP_SysTick_setPeriod(48000); // Every 1 msec
        MAP_SysTick_enableInterrupt();
    
        /* Configuring UART Module */
        MAP_UART_initModule(EUSCI_A0_BASE, &uartConfig);
    
        /* Enable UART module */
        MAP_UART_enableModule(EUSCI_A0_BASE);
    
        /* Enabling interrupts */
        MAP_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT|EUSCI_A_UART_TRANSMIT_INTERRUPT);
    
        /* Enabling interrupts */
        MAP_Interrupt_enableInterrupt(INT_EUSCIA0);
    
        /* Enabling MASTER interrupts */
        MAP_Interrupt_enableMaster();
    
        //debug
        strcpy(TXData, "Hello, World!\n\r");
        TXIdx = 0;
    
        while (1)
        {
            
    
            if (RXData != 0) {
                if ((RXData == '\r') || (RXData == '\n')) {
                    RXLine[RXIdx] = '\0';
    
                    RXData = 0;
    
                    executeCommand(RXLine);
    
                    RXIdx = 0;
                    MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
    
                } else {
    
                    RXLine[RXIdx++] = RXData;
    
                    waitForSerial();
                    TXData[0] = RXData;
                    TXData[1] = '\0';
    
                    TXIdx = 0;
                    RXData = 0;
    
                }
    
            }
            
            if (TXIdx == 0)
            {
                // Start the transmission
                MAP_UART_transmitData(EUSCI_A0_BASE, TXData[TXIdx++]);
            }
    
        } // while()
    }
    
    
    
    /* EUSCI A0 UART ISR */
    void EUSCIA0_IRQHandler(void)
    {
        uint32_t status = MAP_UART_getEnabledInterruptStatus(EUSCI_A0_BASE);
    
        MAP_UART_clearInterruptFlag(EUSCI_A0_BASE, status);
    
        if(status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG)
        {
            RXData = MAP_UART_receiveData(EUSCI_A0_BASE);
    
    
        } else if (status & EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG) {
            // Ready to transmit the next byte
            if (TXIdx == -1) return;
    
            if (TXData[TXIdx] == '\0')
            {
                // Done transmitting
                TXIdx = -1;
    
            } else {
                MAP_UART_transmitData(EUSCI_A0_BASE, TXData[TXIdx++]);
    
            }
        }
    
    }
    
    
    void waitForSerial(void)
    {
        // Wait for TXIdx to go to -1...
        while (TXIdx != -1);
    
    }
    
    void SysTick_Handler(void)
    {
        Tick++;
    }
    
    void Delay(int msec) {
        // Busy wait msec ms
        int starttime = Tick;
    
        while((Tick - starttime) < msec);
    }

  • Hi Ron,

    Sorry for the late response, and actually the code examples use RX interrupt for application.

    You can try to enable the TX interrupt and then try to use the interrupt for transimit. UCTXIFG is set when new data can be written into UCAxTXBUF.

        UCA3IE |= UCRXIE;                       // Enable USCI_A3 RX interrupt

    ->UCA3IE |= UCRXIE | UCTXIE;       // Enable USCI_A3 RX & TX interrupt

    Welcome reply to threads if you meet any questions when using TX interrupt.

    B.R.

    Sal

**Attention** This is a public forum