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.

MSP432P401R: MSP432 Transmit Not Working after Hooking up to UART Slave

Part Number: MSP432P401R

Hello All,

This is a follow-up to my previous question where I had left in the "MAP_Interrupt_enableSleepOnIsrExit();" line which caused me to go to sleep after the first interrupt. I am currently experiencing an odd issue when hooking up my MSP432 launchpad to its UART slave. The attached image illustrates the hardware setup.

Previously, I have tested Tx and Rx independently on both devices with Tx and Rx shorted together on each device. The single wire Tx and Rx solution is something that is required for the project. After hooking up the boards together as shown in the figure attached, I no longer transmit from the MSP432. Strangely, after the removal of the Arduino from the equation and maintaining the short from Tx and Rx on the MSP432, it appears to no longer function either even though it was previously tested. I am not sure whether something was damaged by hooking the boards up this way, however, the receive functionality works flawlessly on the MSP432. The transmit and receive functionality also works as expected on the Arduino. Please see my code below:

/******************************************************************************
 * MSP432 UART - Arduino with 12MHz BRCLK
 *
 * Description: This program communicates with the Talos's Arduino platform.
 * SMCLK/DCO is used as a clock source and the device is put in LPM0
 * The auto-clock enable feature is used by the eUSCI and SMCLK is turned off
 * when the UART is idle and turned on when a receive edge is detected.
 * Note that level shifter hardware is needed to shift between RS232 and MSP
 * voltage levels.
 *
 *               MSP432P401
 *             -----------------
 *            |                 |
 *            |                 |
 *            |                 |
 *       RST -|     P1.3/UCA0TXD|----> Arduino Rx
 *            |                 |
 *            |                 |
 *            |     P1.2/UCA0RXD|<---- Arduino Tx
 *            |                 |
 *
 *******************************************************************************/
/* DriverLib Includes */
#include <driverlib.h>

/* Standard Includes */
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>

/*
 * Functions that control what happens when bytes are transmitted and received
 */
void receiveOperation();
void transmitOperation(char* txData);

/*
 * Functions needed for the receive function
 */
volatile char receiveBuffer[100];
volatile i = 0;

//![Simple UART Config]
/* UART Configuration Parameter. These are the configuration parameters to
 * make the eUSCI A UART module to operate with a 9600 baud rate. These
 * values were calculated using the online calculator that TI provides
 * at:
 *software-dl.ti.com/.../index.html
 */
const eUSCI_UART_Config uartConfig =
{
        EUSCI_A_UART_CLOCKSOURCE_SMCLK,          // SMCLK Clock Source
        78,                                     // BRDIV = 78
        2,                                       // UCxBRF = 2
        0,                                       // UCxBRS = 0
        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
};
//![Simple UART Config]

int main(void)
                                                                                                                                                                                                                                                                                                                                         {
    /* Halting WDT  */
    MAP_WDT_A_holdTimer();

    /* Selecting P1.2 and P1.3 in UART mode */
    MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
            GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);

    /* Setting DCO to 12MHz */
    CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_12);

    //![Simple UART Example]
    /* 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);
    //MAP_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_TRANSMIT_INTERRUPT);
    MAP_Interrupt_enableInterrupt(INT_EUSCIA0);
    //MAP_Interrupt_enableSleepOnIsrExit();
    MAP_Interrupt_enableMaster();
    //![Simple UART Example]

    /*
     * 174 150 45 174 100 30 174 150 35 221
     * [START_BYTE] [ENABLE/DISABLE] [PIN SELECTION] [START_BYTE] [ENABLE/DISABLE] [PIN SELECTION] [START_BYTE] [ENABLE/DISABLE] [PIN SELECTION] [TERMINATION]
    */
    char* txData = "17410035221"; // Data to send to Arduino to enable specific pins

    transmitOperation(txData); // Transmit txData to Arduino PCB
    while(1)
    {
        MAP_PCM_gotoLPM0();
    }
}

/* EUSCI A0 UART ISR - Echoes data back to PC host */
void EUSCIA0_IRQHandler(void)
{
    uint32_t status = MAP_UART_getEnabledInterruptStatus(EUSCI_A0_BASE); // Get interrupt value of Emulated Serial A0 Base Address

    MAP_UART_clearInterruptFlag(EUSCI_A0_BASE, status);

    if(status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG) // Check to see if interrupt variable triggered and if receive flag was thrown
    {
        receiveBuffer[i] = MAP_UART_receiveData(EUSCI_A0_BASE); // Check for data in the UART Rx Register
        if((receiveBuffer[i]=='1') && (receiveBuffer[i-1]=='2') && (receiveBuffer[i-2]=='2')) // Check to see if the last values are the terminating byte
        {
           receiveOperation(); // Print Acknowledgments
           i = 0; // Reset increment i
        }
        else // Otherwise
        {
          i++; // Increment i
        }
    }
}

/*
 * Receive Operation. Checks acknowledgments by comparing the send data to the receive acknowledgment
 */
void receiveOperation()
{
    char* string= ""; // Create a character string

    string = receiveBuffer; // Set that equal to the receive buffer of UART

    if(string[0] == '3' && string[1] == '0' && string[2] == '0') // Check for acknowledgment
    {
        printf("Acknowledgment Received: %s \n",string); // Print the Acknowledgment
    }
}

/*
 * Transmit the data stored in the txData character array
 */
void transmitOperation(char* txData)
{
    int j = 0; // Create a new increment variable

    while(txData[j]) // While j does not reach the end of txData
    {
        MAP_UART_transmitData(EUSCI_A0_BASE, txData[j]); // Transmit a byte of data from txData
        j++; // Increment a pointer within txData
    }
}

I believe it may have to do with how I am handling the transmitOperation() function. Perhaps I need to place it inside of an interrupt service routine? It seems strange that when by itself and not having been previously connected up to the Arduino, the UART works flawlessly in that it receives the transmitted message sent via the transmitOperation() function. Just to reiterate, I have tested this system without the Arduino turned on and when the Arduino is completely disconnected and it no longer transmits. Before hooking it up to the Arduino, it functions as expected in that (when Rx and Tx are shorted), the system transmits data as required. Your assistance with this weird transmission issue is appreciated!

Thank you for your time!

  • I would also like to add that the Arduino uses a 9600 baud setup and only listens for a message from the MSP432. Once it receives the message in "txData", it will send an acknowledgment. I do not believe the Arduino is blocking anything.

  • As far as I know, the MSP432 eUSCI has no built-in support for a half-duplex (single wire) configuration like this, so you have to explicitly "give" and "take away" the Tx/Rx pins from the eUSCI on each message, using GPIO_setAsPeripheralModuleFunctionInputPin and GPIO_setAsInputPin. (I'm pretty sure the AVR doesn't know how to do this either, so I expect that end is doing the same thing.) Be sure to wait for the Tx to complete (UCBUSY=0) before disconnecting the pin.

  • Hello Bruce,

    I have gone ahead and changed the GPIO declaration to include only Port 1, GPIO Pin 3. I am still not having much luck at the moment. I am still wondering if the MSP432 has been damaged in some way. I have confirmed that the Arduino is capable of handling Rx and Tx communications with the two respective pins shorted, i.e., when data is Tx'd data reappears on the Rx line. 

    Anyways, here is my code below. In order to reiterate, this specific set of code only has the Tx pin declared. Previously, I tried utilizing the Rx pin only (Tx not declared) and it functioned perfectly fine as a receiver.

    /******************************************************************************
     * MSP432 UART - Arduino with 12MHz BRCLK
     *
     * Description: This program communicates with the Talos's Arduino platform.
     * SMCLK/DCO is used as a clock source and the device is put in LPM0
     * The auto-clock enable feature is used by the eUSCI and SMCLK is turned off
     * when the UART is idle and turned on when a receive edge is detected.
     * Note that level shifter hardware is needed to shift between RS232 and MSP
     * voltage levels.
     *
     *               MSP432P401
     *             -----------------
     *            |                 |
     *            |                 |
     *            |                 |
     *       RST -|     P1.3/UCA0TXD|----> Arduino Rx
     *            |                 |
     *            |                 |
     *            |     P1.2/UCA0RXD|<---- Arduino Tx
     *            |                 |
     *
     *******************************************************************************/
    /* DriverLib Includes */
    #include <driverlib.h>
    
    /* Standard Includes */
    #include <stdint.h>
    #include <stdbool.h>
    #include <stdio.h>
    
    /*
     * Functions that control what happens when bytes are transmitted and received
     */
    void receiveOperation();
    void transmitOperation(char* txData);
    
    /*
     * Functions needed for the receive function
     */
    volatile char receiveBuffer[100];
    volatile i = 0;
    
    //![Simple UART Config]
    /* UART Configuration Parameter. These are the configuration parameters to
     * make the eUSCI A UART module to operate with a 9600 baud rate. These
     * values were calculated using the online calculator that TI provides
     * at:
     *software-dl.ti.com/.../index.html
     */
    const eUSCI_UART_Config uartConfig =
    {
            EUSCI_A_UART_CLOCKSOURCE_SMCLK,          // SMCLK Clock Source
            78,                                     // BRDIV = 78
            2,                                       // UCxBRF = 2
            0,                                       // UCxBRS = 0
            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
    };
    //![Simple UART Config]
    
    int main(void)
                                                                                                                                                                                                                                                                                                                                             {
        /* Halting WDT  */
        MAP_WDT_A_holdTimer();
    
        /* Selecting P1.2 and P1.3 in UART mode */
        MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1, // Changed here to Tx only
                GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
    
        /* Setting DCO to 12MHz */
        CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_12);
    
        //![Simple UART Example]
        /* 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);
        //MAP_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_TRANSMIT_INTERRUPT);
        MAP_Interrupt_enableInterrupt(INT_EUSCIA0);
        //MAP_Interrupt_enableSleepOnIsrExit();
        MAP_Interrupt_enableMaster();
        //![Simple UART Example]
    
        /*
         * 174 150 45 174 100 30 174 150 35 221
         * [START_BYTE] [ENABLE/DISABLE] [PIN SELECTION] [START_BYTE] [ENABLE/DISABLE] [PIN SELECTION] [START_BYTE] [ENABLE/DISABLE] [PIN SELECTION] [TERMINATION]
        */
        char* txData = "17410035221"; // Data to send to Arduino to enable specific pins
        int k = 0;
    
        transmitOperation(txData); // Transmit txData to Arduino PCB
        while(1)
        {
            MAP_PCM_gotoLPM0();
        }
    }
    
    /* EUSCI A0 UART ISR - Echoes data back to PC host */
    void EUSCIA0_IRQHandler(void)
    {
        uint32_t status = MAP_UART_getEnabledInterruptStatus(EUSCI_A0_BASE); // Get interrupt value of Emulated Serial A0 Base Address
    
        MAP_UART_clearInterruptFlag(EUSCI_A0_BASE, status);
    
        if(status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG) // Check to see if interrupt variable triggered and if receive flag was thrown
        {
            receiveBuffer[i] = MAP_UART_receiveData(EUSCI_A0_BASE); // Check for data in the UART Rx Register
            if((receiveBuffer[i]=='1') && (receiveBuffer[i-1]=='2') && (receiveBuffer[i-2]=='2')) // Check to see if the last values are the terminating byte
            {
               receiveOperation(); // Print Acknowledgments
               i = 0; // Reset increment i
            }
            else // Otherwise
            {
              i++; // Increment i
            }
        }
    }
    
    /*
     * Receive Operation. Checks acknowledgments by comparing the send data to the receive acknowledgment
     */
    void receiveOperation()
    {
        char* string= ""; // Create a character string
    
        string = receiveBuffer; // Set that equal to the receive buffer of UART
    
        if(string[0] == '3' && string[1] == '0' && string[2] == '0') // Check for acknowledgment
        {
            printf("Acknowledgment Received: %s \n",string); // Print the Acknowledgment
        }
    }
    
    /*
     * Transmit the data stored in the txData character array
     */
    void transmitOperation(char* txData)
    {
        int j = 0; // Create a new increment variable
    
        while(txData[j]) // While j does not reach the end of txData
        {
            MAP_UART_transmitData(EUSCI_A0_BASE, txData[j]); // Transmit a byte of data from txData
            j++; // Increment a pointer within txData
        }
    }
    

    Thank you again!

  • This code transmits properly on my Launchpad. 

    Can you say more about your Arduino? The closest match I could find was Talos Robotics, which apparently uses an Arduino UNO, which runs at 5V. This should really(!) not be directly connected to the MSP432's 3.3V pins. Doing this can damage the pins (though it doesn't always). 

    At a UART level, there's nothing wrong with using a single wire (Rx connected to Tx), but the eUSCI won't help you out. You need to (a) connect and disconnect (at a GPIO level) the Tx pin at appropriate times, to avoid a bus conflict from the other side and (b) ignore any Rx you get while you're Tx-ing, either in your code or by disconnecting (at a GPIO level) the Rx pin. This sort of thing is common with e.g. RS-485.

  • Bruce,

    Upon further examination and removing a large mess of wires from the equation, I determined the issues were the following:

    1. MSP432 eUSCI does not support half-duplex communication like you said. I have fixed it by toggling unused pins as input when not used.

    2. The single wire was soldered to the Arduino using an Arduino adapter board breakout which was touching the USB connector's casing. The USB connector's casing is tied to ground.

    The Arduino actually can handle the single-wire configuration. Thank you again for your help!