2
votes

I am trying to read a SDP610 sensiron differential pressure sensor via a Texas Instruments msp430. I am having the issue of the sensor not acknowledging the command and thus, not communicating the pressure value itself. Note I have confirmed that the sensor works by hooking it up to an arduino via an opensource library and, I can see the data via this. Note my IDE is code composer. My chips is MSP430FR2311 (a launch pad breakout board).

My hardware setup is 4 wires. Vcc(3.3V), Ground(0V), SDK and SCL. The SDK and SCL lines are pulled to VCC with a 4.7Kohm resistor as per specification.

I have the following code for my MSP430 see below:

However, I do not see the response of the sensor via a logic analyser. Here is my capture. You will have to click the link. Note the top line is clock and bottom is the data. MSP430 output. The logic flow for reading the sensor from the datasheet and from the arduino code is as follows:

  • Write address of the device to the I2C line(8 bit h81)
  • Wait for slave acknowledge
  • Write command for reading (8 bit hF1)
  • Wait for slave acknowledge
  • Slave holds the master
  • Slave outputs 3 bytes (2 data one msb and 1 lsb then a check sum)
  • acknowledge

This is the datasheet for the sensor

Any tips to why the sensor is not responding.

CODE

void Read_Diff_pressure(void)
{
    int rx_byte;
    UCB0CTL1 |= UCTXSTT+ UCTR; // Generating START + I2C transmit (write)
    UCB0I2CSA = SDP610Address; // SDP610 7 bit address 0x40
    UCB0TXBUF = SDP610Read; // sending the read command 0x78
    while(!(UCB0IFG & UCTXIFG)); //wait until reg address got sent
    while( UCB0CTL1 & UCTXSTT); //wait till START condition is cleared
    UCB0CTL1 |= UCTXSTT; //generate RE-START
    UCB0I2CSA = SDP610Address; // SDP610 7 bit address 0x40
    UCB0CTL1 &=~ UCTR; //receive mode
    while( UCB0CTL1 & UCTXSTT); //wait till START condition is cleared
    rx_byte = UCB0RXBUF; //read byte
    //while(!(UCB0IFG & UCRXIFG)); //wait while the Byte is being read
    UCB0CTL1 |= UCTXNACK; //generate a NACK
    UCB0CTL1 |= UCTXSTP; //generate stop condition
    while(UCB0CTL1 & UCTXSTP); //wait till stop condition got sent```

    Pressure_result = rx_byte;
}
void InitI2C_diff(void)
{

    PAOUT |= I2C_SCL_PIN|I2C_SDA_PIN;//P1.2(SDA) - P1.3(SCL) as per silk screen defined in a header
    PADIR |= I2C_SCL_PIN|I2C_SDA_PIN;
    PASEL0 |= (I2C_SCL_PIN|I2C_SDA_PIN);              // configure I2C pins (device specific)
    UCB0CTLW0 |= UCSWRST;                             // put eUSCI_B in reset state
    UCB0CTLW0 |= UCMODE_3 | UCSYNC | UCMST;           // I2C master mode, SMCL
    UCB0CTL1 = UCSSEL_2 + UCSWRST; //use SMCLK + still reset
    UCB0BR0 = 10; // default SMCLK 1M/10 = 100KHz
    UCB0BR1 = 0; //
    UCB0I2CSA =  SDP610Address;                       //The address of the device
    UCB0CTLW0 &= ~UCSWRST;                            // eUSCI_B in operational state

    //UCB0BRW = 64;                                     // baudrate = SMCLK / 64
}
int main(void)
{
    InitI2C_diff();//Init the i2c


    while (1) { // Mainloop
        Read_Diff_pressure();
        delay(1000);//1 Second delay before re looping
    }
}
2
You are going to have to debug this step by step by watch I2C registers in the debugger along with the signals on a scope. Unrelated to your problem: given that MSP430 is 16 bit, using 16 bit signed int for bitwise operations is to ask for problems.Lundin
Ok so ill change my ints to uint8_t. But what signals should I watch in the debugger do you mean the USCI register variables and making sure that they are set correctly?Thomas Morris
You are unlikely to find the bug just by staring at the code, so you have to go through every register. Basically: "have I understood the use of this register correctly" (manual -> programmer), then "does the code do what I want it to do" (programmer -> generated program) and then "does the hardware behave accordingly" (generated program -> hardware).Lundin
Whats the best method for doing this? I presume going into the debugger and stepping through the code. I have been stepping though it and found a hold on while(!(UCB0IFG & UCRXIFG)); Therefore, I presume this is never true. Meaning the byte is never read correctly.Thomas Morris
Clear LOCKLPM5.CL.

2 Answers

2
votes

A few parts were missing compared to an old Project implementation of mine (VCNL3020 + MSP430).

For example: set the 7-bit addressing mode, single-master environment, I2C Master, synchronous mode,..Maybe I have overlooked it

Does the sensor need itself an init?

The Init Part of the I2C only looked like this:

void I2CInit( void )
{
    P1SEL |= BIT6 + BIT7;                    // Assign I2C pins to USCI_B0
    P1SEL2|= BIT6 + BIT7;
    UCB0CTL1 |= UCSWRST;                    // Enable SW reset
    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;    // 7-bit addressing, single-master environment, I2C Master, synchronous mode
    UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
    UCB0BR0 = 16;                    // fSCL = SMCLK/UCB0BR1
    UCB0BR1 = 0;
    UCB0I2CIE |= UCNACKIE;                    // Enable not-acknowledge interrupt
    UCB0I2CSA=slave_adress;
    UCB0CTL1 &= ~UCSWRST;                    // Clear SW reset, resume operation
    IE2 |= UCB0TXIE + UCB0RXIE;                // Enable TX&RX interrupts

}

To not make it unnecessary complicated, you could check my implementation on github and see if it helps Github Link I2C MSP430 Main

I hope this helps a bit- have fun!

0
votes

I'm not sure what your hardware looks like, but your I2C pull-ups sound too large.I know of lot of app notes talk about about 4.7K, but I'd look at the rise time of the lines with an oscilloscope. If you don't have access to a scope, I'd use 1K or 2 K and see what happens.