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;
}