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.

CCS/MSP430FR2355: LMP90100 sensor AFE + SPI

Part Number: MSP430FR2355
Other Parts Discussed in Thread: LMP90100,

Tool/software: Code Composer Studio

Hi everyone,

Could someone please help me?

I want to connect MSP430FR2355 with LMP90100 by SPI interface using the "Demo Application01 for MSP430/LMP90100 Interface Code Library v1.0" code. I'm trying to write 0x83 value to 0x11 register but MISO returns 0x00 all the time. I know that I'm missing something but I don't know what it is. 

Connections:  3.3V -------------------------------> VDD3P3 (JP12.13)

                       GND ------------------------------> GND (JP12.2)

                       GND ------------------------------> GND (J8)

                       UCA0CLK (P1.5) --------------> SCLK (J8)

                       UCA0SOMI (P1.6) ------------> SDO_DRDYB (J8)

                       UCA0SIMO (P1.7) ------------> SDI (J8)

                       CS (P2.0) ------------------------> CSB (J8)

                       P2.2 -------------------------------> D6_DRDYB (JP8)

Code:

#include <msp430.h>
#include <stdint.h>

#define LMP90100_URA_END (0xFF)
#define LMP90100_URA_MASK (0x70)
#define LMP90100_LRA_MASK (0x0F)
#define LMP90100_READ_BIT (0x80)
#define LMP90100_WRITE_BIT (0x00)
#define LMP90100_SIZE_1B (0x00)

#define LMP90100_INSTRUCTION_BYTE1_WRITE               (0x10)

#define TI_LMP90100_SPI_DRDYBCN_REG_VALUE              (0x83)             /* Enable DRDYB on D6, bits 0 & 1 must be 1, others default */

#define TI_LMP90100_SPI_DRDYBCN_REG                    (0x11)             /* SPI Data Ready Bar Control */

uint8_t prev_URA;
uint8_t reg_write_data, reg_read_data;
void TI_LMP90100_WriteRegSettings(uint8_t *); // Configure LMP90100 registers
uint8_t addr, i;

//------------------------------------------------------------------------------
// void TI_LMP90100_SPIWriteReg(uint8_t addr, uint8_t value, uint8_t *pURA)
//
// DESCRIPTION:
// Writes "value" to a single configuration register at address "addr". If
// "addr" lies within the same segment as "*pURA", it takes 1 less transaction
// to write the value.
//------------------------------------------------------------------------------


void TI_LMP90100_SPIWriteReg(uint8_t addr, uint8_t value, uint8_t *pURA)
{
uint8_t new_URA, inst;

new_URA = (addr & LMP90100_URA_MASK)>>4;                                                               // extract upper register address

P2OUT &= ~BIT0;                                                                                                                   // /CS enable

if (*pURA != new_URA)                                                                                                           // if new and previous URA not same, add transaction 1
{
inst = LMP90100_INSTRUCTION_BYTE1_WRITE;                                                               // Transaction-1

while (!(UCA0IFG&UCTXIFG));                                                                                               // Wait for TXBUF ready
UCA0TXBUF = inst;                                                                                                                 // Send instruction

while (!(UCA0IFG&UCTXIFG));                                                                                               // Wait for TXBUF ready
UCA0TXBUF = new_URA;                                                                                                      // Send upper register address

*pURA = new_URA;                                                                                                                 // save new URA

}

inst = LMP90100_WRITE_BIT | LMP90100_SIZE_1B |(addr & LMP90100_LRA_MASK);     // lower register address
while (!(UCA0IFG&UCTXIFG));                                                                                               // Wait for TXBUF ready
UCA0TXBUF = inst;                                                                                                                // Send lower register address

while (!(UCA0IFG&UCTXIFG)); // Wait for TXBUF ready
UCA0TXBUF = value;                                                                                                             // Send data value

while (UCA0STATW & UCBUSY);                                                                                          // Wait for TX complete
P2OUT |= BIT0;                                                                                                                      // /CS disable

}

//------------------------------------------------------------------------------
// uint8_t TI_LMP90100_SPIReadReg(uint8_t addr, unit8_t *pURA)
//
// DESCRIPTION:
// Reads a single configuration register at address "addr" and returns the
// value read. If "addr" lies within the same segment as "*pURA", it takes 1
// less transaction to read the value.
//------------------------------------------------------------------------------
uint8_t TI_LMP90100_SPIReadReg(uint8_t addr, uint8_t *pURA)
{
uint8_t x, new_URA, inst;

new_URA = (addr & LMP90100_URA_MASK)>>4;                 // extract upper register address

P2OUT &= ~BIT0;                                                                    // /CS enable

if (*pURA != new_URA)                                                           // if new and previous URA not same, add transaction 1
{
inst = LMP90100_INSTRUCTION_BYTE1_WRITE;               // Transaction-1

while (!(UCA0IFG&UCTXIFG));                                               // Wait for TXBUF ready
UCA0TXBUF = inst;                                                                // Send instruction

while (!(UCA0IFG&UCTXIFG));                                              // Wait for TXBUF ready
UCA0TXBUF = new_URA;                                                     // Send upper register address

*pURA = new_URA;                                                               // save new URA

}

inst = LMP90100_WRITE_BIT | LMP90100_SIZE_1B | (addr & LMP90100_LRA_MASK);      // Transaction-2

while (!(UCA0IFG&UCTXIFG));             // Wait for TXBUF ready
UCA0TXBUF = inst;                               // Send lower register address

while (!(UCA0IFG&UCTXIFG));             // Wait for TXBUF ready
UCA0TXBUF = 0;                                  // Dummy write so we can read data

while (UCA0STATW & UCBUSY);         // Wait for TX complete
while (!(UCA0IFG&UCRXIFG));
x = UCA0RXBUF;                                  // Read data

P2OUT |= BIT0;                                    // /CS disable

return x;
}

void LMP90100_SPISetup(void)
{
P2OUT |= BIT0;
P2DIR |= BIT0;                                     // /CS disable

UCA0CTLW0 |= UCSWRST;               // **Disable USCI state machine**
UCA0CTLW0 |= UCMST|UCSYNC|UCCKPL|UCSTEM|UCMSB|UCMODE_2; 
UCA0CTLW0 |= UCSSEL_2;             // SMCLK
UCA0BRW = 0x10;                            // UCLK/16
UCA0MCTLW = 0;
UCA0IE |= UCRXIE;
UCA0IE |= UCTXIE;


P1SEL0 |= BIT7 | BIT6;                      // SIMO P1.7, SOMI P1.6

P1SEL0 |= BIT5;                                 // CLK P1.5
// SPI option select
P1DIR |= BIT7 | BIT5;                         // SPI TXD out direction


UCA0CTLW0 &= ~UCSWRST;           // **Initialize USCI state machine**


}


int main(void)
{
WDTCTL = WDTPW | WDTHOLD;                                                                                                             // stop watchdog timer
PM5CTL0 &= ~LOCKLPM5;                                                                                                                       // Disable the GPIO power-on default high-impedance mode


P1OUT |= BIT0;                                                                                                                                           // Set LED ON
P1DIR |= BIT0;                                                                                                                                            // Set pin direction is output

LMP90100_SPISetup();                                                                                                                              // Initilaize MSP430 SPI Block
prev_URA = LMP90100_URA_END;                                                                                                          // Initialize prev_URA to invalid segment

reg_write_data = TI_LMP90100_SPI_DRDYBCN_REG_VALUE;                                                              // value to write
TI_LMP90100_SPIWriteReg(TI_LMP90100_SPI_DRDYBCN_REG, reg_write_data, &prev_URA);         // Write to SPI_DRDYBCN register
reg_read_data = TI_LMP90100_SPIReadReg(TI_LMP90100_SPI_DRDYBCN_REG, &prev_URA);       // Read back the value written

// test if write/read values match
if (reg_write_data == reg_read_data)
{
while (1)                                                          // no error: blink LED continuously
{
__delay_cycles(250000);
__delay_cycles(250000);
P1OUT ^= BIT0;
}

} else
{
P1OUT &= ~BIT0;                                          // error: Set LED OFF
}
__bis_SR_register(LPM0_bits + GIE);          // Enter LPM0, enable interrupts
__no_operation();                                          // For debugger

}

Thanks,

Mikel

                      

  • The data sheet (SNSAS510S) Sec. 9.5.6 says Transactions are framed by CSB transitions, and Sec. 9.5.4 refers to INST1 and INST2 as separate Transactions. Have you tried wiggling CSB around each of those separately?
    --------------------------------------
    Unsolicited: Since you're driving CSB as a GPIO, you're really doing 3-wire (UCMODE=0, UCSTEM=0). Even if you connected UCASTE (P1SEL), UCSTEM=1 wouldn't do what you want. I suggest you use UCMODE_0 with UCSTEM=0; I can't say that it's causing trouble, but it might be prudent anyway.
  • Sorry, what do you mean with "Have you tried wiggling CSB around each of those separately"? 

    Okay I will try with UCMODE_0 with UCSTEM=0. Thank you for the advice!

  • Do you mean something like this?

    ----------------------------------------------------------------------------------------------------------------------------------------------

    void TI_LMP90100_SPIWriteReg(uint8_t addr, uint8_t value, uint8_t *pURA)
    {
    uint8_t new_URA, inst;

    new_URA = (addr & LMP90100_URA_MASK)>>4; // extract upper register address

    P2OUT &= ~BIT0; // /CS enable

    if (*pURA != new_URA) // if new and previous URA not same, add transaction 1
    {
    inst = LMP90100_INSTRUCTION_BYTE1_WRITE; // Transaction-1

    while (!(UCA0IFG&UCTXIFG)); // Wait for TXBUF ready
    UCA0TXBUF = inst; // Send instruction

    while (!(UCA0IFG&UCTXIFG)); // Wait for TXBUF ready
    UCA0TXBUF = new_URA; // Send upper register address

    *pURA = new_URA; // save new URA

    }
    P2OUT |= BIT0; // /CS disable <---------------------- THIS


    P2OUT &= ~BIT0; // /CS enable <---------------------- AND THIS

    inst = LMP90100_WRITE_BIT | LMP90100_SIZE_1B |(addr & LMP90100_LRA_MASK); // lower register address
    while (!(UCA0IFG&UCTXIFG)); // Wait for TXBUF ready
    UCA0TXBUF = inst; // Send lower register address

    while (!(UCA0IFG&UCTXIFG)); // Wait for TXBUF ready
    UCA0TXBUF = value; // Send data value

    while (UCA0STATW & UCBUSY); // Wait for TX complete

    P2OUT |= BIT0; // /CS disable

    }
  • Hi, I just resolved the problem summing dummy byte after write instructions and also removing dummy after transaction 2.
    Here the code:

    ------------------------------------------------------------------------------------------------------------
    void TI_LMP90100_SPIWriteReg(uint8_t addr, uint8_t value, uint8_t *pURA)
    {

    new_URA = (addr & LMP90100_URA_MASK)>>4; // extract upper register address

    // P2OUT &= ~BIT0; // /CS enable

    if (*pURA != new_URA) // if new and previous URA not same, add transaction 1
    {
    inst = LMP90100_INSTRUCTION_BYTE1_WRITE; // Transaction-1

    while (!(UCA0IFG&UCTXIFG)); // Wait for TXBUF ready
    UCA0TXBUF = inst; // Send instruction

    while (!(UCA0IFG&UCTXIFG)); // Wait for TXBUF ready
    UCA0TXBUF = 0;

    while (!(UCA0IFG&UCTXIFG)); // Wait for TXBUF ready
    UCA0TXBUF = new_URA; // Send upper register address

    *pURA = new_URA; // save new URA

    }
    // P2OUT |= BIT0; // /CS disable

    // P2OUT &= ~BIT0; // /CS enable

    inst = LMP90100_WRITE_BIT | LMP90100_SIZE_1B |(addr & LMP90100_LRA_MASK); // lower register address
    while (!(UCA0IFG&UCTXIFG)); // Wait for TXBUF ready
    UCA0TXBUF = inst; // Send lower register address

    while (!(UCA0IFG&UCTXIFG)); // Wait for TXBUF ready
    UCA0TXBUF = value; // Send data value

    while (UCA0STATW & UCBUSY); // Wait for TX complete

    // P2OUT |= BIT0; // /CS disable

    }

    //------------------------------------------------------------------------------
    // uint8_t TI_LMP90100_SPIReadReg(uint8_t addr, unit8_t *pURA)
    //
    // DESCRIPTION:
    // Reads a single configuration register at address "addr" and returns the
    // value read. If "addr" lies within the same segment as "*pURA", it takes 1
    // less transaction to read the value.
    //------------------------------------------------------------------------------
    uint8_t TI_LMP90100_SPIReadReg(uint8_t addr, uint8_t *pURA)
    {

    new_URA = (addr & LMP90100_URA_MASK)>>4; // extract upper register address

    // P2OUT &= ~BIT0; // /CS enable

    if (*pURA != new_URA) // if new and previous URA not same, add transaction 1
    {
    inst = LMP90100_INSTRUCTION_BYTE1_WRITE; // Transaction-1

    while (!(UCA0IFG&UCTXIFG)); // Wait for TXBUF ready
    UCA0TXBUF = inst; // Send instruction

    while (!(UCA0IFG&UCTXIFG)); // Wait for TXBUF ready
    UCA0TXBUF = 0;

    while (!(UCA0IFG&UCTXIFG)); // Wait for TXBUF ready
    UCA0TXBUF = new_URA; // Send upper register address

    *pURA = new_URA; // save new URA

    }
    // P2OUT |= BIT0; // /CS disable

    // P2OUT &= ~BIT0; // /CS enable

    inst = LMP90100_WRITE_BIT | LMP90100_SIZE_1B | (addr & LMP90100_LRA_MASK); // Transaction-2

    while (!(UCA0IFG&UCTXIFG)); // Wait for TXBUF ready
    UCA0TXBUF = inst; // Send lower register address

    // while (!(UCA0IFG&UCTXIFG)); // Wait for TXBUF ready
    // UCA0TXBUF = 0; // Dummy write so we can read data

    while (UCA0STATW & UCBUSY); // Wait for TX complete

    x = UCA0RXBUF; // Read data

    // P2OUT |= BIT0; // /CS disable

    return x;
    }

    -------------------------------------------------------------------------------------------------------------------------------------

    Regards,

    Mikel
  • Evidently CSB isn't needed at all. (That Wasn't going to be my next guess (:-)).) I'm glad you got it working.
  • Hi Bruce,
    It worked for a moment, but I'm stuck again hahaha.

    Edited:

    Well, sometimes it works and sometimes it does not. I don't know why, it's turning me crazy hahaha.

  • It seems like sometimes the UCA0RXBUF doesn't receive 0x83 value. Why could this be happening?
  • As I read data sheet (SNAS510S) Fig 60, Transaction-1 (INST1) is only two bytes, but you're sending three bytes. I suspect the third byte is being interpreted as the first byte of Transaction-2.

    Similarly, I don't see how you'll get the read-data byte from Transaction-2 without sending a dummy byte. I suspect you sometimes get the right thing "by accident" due to the mis-count in Transaction-1.
  • I tried exactly with the same configuration as the datasheet but it didn't work. That's why I changed the code on both transactions. Now I'm trying different configurations and also changing "LMP90100_SIZE_1B" with "LMP90100_SIZE_2B" or "LMP90100_SIZE_3B". I'm getting some different values in reg_read_data but are not correct. Let's see if I get the correct configuration.
  • Hi Mikel,

    Haven’t heard from you for long time, so I’m assuming you were able to resolve your issue. If this isn’t the case, please click the "This did NOT resolve my issue" button and reply to this thread with more information. If this thread locks, please click the "Ask a related question" button and in the new thread describe the current status of your issue and any additional details you may have to assist us in helping to solve your issues.

**Attention** This is a public forum