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: Unable to read device id

Part Number: MSP430FR5994

Dear sir/mam

I'm trying to interface ADXL345 accelerometer with msp430fr5994 by using SPI. When i run the program I'm getting dummy value as 0XFF on transmit buffer.Im sharing the code here.I have used header file as SDK of standared master_spi. Please solve my mistake.

#include <msp430.h>
#include <spi.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

unsigned char addr[30]="";

void initSPI()
{
//Clock Polarity: The inactive state is high
//MSB First, 8-bit, Master, 3-pin mode, Synchronous
UCB1CTLW0 = UCSWRST; // **Put state machine in reset
UCB1CTLW0 |= UCCKPL | UCMSB | UCSYNC
| UCMST | UCSSEL__SMCLK; // 3-pin, 8-bit SPI Slave SMCLK=16MHZ
UCB1BRW = 0x160; //16000000/160=100KHZ
//UCB1MCTLW = 0;
UCB1CTLW0 &= ~UCSWRST; // **Initialize USCI state machine**
UCB1IE |= UCRXIE; // Enable USCI0 RX interrupt
}


void initGPIO()
{
//LEDs
COMMS_LED_DIR |= COMMS_LED_PIN;
COMMS_LED_OUT &= ~COMMS_LED_PIN;

BUTTON_LED_DIR |= BUTTON_LED_PIN;
BUTTON_LED_OUT &= ~BUTTON_LED_PIN;

// Configure SPI
P5SEL0 |= BIT0 | BIT1 | BIT2;

SLAVE_RST_DIR |= SLAVE_RST_PIN;
SLAVE_RST_OUT |= SLAVE_RST_PIN;

SLAVE_CS_DIR |= SLAVE_CS_PIN;
SLAVE_CS_OUT |= SLAVE_CS_PIN;

//Button to initiate transfer
BUTTON_DIR &= ~(BUTTON_PIN); // button input
BUTTON_OUT |= BUTTON_PIN; // button pull up
BUTTON_REN |= BUTTON_PIN; // button pull up/down resistor enable
BUTTON_IES |= BUTTON_PIN; // button Hi/lo edge
BUTTON_IE |= BUTTON_PIN; // button interrupt enabled

// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;

BUTTON_IFG &= ~BUTTON_PIN; // button IFG cleared
}

void initClockTo16MHz()
{
// Configure one FRAM waitstate as required by the device datasheet for MCLK
// operation beyond 8MHz _before_ configuring the clock system.
FRCTL0 = FRCTLPW | NWAITS_1;

// Clock System Setup
CSCTL0_H = CSKEY_H; // Unlock CS registers
CSCTL1 = DCOFSEL_0; // Set DCO to 1MHz

// Set SMCLK = MCLK = DCO, ACLK = LFXTCLK (VLOCLK if unavailable)
CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;

// Per Device Errata set divider to 4 before changing frequency to
// prevent out of spec operation from overshoot transient
CSCTL3 = DIVA__4 | DIVS__4 | DIVM__4; // Set all corresponding clk sources to divide by 4 for errata
CSCTL1 = DCOFSEL_4 | DCORSEL; // Set DCO to 16MHz

// Delay by ~10us to let DCO settle. 60 cycles = 20 cycles buffer + (10us / (1/4MHz))
__delay_cycles(60);
CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1; // Set all dividers to 1 for 16MHz operation
CSCTL0_H = 0; // Lock CS registers
}

int adxl_device_id()
{
unsigned int id;
SPI_Master_ReadReg(CMD_TYPE_0_SLAVE,TYPE_0_LENGTH);
id=ReceiveBuffer[0];
return id;
}

int main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

initClockTo16MHz();
initGPIO();
initSPI();

SLAVE_RST_OUT &= ~SLAVE_RST_PIN; // Now with SPI signals initialized,
__delay_cycles(100000);
SLAVE_RST_OUT |= SLAVE_RST_PIN; // reset slave
__delay_cycles(100000); // Wait for slave to initialize

COMMS_LED_OUT |= COMMS_LED_PIN;

while(1)
{
int adxl_id;
adxl_id=adxl_device_id();

}
return 0;
}

  • Missing is the code to do the actual SPI read. It appears that you might be using some driver library. The one I looked at had its very own definition for SLAVE_CS_OUT. Unless that matches what you chose here, it will never work.

  • dear david

    I'M sharing the code with missed code as you said.Actually i have used TI's sdk as header file which i have not shared previously.So please check the code. And coming to driver library i have used same library which i have used in my previous programs.

    //////////////////////////////////////////////////////////////////////////////////////main.c//////////////////////////////////////////////////////////////////////////////////////////////////////

    #include <msp430.h>
    #include <spi.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>

    unsigned char addr[30]="";


    void initSPI()
    {
    //Clock Polarity: The inactive state is high
    //MSB First, 8-bit, Master, 3-pin mode, Synchronous
    UCB1CTLW0 = UCSWRST; // **Put state machine in reset
    UCB1CTLW0 |= UCCKPL | UCMSB | UCSYNC
    | UCMST | UCSSEL__SMCLK; // 3-pin, 8-bit SPI Slave SMCLK=16MHZ
    UCB1BRW = 0x160; //16000000/160=100KHZ
    //UCB1MCTLW = 0;
    UCB1CTLW0 &= ~UCSWRST; // **Initialize USCI state machine**
    UCB1IE |= UCRXIE; // Enable USCI0 RX interrupt
    }


    void initGPIO()
    {
    //LEDs
    COMMS_LED_DIR |= COMMS_LED_PIN;
    COMMS_LED_OUT &= ~COMMS_LED_PIN;

    BUTTON_LED_DIR |= BUTTON_LED_PIN;
    BUTTON_LED_OUT &= ~BUTTON_LED_PIN;

    // Configure SPI
    P5SEL0 |= BIT0 | BIT1 | BIT2;

    SLAVE_RST_DIR |= SLAVE_RST_PIN;
    SLAVE_RST_OUT |= SLAVE_RST_PIN;

    SLAVE_CS_DIR |= SLAVE_CS_PIN;
    SLAVE_CS_OUT |= SLAVE_CS_PIN;

    //Button to initiate transfer
    BUTTON_DIR &= ~(BUTTON_PIN); // button input
    BUTTON_OUT |= BUTTON_PIN; // button pull up
    BUTTON_REN |= BUTTON_PIN; // button pull up/down resistor enable
    BUTTON_IES |= BUTTON_PIN; // button Hi/lo edge
    BUTTON_IE |= BUTTON_PIN; // button interrupt enabled

    // Disable the GPIO power-on default high-impedance mode to activate
    // previously configured port settings
    PM5CTL0 &= ~LOCKLPM5;

    BUTTON_IFG &= ~BUTTON_PIN; // button IFG cleared
    }

    void initClockTo16MHz()
    {
    // Configure one FRAM waitstate as required by the device datasheet for MCLK
    // operation beyond 8MHz _before_ configuring the clock system.
    FRCTL0 = FRCTLPW | NWAITS_1;

    // Clock System Setup
    CSCTL0_H = CSKEY_H; // Unlock CS registers
    CSCTL1 = DCOFSEL_0; // Set DCO to 1MHz

    // Set SMCLK = MCLK = DCO, ACLK = LFXTCLK (VLOCLK if unavailable)
    CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;

    // Per Device Errata set divider to 4 before changing frequency to
    // prevent out of spec operation from overshoot transient
    CSCTL3 = DIVA__4 | DIVS__4 | DIVM__4; // Set all corresponding clk sources to divide by 4 for errata
    CSCTL1 = DCOFSEL_4 | DCORSEL; // Set DCO to 16MHz

    // Delay by ~10us to let DCO settle. 60 cycles = 20 cycles buffer + (10us / (1/4MHz))
    __delay_cycles(60);
    CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1; // Set all dividers to 1 for 16MHz operation
    CSCTL0_H = 0; // Lock CS registers
    }

    int adxl_device_id()
    {
    unsigned int id;
    SPI_Master_ReadReg(CMD_TYPE_0_SLAVE,TYPE_0_LENGTH);
    id=ReceiveBuffer[0];
    return id;
    }


    int main(void) {
    WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

    initClockTo16MHz();
    initGPIO();
    initSPI();

    SLAVE_RST_OUT &= ~SLAVE_RST_PIN; // Now with SPI signals initialized,
    __delay_cycles(100000);
    SLAVE_RST_OUT |= SLAVE_RST_PIN; // reset slave
    __delay_cycles(100000); // Wait for slave to initialize

    COMMS_LED_OUT |= COMMS_LED_PIN;
    // SPI_Master_WriteReg(CMD_TYPE_0_MASTER, MasterType0, TYPE_0_LENGTH);
    //__bis_SR_register(LPM0_bits + GIE); // CPU off, enable interrupts
    while(1)
    {
    int adxl_id;
    adxl_id=adxl_device_id();
    printf("%x",adxl_id);
    }
    }

    //////////////////////////////////////////////////////////////////////////////////////////////spi.h//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    #include <msp430.h>
    #include <stdint.h>
    #include <stdbool.h>
    //******************************************************************************
    // Pin Config ******************************************************************
    //******************************************************************************
    volatile int Tx_index=0;
    volatile int Rx_index=0;
    volatile unsigned int Rx_key=0;
    volatile unsigned int Tx_key=0;
    int size=0;
    unsigned char Data[15]="";
    unsigned char RXData[5]="";
    #define SLAVE_CS_OUT P5OUT
    #define SLAVE_CS_DIR P5DIR
    #define SLAVE_CS_PIN BIT2

    #define SLAVE_RST_OUT P1OUT
    #define SLAVE_RST_DIR P1DIR
    #define SLAVE_RST_PIN BIT4

    #define BUTTON_DIR P5DIR
    #define BUTTON_OUT P5OUT
    #define BUTTON_REN P5REN
    #define BUTTON_PIN BIT5
    #define BUTTON_IES P5IES
    #define BUTTON_IE P5IE
    #define BUTTON_IFG P5IFG
    #define BUTTON_VECTOR PORT5_VECTOR

    #define BUTTON_LED_OUT P1OUT
    #define BUTTON_LED_DIR P1DIR
    #define BUTTON_LED_PIN BIT1

    #define COMMS_LED_OUT P1OUT
    #define COMMS_LED_DIR P1DIR
    #define COMMS_LED_PIN BIT0

    //******************************************************************************
    // Example Commands ************************************************************
    //******************************************************************************

    #define DUMMY 0xFF

    /* CMD_TYPE_X_SLAVE are example commands the master sends to the slave.
    * The slave will send example SlaveTypeX buffers in response.
    *
    * CMD_TYPE_X_MASTER are example commands the master sends to the slave.
    * The slave will initialize itself to receive MasterTypeX example buffers.
    * */

    #define CMD_TYPE_0_SLAVE 0
    #define CMD_TYPE_1_SLAVE 1
    #define CMD_TYPE_2_SLAVE 2

    #define CMD_TYPE_0_MASTER 3
    #define CMD_TYPE_1_MASTER 4
    #define CMD_TYPE_2_MASTER 5

    #define TYPE_0_LENGTH 1
    #define TYPE_1_LENGTH 2
    #define TYPE_2_LENGTH 6

    #define MAX_BUFFER_SIZE 20

    /* MasterTypeX are example buffers initialized in the master, they will be
    * sent by the master to the slave.
    * SlaveTypeX are example buffers initialized in the slave, they will be
    * sent by the slave to the master.
    * */

    uint8_t MasterType0 [TYPE_0_LENGTH] = {0x11};
    uint8_t MasterType1 [TYPE_1_LENGTH] = {8, 9};
    uint8_t MasterType2 [TYPE_2_LENGTH] = {'F', '4' , '1' , '9', '2', 'B'};

    uint8_t SlaveType2 [TYPE_2_LENGTH] = {0};
    uint8_t SlaveType1 [TYPE_1_LENGTH] = {0};
    uint8_t SlaveType0 [TYPE_0_LENGTH] = {0};


    //******************************************************************************
    // General SPI State Machine ***************************************************
    //******************************************************************************

    typedef enum SPI_ModeEnum{
    IDLE_MODE,
    TX_REG_ADDRESS_MODE,
    RX_REG_ADDRESS_MODE,
    TX_DATA_MODE,
    RX_DATA_MODE,
    TIMEOUT_MODE
    } SPI_Mode;


    /* Used to track the state of the software state machine*/
    SPI_Mode MasterMode = IDLE_MODE;

    /* The Register Address/Command to use*/
    uint8_t TransmitRegAddr = 0;

    /* ReceiveBuffer: Buffer used to receive data in the ISR
    * RXByteCtr: Number of bytes left to receive
    * ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
    * TransmitBuffer: Buffer used to transmit data in the ISR
    * TXByteCtr: Number of bytes left to transfer
    * TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
    * */
    uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t RXByteCtr = 0;
    uint8_t ReceiveIndex = 0;
    uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t TXByteCtr = 0;
    uint8_t TransmitIndex = 0;

    /* SPI Write and Read Functions */

    /* For slave device, writes the data specified in *reg_data
    *
    * reg_addr: The register or command to send to the slave.
    * Example: CMD_TYPE_0_MASTER
    * *reg_data: The buffer to write
    * Example: MasterType0
    * count: The length of *reg_data
    * Example: TYPE_0_LENGTH
    * */
    SPI_Mode SPI_Master_WriteReg(uint8_t reg_addr, uint8_t *reg_data, uint8_t count);

    /* For slave device, read the data specified in slaves reg_addr.
    * The received data is available in ReceiveBuffer
    *
    * reg_addr: The register or command to send to the slave.
    * Example: CMD_TYPE_0_SLAVE
    * count: The length of data to read
    * Example: TYPE_0_LENGTH
    * */
    SPI_Mode SPI_Master_ReadReg(uint8_t reg_addr, uint8_t count);
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
    void SendUCB1Data(uint8_t val);

    void SendUCB1Data(uint8_t val)
    {
    while (!(UCB1IFG & UCTXIFG)); // USCI_B1 TX buffer ready?
    UCB1TXBUF = val;
    }

    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
    {
    uint8_t copyIndex = 0;
    for (copyIndex = 0; copyIndex < count; copyIndex++)
    {
    dest[copyIndex] = source[copyIndex];
    }
    }


    SPI_Mode SPI_Master_WriteReg(uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
    {
    MasterMode = TX_REG_ADDRESS_MODE;
    TransmitRegAddr = reg_addr;

    //Copy register data to TransmitBuffer
    CopyArray(reg_data, TransmitBuffer, count);

    TXByteCtr = count;
    RXByteCtr = 0;
    ReceiveIndex = 0;
    TransmitIndex = 0;

    SLAVE_CS_OUT &= ~(SLAVE_CS_PIN);
    SendUCB1Data(TransmitRegAddr);

    __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts

    SLAVE_CS_OUT |= SLAVE_CS_PIN;
    return MasterMode;
    }

    SPI_Mode SPI_Master_ReadReg(uint8_t reg_addr, uint8_t count)
    {
    MasterMode = TX_REG_ADDRESS_MODE;
    TransmitRegAddr = reg_addr;//0X00,1
    RXByteCtr = count;
    TXByteCtr = 0;
    ReceiveIndex = 0;
    TransmitIndex = 0;

    SLAVE_CS_OUT &= ~(SLAVE_CS_PIN);
    SendUCB1Data(TransmitRegAddr);//0x00

    __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts

    SLAVE_CS_OUT |= SLAVE_CS_PIN;
    return MasterMode;
    }

    //******************************************************************************
    // SPI Interrupt ***************************************************************
    //******************************************************************************

    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=USCI_B1_VECTOR
    __interrupt void USCI_B1_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_B1_VECTOR))) USCI_B1_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
    uint8_t ucb1_rx_val = 0;
    switch(__even_in_range(UCB1IV, USCI_SPI_UCTXIFG))
    {
    case USCI_NONE: break;
    case USCI_SPI_UCRXIFG:
    ucb1_rx_val = UCB1RXBUF;
    UCB1IFG &= ~UCRXIFG;
    switch (MasterMode)
    {
    case TX_REG_ADDRESS_MODE:
    if (RXByteCtr)
    {
    MasterMode = RX_DATA_MODE; // Need to start receiving now
    //Send Dummy To Start
    __delay_cycles(2000000);
    SendUCB1Data(DUMMY);
    }
    else
    {
    MasterMode = TX_DATA_MODE; // Continue to transmision with the data in Transmit Buffer
    //Send First
    SendUCB1Data(TransmitBuffer[TransmitIndex++]);
    TXByteCtr--;
    }
    break;

    case TX_DATA_MODE:
    if (TXByteCtr)
    {
    SendUCB1Data(TransmitBuffer[TransmitIndex++]);
    TXByteCtr--;
    }
    else
    {
    //Done with transmission
    MasterMode = IDLE_MODE;
    __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
    }
    break;

    case RX_DATA_MODE:
    if (RXByteCtr)
    {
    ReceiveBuffer[ReceiveIndex++] = ucb1_rx_val;
    //Transmit a dummy
    RXByteCtr--;
    }
    if (RXByteCtr == 0)
    {
    MasterMode = IDLE_MODE;
    __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
    }
    else
    {
    SendUCB1Data(DUMMY);
    }
    break;

    default:
    __no_operation();
    break;
    }
    __delay_cycles(1000);
    break;
    case USCI_SPI_UCTXIFG:
    break;
    default: break;
    }
    }


    //******************************************************************************
    // Button Port Interrupt *************************************************************
    // Interrupt occurs on button press and initiates the SPI data transfer ********
    //******************************************************************************

    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=BUTTON_VECTOR
    __interrupt void Button_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(BUTTON_VECTOR))) Button_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
    BUTTON_LED_OUT |= BUTTON_LED_PIN;
    BUTTON_IFG &= ~BUTTON_PIN; // button IFG cleared
    BUTTON_IE &= ~BUTTON_PIN;
    //Initiate
    __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
    }

  • It appears as though you are trying to use port 5 bit 2 as the chip select even though that pin is assigned to the SPI clock output. That will never work. Do you really have CS connected to the SPI clock or to some other pin?

    Fullscreen
    1
    2
    3
    4
    5
    6
    // Configure SPI
    P5SEL0 |= BIT0 | BIT1 | BIT2;
    #define SLAVE_CS_OUT P5OUT
    #define SLAVE_CS_DIR P5DIR
    #define SLAVE_CS_PIN BIT2
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • I have checked the pins and changed the macros P5  with P8 as CS - pin is P8.2. But still I'm getting a dummy (0xFF) in transmit buffer.

  • It si difficult to debug a hardware/software system remotely. You are going to have to figure out how to do that. Start simple and test as you go. Can you get data and clock out of the SPI port? Chip select? Then get data back. It can be tricky sometimes. I recently had an OLED display give me fits. Then I discovered that in spite of what its data sheet said, it cared about the idle state of the SPI clock.

    The interrupts complicate your life a lot. They don't seem to add much and for simple systems I prefer a polled approach with a simple function that writes a byte and returns one. It is really simple: put data into TXBUF, wait for RXIFG, read RXBUF.

    This is what I used with the OLED. (Different MSP430 so the details will of course vary.)

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    char spi_write(char data)
    {
    UCB0TXBUF = data;
    while(!(IFG2 & UCB0RXIFG))
    ;
    return UCB0RXBUF;
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • can you please tell me weather UCB1BRW value was correct are not. And can you tell me that how to select the mode programatically for spi. Because for SPI there are 4 modes by clock phase and clock polarity. So can you ans to these 2 questions?

  • I have no idea if your BRW value is "correct". It is certainly far larger than is required to keep the clock frequency slow enough. As for clock phase and polarity, you must look at the data sheets. I have used the ADXL335 in I2C mode but never the 345.

  • 1. I would advise you use a logic analyzer(An oscilloscope would be acceptable) to catch the wave to see whether the data send out is as expected.

    2. You need to check the datasheet of ADXL335 to see whether the SPI data send out is right.

    3. Then you can know how to change the code.

  • Hi David,

    Really thank you for answering the question!

    Eason

  • I'm getting device id as E5 on receive_buffer but it is getting without going into the RX_DATA_MODE which is triggered at mastermode=RX_DATA_MODE of SPI.h and command 0x00 is not getting loaded in TransmitRegAddr which is in read function of SPI.h .

    I think SPI initialization was correct because that correct id will not receive on receive buffer if initialization was wrong. I'm sharing the code here please tell me where i'm missing.

     ********************************************************main.c****************************************************************

    #include <msp430.h>
    #include <spi.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>

    unsigned char addr[30]="";
    uint8_t x,y,z;

    void uart_config()
    {
    P2SEL0 &= ~(BIT0 | BIT1);
    P2SEL1 |= (BIT0 | BIT1); // USCI_A0 UART operation
    PM5CTL0 &= ~LOCKLPM5;
    UCA0CTLW0=UCSWRST;//eUSCI in reset mode(disabling) and this will automatically SETS the UCTXIFG and RESETS the UCRXIFG,UCRXIE,UCTXIE
    UCA0CTLW0 |=UCSSEL__SMCLK;//CLOCK is SMCLK=8MHZ
    UCA0BRW = 52;
    UCA0MCTLW |= UCOS16 | UCBRF_1 | 0x49;
    UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI
    UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt
    }

    void initSPI()
    {
    UCB1CTLW0 = UCSWRST; // **Put state machine in reset**
    UCB1CTLW0 |= UCMSB | UCSYNC | UCMST | UCSSEL__SMCLK | UCCKPL; // UCCKPH | 3-pin, 8-bit SPI Slave
    //UCB1CTLW0 |= UCMSB | UCSYNC | UCMST | UCSSEL__SMCLK ; // UCCKPH | 3-pin, 8-bit SPI Slave
    UCB1BRW = 2;
    UCB1CTLW0 &= ~UCSWRST; // **Initialize USCI state machine**
    UCB1IE |= UCRXIE; // Enable USCI0 RX interrupt
    }

    void initGPIO()
    {
    //LEDs
    COMMS_LED_DIR |= COMMS_LED_PIN;
    COMMS_LED_OUT &= ~COMMS_LED_PIN;

    // Configure SPI
    P5SEL0 |= BIT0 | BIT1 | BIT2;

    SLAVE_CS_DIR |= SLAVE_CS_PIN;
    SLAVE_CS_OUT |= SLAVE_CS_PIN;

    // Disable the GPIO power-on default high-impedance mode to activate
    // previously configured port settings
    PM5CTL0 &= ~LOCKLPM5;


    }

    void LPM1_Clock_config()
    {
    CSCTL0_H = CSKEY_H;
    CSCTL1 = DCOFSEL_6; //8MHz |DCOFSEL_0 -1MHz
    CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK; // Set SMCLK = MCLK = DCO
    CSCTL3 = DIVA_1|DIVS__1|DIVM__1;
    CSCTL0_H = 0;
    }


    int adxl_device_id()
    {
    unsigned int id;
    SPI_Master_ReadReg(CMD_TYPE_0_SLAVE,TYPE_0_LENGTH);
    id=ReceiveBuffer[0];
    return id;
    }

    void id_print(unsigned char *str)
    {
    strcpy(Data, str);
    size = strlen(Data);
    Tx_index=0;
    UCA0IE |= UCTXIE | UCTXCPTIE;
    UCA0TXBUF=Data[Tx_index];
    Tx_index++;
    __bis_SR_register(LPM0_bits|GIE);
    }

    int main(void) {
    WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

    //initClockTo16MHz();
    LPM1_Clock_config();
    initGPIO();
    initSPI();
    uart_config();

    COMMS_LED_OUT |= COMMS_LED_PIN;

    while(1)
    {
    int adxl_id;
    adxl_id=adxl_device_id();
    sprintf(addr,"ID=%x\r\n",adxl_id);// function used to convert any ddata type to string
    id_print(addr);
    UCA0IE &= ~UCTXIE;
    UCA0IE &= ~UCTXCPTIE;

    __delay_cycles(8000000);
    }
    }

    *************************************************spi.h*********************************************************************

    #include <msp430.h>
    #include <stdint.h>
    #include <stdbool.h>
    //******************************************************************************
    // Pin Config ******************************************************************
    //******************************************************************************
    volatile int Tx_index=0;
    volatile int Rx_index=0;
    volatile unsigned int Rx_key=0;
    volatile unsigned int Tx_key=0;
    int size=0;
    unsigned char Data[15]="";
    unsigned char RXData[5]="";
    #define SLAVE_CS_OUT P8OUT
    #define SLAVE_CS_DIR P8DIR
    #define SLAVE_CS_PIN BIT2

    #define SLAVE_RST_OUT P1OUT
    #define SLAVE_RST_DIR P1DIR
    #define SLAVE_RST_PIN BIT5

    #define BUTTON_DIR P5DIR
    #define BUTTON_OUT P5OUT
    #define BUTTON_REN P5REN
    #define BUTTON_PIN BIT5
    #define BUTTON_IES P5IES
    #define BUTTON_IE P5IE
    #define BUTTON_IFG P5IFG
    #define BUTTON_VECTOR PORT5_VECTOR

    #define BUTTON_LED_OUT P1OUT
    #define BUTTON_LED_DIR P1DIR
    #define BUTTON_LED_PIN BIT1

    #define COMMS_LED_OUT P1OUT
    #define COMMS_LED_DIR P1DIR
    #define COMMS_LED_PIN BIT0

    //******************************************************************************
    // Example Commands ************************************************************
    //******************************************************************************

    #define DUMMY 0xFF

    /* CMD_TYPE_X_SLAVE are example commands the master sends to the slave.
    * The slave will send example SlaveTypeX buffers in response.
    *
    * CMD_TYPE_X_MASTER are example commands the master sends to the slave.
    * The slave will initialize itself to receive MasterTypeX example buffers.
    * */
    #define CMD_TYPE_0_SLAVE 0
    #define CMD_TYPE_1_SLAVE 1
    #define CMD_TYPE_2_SLAVE 2

    #define CMD_TYPE_0_MASTER 3
    #define CMD_TYPE_1_MASTER 4
    #define CMD_TYPE_2_MASTER 5

    #define TYPE_0_LENGTH 1
    #define TYPE_1_LENGTH 2
    #define TYPE_2_LENGTH 6

    #define MAX_BUFFER_SIZE 20

    /* MasterTypeX are example buffers initialized in the master, they will be
    * sent by the master to the slave.
    * SlaveTypeX are example buffers initialized in the slave, they will be
    * sent by the slave to the master.
    * */

    uint8_t MasterType0 [TYPE_0_LENGTH] = {0x11};
    uint8_t MasterType1 [TYPE_1_LENGTH] = {8, 9};
    uint8_t MasterType2 [TYPE_2_LENGTH] = {'F', '4' , '1' , '9', '2', 'B'};

    uint8_t SlaveType2 [TYPE_2_LENGTH] = {0};
    uint8_t SlaveType1 [TYPE_1_LENGTH] = {0};
    uint8_t SlaveType0 [TYPE_0_LENGTH] = {0};


    //******************************************************************************
    // General SPI State Machine ***************************************************
    //******************************************************************************

    typedef enum SPI_ModeEnum{
    IDLE_MODE,
    TX_REG_ADDRESS_MODE,
    RX_REG_ADDRESS_MODE,
    TX_DATA_MODE,
    RX_DATA_MODE,
    TIMEOUT_MODE
    } SPI_Mode;


    /* Used to track the state of the software state machine*/
    SPI_Mode MasterMode = IDLE_MODE;

    /* The Register Address/Command to use*/
    uint8_t TransmitRegAddr = 0;

    /* ReceiveBuffer: Buffer used to receive data in the ISR
    * RXByteCtr: Number of bytes left to receive
    * ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
    * TransmitBuffer: Buffer used to transmit data in the ISR
    * TXByteCtr: Number of bytes left to transfer
    * TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
    * */
    uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t RXByteCtr = 0;
    uint8_t ReceiveIndex = 0;
    uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t TXByteCtr = 0;
    uint8_t TransmitIndex = 0;

    /* SPI Write and Read Functions */

    /* For slave device, writes the data specified in *reg_data
    *
    * reg_addr: The register or command to send to the slave.
    * Example: CMD_TYPE_0_MASTER
    * *reg_data: The buffer to write
    * Example: MasterType0
    * count: The length of *reg_data
    * Example: TYPE_0_LENGTH
    * */
    SPI_Mode SPI_Master_WriteReg(uint8_t reg_addr, uint8_t *reg_data, uint8_t count);

    /* For slave device, read the data specified in slaves reg_addr.
    * The received data is available in ReceiveBuffer
    *
    * reg_addr: The register or command to send to the slave.
    * Example: CMD_TYPE_0_SLAVE
    * count: The length of data to read
    * Example: TYPE_0_LENGTH
    * */
    SPI_Mode SPI_Master_ReadReg(uint8_t reg_addr, uint8_t count);
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
    void SendUCB1Data(uint8_t val);

    void SendUCB1Data(uint8_t val)
    {
    while (!(UCB1IFG & UCTXIFG)); // USCI_B1 TX buffer ready?
    UCB1TXBUF = val;
    }

    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
    {
    uint8_t copyIndex = 0;
    for (copyIndex = 0; copyIndex < count; copyIndex++)
    {
    dest[copyIndex] = source[copyIndex];
    }
    }


    SPI_Mode SPI_Master_WriteReg(uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
    {
    MasterMode = TX_REG_ADDRESS_MODE;
    TransmitRegAddr = reg_addr;

    //Copy register data to TransmitBuffer
    CopyArray(reg_data, TransmitBuffer, count);

    TXByteCtr = count;
    RXByteCtr = 0;
    ReceiveIndex = 0;
    TransmitIndex = 0;

    SLAVE_CS_OUT &= ~(SLAVE_CS_PIN);
    SendUCB1Data(TransmitRegAddr);

    __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts

    SLAVE_CS_OUT |= SLAVE_CS_PIN;
    return MasterMode;
    }

    SPI_Mode SPI_Master_ReadReg(uint8_t reg_addr, uint8_t count)
    {
    MasterMode = TX_REG_ADDRESS_MODE;
    TransmitRegAddr = reg_addr;//0X00,1
    RXByteCtr = count;
    TXByteCtr = 0;
    ReceiveIndex = 0;
    TransmitIndex = 0;

    SLAVE_CS_OUT &= ~(SLAVE_CS_PIN);
    SendUCB1Data(TransmitRegAddr);//0x00

    __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts

    SLAVE_CS_OUT |= SLAVE_CS_PIN;
    return MasterMode;
    }

    //******************************************************************************
    // SPI Interrupt ***************************************************************
    //******************************************************************************

    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=USCI_B1_VECTOR
    __interrupt void USCI_B1_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_B1_VECTOR))) USCI_B1_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
    uint8_t ucb1_rx_val = 0;
    switch(__even_in_range(UCB1IV, USCI_SPI_UCTXIFG))
    {
    case USCI_NONE: break;
    case USCI_SPI_UCRXIFG:
    ucb1_rx_val = UCB1RXBUF;
    UCB1IFG &= ~UCRXIFG;
    switch (MasterMode)
    {
    case TX_REG_ADDRESS_MODE:
    if (RXByteCtr)
    {
    MasterMode = RX_DATA_MODE; // Need to start receiving now
    //Send Dummy To Start
    // __delay_cycles(2000000);
    SendUCB1Data(DUMMY);
    }
    else
    {
    MasterMode = TX_DATA_MODE; // Continue to transmision with the data in Transmit Buffer
    //Send First
    SendUCB1Data(TransmitBuffer[TransmitIndex++]);
    TXByteCtr--;
    }
    break;

    case TX_DATA_MODE:
    if (TXByteCtr)
    {
    SendUCB1Data(TransmitBuffer[TransmitIndex++]);
    TXByteCtr--;
    }
    else
    {
    //Done with transmission
    MasterMode = IDLE_MODE;
    __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
    }
    break;

    case RX_DATA_MODE:
    if (RXByteCtr)
    {
    ReceiveBuffer[ReceiveIndex++] = ucb1_rx_val;
    //Transmit a dummy
    RXByteCtr--;
    }
    if (RXByteCtr == 0)
    {
    MasterMode = IDLE_MODE;
    __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
    }
    else
    {
    SendUCB1Data(DUMMY);
    }
    break;

    default:
    __no_operation();
    break;
    }
    __delay_cycles(1000);
    break;
    case USCI_SPI_UCTXIFG:
    break;
    default: break;
    }
    }


    //******************************************************************************
    // Button Port Interrupt *************************************************************
    // Interrupt occurs on button press and initiates the SPI data transfer ********
    //******************************************************************************

    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=BUTTON_VECTOR
    __interrupt void Button_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(BUTTON_VECTOR))) Button_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
    BUTTON_LED_OUT |= BUTTON_LED_PIN;
    BUTTON_IFG &= ~BUTTON_PIN; // button IFG cleared
    BUTTON_IE &= ~BUTTON_PIN;
    //Initiate
    __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
    }


    /////////////////////////////////////////////////////////UART.H///////////////////////////////////////////////////////

    #pragma vector = EUSCI_A0_VECTOR
    __interrupt void USCI_A0_ISR(void)
    {
    switch(__even_in_range(UCA0IV, USCI_UART_UCTXCPTIFG))
    {
    case USCI_NONE: break;
    case USCI_UART_UCRXIFG:
    Rx_key=0;
    RXData[Rx_index]=UCA0RXBUF;
    if((RXData[Rx_index] == '\x0d'/*'\r'*/) || (RXData[Rx_index] == '\n')||(RXData[Rx_index] == '\r'))
    {
    __bic_SR_register_on_exit(CPUOFF|GIE);
    UCA0IE &= ~UCRXIE;
    Rx_index=0;
    Rx_key=0;
    break;
    }
    Rx_index++;
    break;
    case USCI_UART_UCTXIFG:
    if(Tx_key==1)
    {
    if(Tx_index>size)
    {
    __bic_SR_register_on_exit(CPUOFF|GIE);
    UCA0IE &= ~UCTXIE;
    UCA0IE &= ~UCTXCPTIE;
    Tx_key=0;
    break;
    }
    UCA0TXBUF = Data[Tx_index];
    Tx_index++;
    Tx_key=0;
    }
    break;
    case USCI_UART_UCSTTIFG: break;
    case USCI_UART_UCTXCPTIFG:
    Tx_key=1;
    UCA0IFG|=UCTXIFG;
    break;
    default: break;
    }
    }

  • 1. Sorry, I can't understand you description clearly. Can use a logic analyzer(An oscilloscope would be acceptable) to catch the wave to see whether the data send out is as expected?

    2. I think you are the guy who is mostly familiar with the code. All we can do is to give some direction.

  • I'm getting the output through uart eventhough that data is not collected by a variable from receivebuffer. Can you tell what could be the reasons for this?

  • I just wondering can you use a logic analyzer(An oscilloscope would be acceptable) to catch the wave?

    It is really hard to just look into your code to find why your SPI don't receive anything.

**Attention** This is a public forum