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.

SIMPLELINK-CC2640R2-SDK: Getting 0 values when reading I2C LSM303DLHC Sensor using Sensor Controller

Part Number: SIMPLELINK-CC2640R2-SDK

Hi,

 This is continuation of that post "SIMPLELINK-CC2640R2-SDK: v2.30: Not able to pass Sensor Controller LSM303AGR Accelerometer + Magnetometer data to Main Application?". As per your request I have taken I2C Logic Analyzer Capture. I have I2C Logic Analyzer Capture of using TI-RTOS and Sensor Controller for comparison. I have attached the I2C Logic Analyzer Capture files and you can open the files using Sigrok Pulseview. You just need to set I2C Protocol, SCL - D0, SDA - D1. Due to this problem we decided already not to use Sensor Controller to read the I2C Sensor. If there is a quick fix to this that would be nice. If not and the fix will take some time, maybe I can use that fix at the next project.

Here is I2C Logic Analyzer Capture of LSM303DLHC Accelerometer using Simple Peripheral TI-RTOS. I do not see any problem.

Reading LSM303DLHC_OUT_X_L_A(0x28)


Reading LSM303DLHC_OUT_X_H_A(0x29)


Here is I2C Logic Analyzer Capture of LSM303DLHC Accelerometer using Sensor Controller Task Testing. I see the 0 I2C Data Read. I also see wrong clock timing.

Sigrok Pulseview.rar

  • Hi Markel,

    I'm taking a look at the logic traces you've provided. I'll come back when I've reviewed them.

    Meanwhile, have you tried making a minimal application, without the Simple Peripheral part, which just starts the SC task that is able to reproduce the issue? This would be great to verify and eliminate possible issues such as PIN collisions, etc.
  • Hi Severin,

    Sorry, I edited the original post as you can see in red above.. The second set of pictures are as below. I just use the Sensor Controller Task Testing, then capture the I2C signals using Logic Analyzer

    " I2C Logic Analyzer Capture of LSM303DLHC Accelerometer using Sensor Controller Task Testing. I see the 0 I2C Data Read. I also see wrong clock timing"

    -kel
  • I've reviewed your traces and have the following comments:

    * Your SC code doesn't seem to be implemented correctly. You are calling i2cStop() conditionally if the i2c.status is OK. This is wrong. You must always call i2cStop() after calling i2cStart(), regardless of the i2c.status. Please refer to the I2C code examples in the Help Viewer.
    * You are ACK-ing the last I2C RX when you should be NACK-ing. Again, please refer to the I2C code examples in the Help Viewer.
    * Comparing the working TI-RTOS exchange vs. the SC, each I2C transfer is pretty much back-to-back on the SC compared to TI-RTOS which has some delays. It could be that the sensor is not quick enough to process the I2C transaction before writing back to the SC. Maybe try to add a small delay between each I2C transaction?
  • Here is my Sensor Controller Code

    i2cStart();
    // Set LSM303DLHC Accelerometer I2C Slave Address
    i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_WRITE);
    // Initialize the LSM303DLHC Accelerometer
    // X, Y and Z-axis enable, power on mode, o/p data rate 10 Hz(0x27)
    i2cTx(LSM303DLHC_CTRL_REG1_A);
    i2cTx(0x27);
    i2cStop();
    
    i2cStart();
    // Set LSM303DLHC Accelerometer I2C Slave Address
    i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_WRITE);
    // Continous Mode.
    // Full scale +/- 2g
    i2cTx(LSM303DLHC_CTRL_REG4_A);
    i2cTx(0x00);
    i2cStop();
    
    // Read the accelerometer
    i2cStart();
    i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_WRITE);
    i2cTx(LSM303DLHC_OUT_X_L_A);
    
    // If successful ...
    if (state.i2cStatus == 0x0000) {
        // Read the result
        i2cRepeatedStart();
        i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_READ);
        i2cRxAck(output.accbuffer[0]);
        i2cStop();
    }
    
    i2cStart();
    i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_WRITE);
    i2cTx(LSM303DLHC_OUT_X_H_A);
    
    // If successful ...
    if (state.i2cStatus == 0x0000) {
        // Read the result
        i2cRepeatedStart();
        i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_READ);
        i2cRxAck(output.accbuffer[1]);
        i2cStop();
    }
    
    i2cStart();
    i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_WRITE);
    i2cTx(LSM303DLHC_OUT_Y_L_A);
    
    // If successful ...
    if (state.i2cStatus == 0x0000) {
        // Read the result
        i2cRepeatedStart();
        i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_READ);
        i2cRxAck(output.accbuffer[2]);
        i2cStop();
    }
    
    i2cStart();
    i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_WRITE);
    i2cTx(LSM303DLHC_OUT_Y_H_A);
    
    // If successful ...
    if (state.i2cStatus == 0x0000) {
        // Read the result
        i2cRepeatedStart();
        i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_READ);
        i2cRxAck(output.accbuffer[3]);
        i2cStop();
    }
    
    i2cStart();
    i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_WRITE);
    i2cTx(LSM303DLHC_OUT_Z_L_A);
    
    // If successful ...
    if (state.i2cStatus == 0x0000) {
        // Read the result
        i2cRepeatedStart();
        i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_READ);
        i2cRxAck(output.accbuffer[4]);
        i2cStop();
    }
    
    i2cStart();
    i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_WRITE);
    i2cTx(LSM303DLHC_OUT_Z_H_A);
    
    // If successful ...
    if (state.i2cStatus == 0x0000) {
        // Read the result
        i2cRepeatedStart();
        i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_READ);
        i2cRxAck(output.accbuffer[5]);
        i2cStop();
    }
    
    output.accX = ((output.accbuffer[1] << 8) | output.accbuffer[0]);
    output.accY = ((output.accbuffer[3] << 8) | output.accbuffer[2]);
    output.accZ = ((output.accbuffer[5] << 8) | output.accbuffer[4]);
    
    // Signalize that the task has been completed
    fwGenAlertInterrupt();

    Actually this is based from the Sensor Controller Help I2C Master Examples, here below. When I read LSM303DLHC_OUT_X_H_A, the data is only 1 byte. If I implement i2cRxAck(output.x);, i2cRxAck(output.y); i2cRxNack(output.z);. Is for 3 bytes.

    // Accelerometer (I2C address 0x86+W): Write X register address (0x04)
    i2cStart();
    i2cTx(0x86 | I2C_OP_WRITE);
    i2cTx(0x04);
    
    // If successful ...
    if (state.i2cStatus == 0x0000) {
    
        // Accelerometer (I2C address 0x86+R): Read X/Y/Z register values
        i2cRepeatedStart();
        i2cTx(0x86 | I2C_OP_READ);
        i2cRxAck(output.x);
        i2cRxAck(output.y);
        i2cRxNack(output.z);
    }
    i2cStop();

  • Hi Severin,

        I updated the code this below and now I am getting good I2C Logic Analyzer Capture.

    i2cStart();
    // Set LSM303DLHC Accelerometer I2C Slave Address
    i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_WRITE);
    // Initialize the LSM303DLHC Accelerometer
    // X, Y and Z-axis enable, power on mode, o/p data rate 10 Hz(0x27)
    i2cTx(LSM303DLHC_CTRL_REG1_A);
    i2cTx(0x27);
    i2cStop();
    
    i2cStart();
    // Set LSM303DLHC Accelerometer I2C Slave Address
    i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_WRITE);
    // Continous Mode.
    // Full scale +/- 2g
    i2cTx(LSM303DLHC_CTRL_REG4_A);
    i2cTx(0x00);
    i2cStop();
    
    // Read the accelerometer
    i2cStart();
    i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_WRITE);
    i2cTx(LSM303DLHC_OUT_X_L_A);
    
    U16 dummy = 0;
    
    // If successful ...
    if (state.i2cStatus == 0x0000) {
        // Read the result
        i2cRepeatedStart();
        i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_READ);
        i2cRxAck(output.accbuffer[0]);
        i2cRxNack(dummy);    
    }
    i2cStop();
    
    i2cStart();
    i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_WRITE);
    i2cTx(LSM303DLHC_OUT_X_H_A);
    
    // If successful ...
    if (state.i2cStatus == 0x0000) {
        // Read the result
        i2cRepeatedStart();
        i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_READ);
        i2cRxAck(output.accbuffer[1]);
        i2cRxNack(dummy);    
    }
    i2cStop();
    
    i2cStart();
    i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_WRITE);
    i2cTx(LSM303DLHC_OUT_Y_L_A);
    
    // If successful ...
    if (state.i2cStatus == 0x0000) {
        // Read the result
        i2cRepeatedStart();
        i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_READ);
        i2cRxAck(output.accbuffer[2]);
        i2cRxNack(dummy);    
    }
    i2cStop();
    
    i2cStart();
    i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_WRITE);
    i2cTx(LSM303DLHC_OUT_Y_H_A);
    
    // If successful ...
    if (state.i2cStatus == 0x0000) {
        // Read the result
        i2cRepeatedStart();
        i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_READ);
        i2cRxAck(output.accbuffer[3]);
        i2cRxNack(dummy);    
    }
    i2cStop();
    
    i2cStart();
    i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_WRITE);
    i2cTx(LSM303DLHC_OUT_Z_L_A);
    
    // If successful ...
    if (state.i2cStatus == 0x0000) {
        // Read the result
        i2cRepeatedStart();
        i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_READ);
        i2cRxAck(output.accbuffer[4]);
        i2cRxNack(dummy);    
    }
    i2cStop();
    
    i2cStart();
    i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_WRITE);
    i2cTx(LSM303DLHC_OUT_Z_H_A);
    
    // If successful ...
    if (state.i2cStatus == 0x0000) {
        // Read the result
        i2cRepeatedStart();
        i2cTx((LSM303DLHC_ACC_I2C_ADDRESS << 1) | I2C_OP_READ);
        i2cRxAck(output.accbuffer[5]);
        i2cRxNack(dummy);    
    }
    i2cStop();
    
    output.accX = ((output.accbuffer[1] << 8) | output.accbuffer[0]);
    output.accY = ((output.accbuffer[3] << 8) | output.accbuffer[2]);
    output.accZ = ((output.accbuffer[5] << 8) | output.accbuffer[4]);
    
    // Signalize that the task has been completed
    fwGenAlertInterrupt();

    -kel