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-EXP432P401R: [MSP432][MSP432P401R] - UART using pins 3.2 and 3.3 - Not receiving anything in the receive buffer

Part Number: MSP-EXP432P401R

Objective: I need the board to interface with a small LIDAR sensor that is based on UART. Before I can interface the sensor to the board and play with it I wanted to make a small "UART driver" of my own to read the sensor values.

Problem Statement: As a validation step, before reading the sensor values, I jumped pin 3.2 and pin 3.3 so that I can read whatever data I put in the UCA2TXBUF register on my UCA2RXBUF register. I used debug mode and step by step/step over for this. I did not have success reading any information on my UCA2RXBUF. My issue is I want to know why.

What I have tried: I checked my clock setup, uart configuration, Modulation control word configuration, NVIC/RX_TX interrupts.  I think its okay. I also tried to turn on loopback for EUSCI_A2 (EUSCI_A_STATW_LISTEN). When i tried this, I was successfully able to receive on UCA2RXBUF.

I am familiar with embedded systems however I am relatively new to development and the MSP micros and so I was wondering if someone on the forum could help figure out why I am not able to receive anything on my receive register. Attaching the code and also pasting it here below

/*****************************************************************************

/*****************************************************************************
*
* Copyright (C) 2013 - 2017 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
*   notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
*   notice, this list of conditions and the following disclaimer in the
*   documentation and/or other materials provided with the
*   distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
*   its contributors may be used to endorse or promote products derived
*   from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*
* UART Driver
* -----------
*
* For the UART to work required items are:
*
*   A. A UART port                        [Port 3, Pins 3.2 and 3.3 chosen]
*   B. UART Port Select Lines             [Port 3, SEL1=0 SEL0=1, UART Mode]
*   C. Clock for Baud rate                [12 MHz chosen]
*   D. Set up Clock registers             [Clock configuration]
*   E. Set up UART registers              [UART configuration]
*
* The recommended initialization procedure from the data sheet is as follows:
*
*   1. Set UCSWRST[UART Reset Flag].
*   2. Initialize all eUSCI_x registers with UCSWRST = 1 (including UCAxCTL1).
*   3. Configure ports.
*   4. Clear UCSWRST with software.
*   5. Enable interrupts (optional) with UCRXIE or UCTXIE.
*
* After the initialization is complete,
*
*  > Data can be transmitted using the TX Buffer and TX Interrupt
*  > Data can be read using the RX Buffer and RX Interrupt
*
******************************************************************************/

#include <stdint.h>
#include "msp.h"
#define __uart2_off() {UCA2CTLW0 |= EUSCI_A_CTLW0_SWRST;}      // Lock UART2
#define __uart2_on()  {UCA2CTLW0 &= (~EUSCI_A_CTLW0_SWRST);}   // Unlock UART2

void uart2clocksetup(void){

    /* Sets up the internal clock of the MSP432p401R
     *
     * Clock Registers Setup (CS)
     * --------------------------
     *
     * Choice of clock is 12 MHz (DCOCLK - SMCLK). While UART itself does not
     * need a clock, a baud rate is generated off of the clock and so it must be
     * configured. Clock registers are also keyed. All bits need to be written
     * together. We then configure the clock registers to set a DCO clock to
     * 12 MHz.
     *
     * Procedure to do this:
     *
     *      1. Unlock clock registers
     *      2. Configure Clock Control register 0
     *      3. Configure Clock Control register 1
     *      4. Lock clock register
     *
    */

    // Set up power for the clock needed. VCORE1 = 1.4 V
    PCM -> CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR__AM_LDO_VCORE1;

    CS -> KEY = CS_KEY_VAL;                           // Unlock CS registers

    // Control Word 0 Set up
    CS -> CTL0 |= CS_CTL0_DCOEN;                      // Enable DCO
    CS -> CTL0 |= CS_CTL0_DCORSEL_0;                  // Reset Tune
    CS -> CTL0 |= CS_CTL0_DCORSEL_3;                  // Set DCO to 12MHz
    CS -> CTL1 |= CS_CTL1_SELS_3;                     // Select DCO CLock
    CS -> CTL1 |= CS_CTL1_DIVS__1;                    // SMCLK divider is 1
    CS -> CTL1 |= CS_CLKEN_SMCLK_EN;                  // Small CLock Enabled

    CS -> KEY = (~CS_KEY_VAL);                        // Lock CS registers

    return;
}


void uart2configure(void){

    /* Sets up the EUSCI_A2 UART registers corresponding to the EUSCI_A2
     * UART module of the MSP432p401R.
     *
     * EUSCI_A2 Registers Setup (UCA2)
     * -------------------------------
     *
     * Protocol requirements for the UART driver are:
     *
     *      1. Parity check disabled
     *      2. LSB first data
     *      3. 8 Data bits
     *      4. 1 Stop bit
     *      5. Baud Rate of 115200
     *
     * Procedure to do this:
     *
     *      1. Reset UART2 flag
     *      2. Configure Control Word0 of EUSCI_A2
     *      3. Configure Control Word1 of EUSCI_A2
     *      4. Configure baud rate register of EUSCI_A2
     *      5. Configure interrupt register of EUSCI_A2
     *
     * Baud Rate Calculation [As per data sheet slau356h.pdf]
     * ---------------------
     *
     * N determines the clock pre-scaler needed to achieve
     * required baud rate
     * N=clock/baud rate
     * N= SMCLK/115200 = 12000000/115200 = 104.166
     * Since N > 16, OS16 = 1 [Meaning Over sampling enabled]
     * UCBR2 = INT(N/16) = INT(6.510) = 6
     * UCBRF2 = INT([(N/16) � INT(N/16)] � 16) = 8
     * UCBRS2 = Fractional part of N = (N - INT(N)) = 0.166 i.e. 0x20
     *
    */

    // Set the UART select lines on PORT3. According to the data
    // sheet, P3.2 and P3.3 are UART RX and TX pins respectively
    // for eUSCIA2. Port 3 select lines needs to be set to 0b01
    // for it to be in UART mode.

    P3 -> DIR = 0;
    P3 -> SEL0 = 0b1;
    P3 -> SEL1 = 0b0;
    P3 -> IE = 0x0C;

    // Control Word0 Set Up
    UCA2CTLW0 &= (~EUSCI_A_CTLW0_PEN);               // Parity Disabled
    UCA2CTLW0 |= EUSCI_A_CTLW0_MSB;                  // MSB First
    UCA2CTLW0 &= (~EUSCI_A_CTLW0_SEVENBIT);          // 8-bit Data
    UCA2CTLW0 &= (~EUSCI_A_CTLW0_SPB);               // 1 stop bit
    UCA2CTLW0 &= (~EUSCI_A_CTLW0_SYNC);              // Asynchronous X
    UCA2CTLW0 |= EUSCI_A_CTLW0_MODE_0;               // UART Mode
    UCA2CTLW0 |= EUSCI_A_CTLW0_UCSSEL_2;             // 12Mhz Clock
    UCA2CTLW0 &= (~EUSCI_A_CTLW0_RXEIE);             // No Error Receive
    UCA2CTLW0 &= (~EUSCI_A_CTLW0_BRKIE);             // No Break Receive

    // Control Word1 Set Up
    UCA2CTLW1 = EUSCI_A_CTLW1_GLIT_0;                // 50ns De-Glitch

    // Modulation Control Word settings
    UCA2MCTLW |= EUSCI_A_MCTLW_OS16;                 // COS16 Enabled
    UCA2BRW = 0x0006;                                // Clock
    UCA2MCTLW |= (EUSCI_A_MCTLW_BRF_MASK & 0x0080);
    UCA2MCTLW |= (EUSCI_A_MCTLW_BRS_MASK & 0x2000);

    // Loop Back Set up
    UCA2STATW &= (~EUSCI_A_STATW_LISTEN);            // Listen OFF

    return;
}

void main(void)
{
    /* Main function of the UART Driver
     *
    */

    WDTCTL = WDTPW | WDTHOLD;                        // Hold Watch dog Timer

    __disable_interrupts();                          // Disable Interrupts
    __uart2_off();                                   // Turn off UART

    uart2clocksetup();                               // Configure CLK for UART
    uart2configure();                                // Configure UART module

    __uart2_on();                                    // Turn on UART

    UCA2IE |= (UCRXIE | UCTXIE | UCTXCPTIE);         // RX & TX Interrupt Enabled

    __enable_interrupts();

    uint16_t cfgin[8] = {0x0042, 0x0057, 0x0002, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002};

    int i;
    uint16_t rxb;

    for(i=0; i<8; i++){
        if(UCA2IFG & UCTXIFG){
            UCA2TXBUF = cfgin[i];
            }
    }


    /*while(1){

        if(UCA2IFG & UCRXIFG){
            rxb = UCA2RXBUF;
        }

    }*/

    return;
}

*
* Copyright (C) 2013 - 2017 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
*   notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
*   notice, this list of conditions and the following disclaimer in the
*   documentation and/or other materials provided with the
*   distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
*   its contributors may be used to endorse or promote products derived
*   from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*
* UART Driver
* -----------
*
* For the UART to work required items are:
*
*   A. A UART port                        [Port 3, Pins 3.2 and 3.3 chosen]
*   B. UART Port Select Lines             [Port 3, SEL1=0 SEL0=1, UART Mode]
*   C. Clock for Baud rate                [12 MHz chosen]
*   D. Set up Clock registers             [Clock configuration]
*   E. Set up UART registers              [UART configuration]
*
* The recommended initialization procedure from the data sheet is as follows:
*
*   1. Set UCSWRST[UART Reset Flag].
*   2. Initialize all eUSCI_x registers with UCSWRST = 1 (including UCAxCTL1).
*   3. Configure ports.
*   4. Clear UCSWRST with software.
*   5. Enable interrupts (optional) with UCRXIE or UCTXIE.
*
* After the initialization is complete,
*
*  > Data can be transmitted using the TX Buffer and TX Interrupt
*  > Data can be read using the RX Buffer and RX Interrupt
*
******************************************************************************/

#include <stdint.h>
#include "msp.h"
#define __uart2_off() {UCA2CTLW0 |= EUSCI_A_CTLW0_SWRST;}      // Lock UART2
#define __uart2_on()  {UCA2CTLW0 &= (~EUSCI_A_CTLW0_SWRST);}   // Unlock UART2

void uart2clocksetup(void){

    /* Sets up the internal clock of the MSP432p401R
     *
     * Clock Registers Setup (CS)
     * --------------------------
     *
     * Choice of clock is 12 MHz (DCOCLK - SMCLK). While UART itself does not
     * need a clock, a baud rate is generated off of the clock and so it must be
     * configured. Clock registers are also keyed. All bits need to be written
     * together. We then configure the clock registers to set a DCO clock to
     * 12 MHz.
     *
     * Procedure to do this:
     *
     *      1. Unlock clock registers
     *      2. Configure Clock Control register 0
     *      3. Configure Clock Control register 1
     *      4. Lock clock register
     *
    */

    // Set up power for the clock needed. VCORE1 = 1.4 V
    PCM -> CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR__AM_LDO_VCORE1;

    CS -> KEY = CS_KEY_VAL;                           // Unlock CS registers

    // Control Word 0 Set up
    CS -> CTL0 |= CS_CTL0_DCOEN;                      // Enable DCO
    CS -> CTL0 |= CS_CTL0_DCORSEL_0;                  // Reset Tune
    CS -> CTL0 |= CS_CTL0_DCORSEL_3;                  // Set DCO to 12MHz
    CS -> CTL1 |= CS_CTL1_SELS_3;                     // Select DCO CLock
    CS -> CTL1 |= CS_CTL1_DIVS__1;                    // SMCLK divider is 1
    CS -> CTL1 |= CS_CLKEN_SMCLK_EN;                  // Small CLock Enabled

    CS -> KEY = (~CS_KEY_VAL);                        // Lock CS registers

    return;
}


void uart2configure(void){

    /* Sets up the EUSCI_A2 UART registers corresponding to the EUSCI_A2
     * UART module of the MSP432p401R.
     *
     * EUSCI_A2 Registers Setup (UCA2)
     * -------------------------------
     *
     * Protocol requirements for the UART driver are:
     *
     *      1. Parity check disabled
     *      2. LSB first data
     *      3. 8 Data bits
     *      4. 1 Stop bit
     *      5. Baud Rate of 115200
     *
     * Procedure to do this:
     *
     *      1. Reset UART2 flag
     *      2. Configure Control Word0 of EUSCI_A2
     *      3. Configure Control Word1 of EUSCI_A2
     *      4. Configure baud rate register of EUSCI_A2
     *      5. Configure interrupt register of EUSCI_A2
     *
     * Baud Rate Calculation [As per data sheet slau356h.pdf]
     * ---------------------
     *
     * N determines the clock pre-scaler needed to achieve
     * required baud rate
     * N=clock/baud rate
     * N= SMCLK/115200 = 12000000/115200 = 104.166
     * Since N > 16, OS16 = 1 [Meaning Over sampling enabled]
     * UCBR2 = INT(N/16) = INT(6.510) = 6
     * UCBRF2 = INT([(N/16) – INT(N/16)] × 16) = 8
     * UCBRS2 = Fractional part of N = (N - INT(N)) = 0.166 i.e. 0x20
     *
    */

    // Set the UART select lines on PORT3. According to the data
    // sheet, P3.2 and P3.3 are UART RX and TX pins respectively
    // for eUSCIA2. Port 3 select lines needs to be set to 0b01
    // for it to be in UART mode.

    P3 -> DIR = 0;
    P3 -> SEL0 = 0b1;
    P3 -> SEL1 = 0b0;
    P3 -> IE = 0x0C;

    // Control Word0 Set Up
    UCA2CTLW0 &= (~EUSCI_A_CTLW0_PEN);               // Parity Disabled
    UCA2CTLW0 |= EUSCI_A_CTLW0_MSB;                  // MSB First
    UCA2CTLW0 &= (~EUSCI_A_CTLW0_SEVENBIT);          // 8-bit Data
    UCA2CTLW0 &= (~EUSCI_A_CTLW0_SPB);               // 1 stop bit
    UCA2CTLW0 &= (~EUSCI_A_CTLW0_SYNC);              // Asynchronous X
    UCA2CTLW0 |= EUSCI_A_CTLW0_MODE_0;               // UART Mode
    UCA2CTLW0 |= EUSCI_A_CTLW0_UCSSEL_2;             // 12Mhz Clock
    UCA2CTLW0 &= (~EUSCI_A_CTLW0_RXEIE);             // No Error Receive
    UCA2CTLW0 &= (~EUSCI_A_CTLW0_BRKIE);             // No Break Receive

    // Control Word1 Set Up
    UCA2CTLW1 = EUSCI_A_CTLW1_GLIT_0;                // 50ns De-Glitch

    // Modulation Control Word settings
    UCA2MCTLW |= EUSCI_A_MCTLW_OS16;                 // COS16 Enabled
    UCA2BRW = 0x0006;                                // Clock
    UCA2MCTLW |= (EUSCI_A_MCTLW_BRF_MASK & 0x0080);
    UCA2MCTLW |= (EUSCI_A_MCTLW_BRS_MASK & 0x2000);

    // Loop Back Set up
    UCA2STATW &= (~EUSCI_A_STATW_LISTEN);            // Listen OFF

    return;
}

void main(void)
{
    /* Main function of the UART Driver
     *
    */

    WDTCTL = WDTPW | WDTHOLD;                        // Hold Watch dog Timer

    __disable_interrupts();                          // Disable Interrupts
    __uart2_off();                                   // Turn off UART

    uart2clocksetup();                               // Configure CLK for UART
    uart2configure();                                // Configure UART module

    __uart2_on();                                    // Turn on UART

    UCA2IE |= (UCRXIE | UCTXIE | UCTXCPTIE);         // RX & TX Interrupt Enabled

    __enable_interrupts();

    uint16_t cfgin[8] = {0x0042, 0x0057, 0x0002, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002};

    int i;
    uint16_t rxb;

    for(i=0; i<8; i++){
        if(UCA2IFG & UCTXIFG){
            UCA2TXBUF = cfgin[i];
            }
    }


    /*while(1){

        if(UCA2IFG & UCRXIFG){
            rxb = UCA2RXBUF;
        }

    }*/

    return;
}



  • Hi Manu,

    just had a brief look into your code.

    The first thing i have seen is your IO pin configuration and this also matches your description of internal loopback is working and loopback on IO not:

    So can you try this changes:

        P3 -> DIR = 0;
        P3 -> SEL0 = 0x0C;   // set special function 0 for P3.2 and P3.3
        P3 -> SEL1 = 0x00;
        P3 -> IE = 0;        // do not io interrupts -> not sure if there was a reason why this should be enabled. 
                             // If yes, the ISR handler is missing.
    

    Regards,

    Stefan

  • Hi Stefan,

    Thank you for the quick response. My apologies, I must have misunderstood/overlooked the fact the sel0 and sel1 registers are 8bit registers for 8 different pins. I get why you suggested the changes. I have tried it out. Unfortunately I still have the same issue. My changes below. I agree I did not notice I had the IE register set incorrectly either. Indeed there is no ISR for it. Corrected that as well. Anything else I could try?

        P3 -> DIR    = 0x00;                                // [Direction is irrelevant]
        P3 -> SEL0 = 0x0C;                               // [0000 1100] P3SEL0 set to 1 for pins 3.2 and 3.3
        P3 -> SEL1 = 0x00;                               // [0000 0000] P3SEL1 set to 0 for pins 3.2 and 3.3
        P3 -> IE       = 0x00;                               // No interrupts enabled for Port 3

  • Hi,

    changed your main function a little bit:

        uint16_t cfgin[8] = {0x0042, 0x0057, 0x0002, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002};
    
        int i = 0;
        uint16_t rxb[8];
        uint16_t * prxb = rxb;
    
        while(i<8){
            if(UCA2IFG & UCTXIFG){   // if TX Buffer is free
                UCA2TXBUF = cfgin[i++];
            }
    
    
            if(UCA2IFG & UCRXIFG){         // if received take the char
                *prxb++ = UCA2RXBUF;
            }
        }
    
    
        while(1){
    
            if(UCA2IFG & UCRXIFG){         // take rest
                *prxb++ = UCA2RXBUF;
            }
    

    The issue was in the flow of the data handling. Data transmit and receive are running parallel not sequential.

    ~ Stefan

  • Stefan,

    I tried the suggested modifications however I still was not able to get anything in the receive buffer

    UCARXBUF    0x0000    eUSCI_Ax Receive Buffer Register [Memory Mapped]    
        UCRXBUF    00000000    Receive data buffer    
    UCARXBUF_SPI    0x0000    eUSCI_Ax Receive Buffer Register [Memory Mapped]    
    UCATXBUF    0x0002    eUSCI_Ax Transmit Buffer Register [Memory Mapped]    
    UCATXBUF_SPI    0x0002    eUSCI_Ax Transmit Buffer Register [Memory Mapped]    

  • Hi Manu,

    i have attached the file i have used so you can compare.

    /*
    *
    * Copyright (C) 2013 - 2017 Texas Instruments Incorporated - http://www.ti.com/
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions
    * are met:
    *
    * * Redistributions of source code must retain the above copyright
    *   notice, this list of conditions and the following disclaimer.
    *
    * * Redistributions in binary form must reproduce the above copyright
    *   notice, this list of conditions and the following disclaimer in the
    *   documentation and/or other materials provided with the
    *   distribution.
    *
    * * Neither the name of Texas Instruments Incorporated nor the names of
    *   its contributors may be used to endorse or promote products derived
    *   from this software without specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    *
    ******************************************************************************
    *
    * UART Driver
    * -----------
    *
    * For the UART to work required items are:
    *
    *   A. A UART port                        [Port 3, Pins 3.2 and 3.3 chosen]
    *   B. UART Port Select Lines             [Port 3, SEL1=0 SEL0=1, UART Mode]
    *   C. Clock for Baud rate                [12 MHz chosen]
    *   D. Set up Clock registers             [Clock configuration]
    *   E. Set up UART registers              [UART configuration]
    *
    * The recommended initialization procedure from the data sheet is as follows:
    *
    *   1. Set UCSWRST[UART Reset Flag].
    *   2. Initialize all eUSCI_x registers with UCSWRST = 1 (including UCAxCTL1).
    *   3. Configure ports.
    *   4. Clear UCSWRST with software.
    *   5. Enable interrupts (optional) with UCRXIE or UCTXIE.
    *
    * After the initialization is complete,
    *
    *  > Data can be transmitted using the TX Buffer and TX Interrupt
    *  > Data can be read using the RX Buffer and RX Interrupt
    *
    ******************************************************************************/
    
    #include <stdint.h>
    #include "msp.h"
    #define __uart2_off() {UCA2CTLW0 |= EUSCI_A_CTLW0_SWRST;}      // Lock UART2
    #define __uart2_on()  {UCA2CTLW0 &= (~EUSCI_A_CTLW0_SWRST);}   // Unlock UART2
    
    void uart2clocksetup(void){
    
        /* Sets up the internal clock of the MSP432p401R
         *
         * Clock Registers Setup (CS)
         * --------------------------
         *
         * Choice of clock is 12 MHz (DCOCLK - SMCLK). While UART itself does not
         * need a clock, a baud rate is generated off of the clock and so it must be
         * configured. Clock registers are also keyed. All bits need to be written
         * together. We then configure the clock registers to set a DCO clock to
         * 12 MHz.
         *
         * Procedure to do this:
         *
         *      1. Unlock clock registers
         *      2. Configure Clock Control register 0
         *      3. Configure Clock Control register 1
         *      4. Lock clock register
         *
        */
    
        // Set up power for the clock needed. VCORE1 = 1.4 V
        PCM -> CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR__AM_LDO_VCORE1;
    
        CS -> KEY = CS_KEY_VAL;                           // Unlock CS registers
    
        // Control Word 0 Set up
        CS -> CTL0 |= CS_CTL0_DCOEN;                      // Enable DCO
        CS -> CTL0 |= CS_CTL0_DCORSEL_0;                  // Reset Tune
        CS -> CTL0 |= CS_CTL0_DCORSEL_3;                  // Set DCO to 12MHz
        CS -> CTL1 |= CS_CTL1_SELS_3;                     // Select DCO CLock
        CS -> CTL1 |= CS_CTL1_DIVS__1;                    // SMCLK divider is 1
        CS -> CTL1 |= CS_CLKEN_SMCLK_EN;                  // Small CLock Enabled
    
        CS -> KEY = (~CS_KEY_VAL);                        // Lock CS registers
    
        return;
    }
    
    
    void uart2configure(void){
    
        /* Sets up the EUSCI_A2 UART registers corresponding to the EUSCI_A2
         * UART module of the MSP432p401R.
         *
         * EUSCI_A2 Registers Setup (UCA2)
         * -------------------------------
         *
         * Protocol requirements for the UART driver are:
         *
         *      1. Parity check disabled
         *      2. LSB first data
         *      3. 8 Data bits
         *      4. 1 Stop bit
         *      5. Baud Rate of 115200
         *
         * Procedure to do this:
         *
         *      1. Reset UART2 flag
         *      2. Configure Control Word0 of EUSCI_A2
         *      3. Configure Control Word1 of EUSCI_A2
         *      4. Configure baud rate register of EUSCI_A2
         *      5. Configure interrupt register of EUSCI_A2
         *
         * Baud Rate Calculation [As per data sheet slau356h.pdf]
         * ---------------------
         *
         * N determines the clock pre-scaler needed to achieve
         * required baud rate
         * N=clock/baud rate
         * N= SMCLK/115200 = 12000000/115200 = 104.166
         * Since N > 16, OS16 = 1 [Meaning Over sampling enabled]
         * UCBR2 = INT(N/16) = INT(6.510) = 6
         * UCBRF2 = INT([(N/16) � INT(N/16)] � 16) = 8
         * UCBRS2 = Fractional part of N = (N - INT(N)) = 0.166 i.e. 0x20
         *
        */
    
        // Set the UART select lines on PORT3. According to the data
        // sheet, P3.2 and P3.3 are UART RX and TX pins respectively
        // for eUSCIA2. Port 3 select lines needs to be set to 0b01
        // for it to be in UART mode.
    
        P3 -> DIR = 0;
        P3 -> SEL0 = 0x0C;   // set special function 0 for P3.2 and P3.3
        P3 -> SEL1 = 0x00;
        P3 -> IE = 0;        // do not io interrupts -> not sure if there was a reason why this should be enabled.
                             // If yes, the ISR handler is missing.
    
        // Control Word0 Set Up
        UCA2CTLW0 &= (~EUSCI_A_CTLW0_PEN);               // Parity Disabled
        UCA2CTLW0 |= EUSCI_A_CTLW0_MSB;                  // MSB First
        UCA2CTLW0 &= (~EUSCI_A_CTLW0_SEVENBIT);          // 8-bit Data
        UCA2CTLW0 &= (~EUSCI_A_CTLW0_SPB);               // 1 stop bit
        UCA2CTLW0 &= (~EUSCI_A_CTLW0_SYNC);              // Asynchronous X
        UCA2CTLW0 |= EUSCI_A_CTLW0_MODE_0;               // UART Mode
        UCA2CTLW0 |= EUSCI_A_CTLW0_UCSSEL_2;             // 12Mhz Clock
        UCA2CTLW0 &= (~EUSCI_A_CTLW0_RXEIE);             // No Error Receive
        UCA2CTLW0 &= (~EUSCI_A_CTLW0_BRKIE);             // No Break Receive
    
        // Control Word1 Set Up
        UCA2CTLW1 = EUSCI_A_CTLW1_GLIT_0;                // 50ns De-Glitch
    
        // Modulation Control Word settings
        UCA2MCTLW |= EUSCI_A_MCTLW_OS16;                 // COS16 Enabled
        UCA2BRW = 0x0006;                                // Clock
        UCA2MCTLW |= (EUSCI_A_MCTLW_BRF_MASK & 0x0080);
        UCA2MCTLW |= (EUSCI_A_MCTLW_BRS_MASK & 0x2000);
    
        // Loop Back Set up
        UCA2STATW &= (~EUSCI_A_STATW_LISTEN);            // Listen OFF
    
        return;
    }
    
    void main(void)
    {
        /* Main function of the UART Driver
         *
        */
    
        WDTCTL = WDTPW | WDTHOLD;                        // Hold Watch dog Timer
    
        __disable_interrupts();                          // Disable Interrupts
        __uart2_off();                                   // Turn off UART
    
        uart2clocksetup();                               // Configure CLK for UART
        uart2configure();                                // Configure UART module
    
        __uart2_on();                                    // Turn on UART
    
        UCA2IE |= (UCRXIE | UCTXIE | UCTXCPTIE);         // RX & TX Interrupt Enabled
    
        __enable_interrupts();
    
        uint16_t cfgin[8] = {0x0042, 0x0057, 0x0002, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002};
    
        int i = 0;
        uint16_t rxb[8];
        uint16_t * prxb = rxb;
    
        while(i<8){
            if(UCA2IFG & UCTXIFG){   // if TX Buffer is free
                UCA2TXBUF = cfgin[i++];
            }
    
    
            if(UCA2IFG & UCRXIFG){         // if received take the char
                *prxb++ = UCA2RXBUF;
            }
        }
    
    
        while(1){
    
            if(UCA2IFG & UCRXIFG){         // take rest
                *prxb++ = UCA2RXBUF;
            }
    
        }
    
        return;
    }
    

    A few things to ensure:

    - you still have the jumper on P3.2 and P3.3

    - when you run the program does it run to the final while loop

    - can you check the content of the rxb buffer

    Regards,

    Stefan

  • Used the main file you attached and tried it out. No dice still.

    Things I ensured:

    - you still have the jumper on P3.2 and P3.3 - Verified. Also checked continuity on the wire i used just in case.

    - when you run the program does it run to the final while loop - Yes. It reaches the //take rest section

    - can you check the content of the rxb buffer - The content of the rxb buffer in the registers window, Registers  -> EUSCI_A2 ->UCARXBUF remains 0x0000 throughout the debug session. UCATXBUF however changes according to the while loop iteration. And so does all other registers under EUSCI_A2 that i change.

    Although its unlikely do you think this could be a hardware issue? Is there a way i can confirm? Or are there more things we could do to debug this issue?

  • I also tried the factory reset script. And then reloaded my code on the target.
  • Hi,
    might be good to check the hardware first before doing some other research on this issue.

    You can do this quite fast within the debugger.
    After downloading the code within CCS (not starting execution):
    - open the Register view window.
    - go to P3 section and expand it.

    - enter a value of 0x0 into P3OUT
    - enter a value of 0x4 into P3DIR
    - check P3IN => BIT3 and BIT4 should be low (Others do not care)

    - enter a value of 0x4 into P3OUT
    - enter a value of 0x4 into P3DIR
    - check P3IN => BIT3 and BIT4 should be high (Others do not care)

    - enter a value of 0x0 into P3OUT
    - enter a value of 0x8 into P3DIR
    - check P3IN => BIT3 and BIT4 should be low (Others do not care)

    - enter a value of 0x8 into P3OUT
    - enter a value of 0x8 into P3DIR
    - check P3IN => BIT3 and BIT4 should be high (Others do not care)

    This ensures the connection between the device pins over the PCB and the jumper is OK.

    This is very fast and nice way to check the connections.

    Regards,
    Stefan
  • My results are as follows. I definitely feel like something is not right.

    dir=0x04, out=0x00 -> p3in = 0x08
    dir=0x04, out=0x04 -> p3in = 0x08
    dir=0x08, out=0x00 -> p3in = 0x00
    dir=0x08, out=0x08 -> p3in = 0x08

    p3.3 is almost always high. I am not sure what this means.

  • Hi Manu,

    there is really something strange.
    it looks like that P3.2 does not work
    The expected result would be
    Without the jumper
    dir=0x04, out=0x04 -> p3in = 0x04
    dir=0x08, out=0x08 -> p3in = 0x08
    Without the jumper
    dir=0x04, out=0x04 -> p3in = 0x0C
    dir=0x08, out=0x08 -> p3in = 0x0C

    Can you check this on another board?

    Regards,
    Stefan
  • That is the way that serial works. It sends a "1" when it is idle, and then a '0' for the startbit.
  • Keith - I am assuming you are referring to data transfer protocol itself. The test that  I performed was just on pin 3 to validate if pin 3.2 and 3.3 work. Not a part of the attached code in the thread. For the test set the P3SEL0=P3SEL1=P3SELC=0x00.

    Stefan - I will place an order for a new board. I am assuming it will arrive the following week. I suppose you can close out this thread. I will re-open an a new issue should i have trouble with the new board.

    Thank you so much stefan and keith for taking the time to help me. Marking this issue as resolved.

  • Is the lidar a literal RS-232? It might be putting too much voltage on the MCU which will kill it. (It is my mission in life to educate people about this.)
  • Good point!

    Manu can you confirm that the voltage levels on the UART are complient to the device and within 0V and DVCC (Supply Volage Level)
    Otherwise you might damage the new board again.

    Regards,
    Stefan
  • Hi,

    I suppose that you were able to move on with your application as you didn't reply anymore, so I'll close this post.
    Please feel free to comment again if you look for further assistance regarding this topic, it will re-open the thread. If you have a different question, please select "Ask a related question" or " Ask a new question".

    Best regards,
    Stefan

**Attention** This is a public forum