i2c_transfer() reads all zeros

Hello,

I am trying to read data from LS2DE12 accelerometer MEMS chip via I2C bus and I am seeing only zeros for all 3 axes.
I can write to the various registers successfully and read back their content to check the write was successful using this function.

static int32_t lis2de12_readb(uint8_t add, uint8_t *b)
{
    struct i2c_msg msgs[2];

    /* Send the address to read from */
    msgs[0].buf = &add;
    msgs[0].len = 1U;
    msgs[0].flags = I2C_MSG_WRITE | I2C_MSG_STOP;

    /* Read from device. STOP after this. */
    msgs[1].buf = b;
    msgs[1].len = 1U;
    msgs[1].flags = I2C_MSG_READ | I2C_MSG_STOP;

    return i2c_transfer(accelerometer.handle, &msgs[0], 2, LIS2DE12_I2C_ADD);
}

The above is called at initialisation to configure the various registers as shown in the snippets of code below, and all seems to be working ok...

accelerometer_t *lis2de12_initialise(void *dev)
{
    accelerometer.handle = dev;
    uint8_t b,d[8];

    accelerometer.moved = false;
    lis2de12_readb( LIS2DE12_WHO_AM_I,&d[0] );
    if ( d[0] != LIS2DE12_ID )
    {
        LOG_INF( "Fail LIS2" );
        return( NULL );
    }
    else
    {
        LOG_DBG( "OK LIS2" );
        accelerometer.present = true;

        lis2de12_writeb( LIS2DE12_CTRL_REG1, 0x2f ); //0x1f);
        lis2de12_readb( LIS2DE12_CTRL_REG1, &d[0] );
        if ( d[0] != 0x2f )
        {
            LOG_INF( "Fail LIS2" );
            return( NULL );
        }

        lis2de12_writeb( LIS2DE12_CTRL_REG4, 0x80 );
        lis2de12_readb( LIS2DE12_CTRL_REG4, &d[1] );
        if (d[1] != 0x80)
        {
            LOG_INF( "Fail LIS2" );
            return( NULL );
        }

        //High pass filter enabled
//      lis2de12_writeb(LIS2DE12_CTRL_REG2,0x40);

        // Normal mode + HPF cutoff freq 0.02 Hz @1 Hz ODR + Enable the internal filter
        lis2de12_writeb( LIS2DE12_CTRL_REG2,0xB8 );
        lis2de12_readb( LIS2DE12_CTRL_REG2,&d[2] );
        if ( d[2] != 0xB8 )
        {
            LOG_INF( "Fail LIS2" );
            return( NULL );
        }

        // Enable FIFO operation
        lis2de12_writeb( LIS2DE12_CTRL_REG5, 0x40 );
        lis2de12_readb( LIS2DE12_CTRL_REG5, &d[3] );
        if (d[3] != 0x40)
        {
            LOG_INF( "Fail LIS2" );
            return( NULL );
        }

        // Enable FIFO Mode
        lis2de12_writeb( LIS2DE12_FIFO_CTRL_REG, 0x40 );
        lis2de12_readb( LIS2DE12_FIFO_CTRL_REG, &d[4] );
        if (d[4] != 0x40)
        {
            LOG_INF( "Fail LIS2" );
            return( NULL );
        }

        LOG_DBG( "C1 %x:C4 %x:C2 %x:C5 %x:FIFO %x:",d[0],d[1],d[2],d[3],d[4] );
        k_sleep(K_MSEC(20));

        return( &accelerometer );
    }

}//lis2de12_initialise()

However, when I read the x,y,z data I am getting all zeros.
The function that reads the x,y,z data is shown below,

static int32_t lis2de12_read_fifo(uint8_t add, uint8_t *b)
{
    struct i2c_msg msgs[2];

    /* Send the address to read from */
    msgs[0].buf = &add;
    msgs[0].len = 1U;
    msgs[0].flags = I2C_MSG_WRITE | I2C_MSG_STOP;

    /* Read from device. STOP after this. */
    msgs[1].buf = b;
    msgs[1].len = 6U;
    msgs[1].flags = I2C_MSG_READ | I2C_MSG_STOP;

    return i2c_transfer(accelerometer.handle, &msgs[0], 2, LIS2DE12_I2C_ADD);
}

The above function lis2de12_read_fifo() is called from the function shown below which itself gets called from an executive loop running in a forever loop.

typedef struct accel{
            void        * handle;
            int16_t     x;
            int16_t     y;
            int16_t     z;
            uint32_t    vector;
            uint32_t    oldvector;
            uint8_t     present:1;
            uint8_t     moved:1;
            uint32_t    LastMovementTime;

        } accelerometer_t;

accelerometer_t accelerometer;

boolean_t lis2de12_getxyz(void)
{
    uint8_t     status;
    uint8_t     d[6],i;
    union {
            uint8_t  b[2];
            int16_t  i;
          } iandb;

    accelerometer.vector = accelerometer.oldvector;

    if (accelerometer.present)
    {
        lis2de12_readb( LIS2DE12_STATUS_REG, &status );
        if ( status & ZYX_DATA_READY )
        {
#if 0
            for ( i = 0; i < 6; i++ )
            {
                if ( lis2de12_readb( LIS2DE12_FIFO_READ_START + i, &d[i] ) != 0 )
                {
                    break;
                }
            }
            if ( i == 6 )
#endif //#if 0

            if ( lis2de12_read_fifo( LIS2DE12_FIFO_READ_START, d ) != 0 )
            {
                iandb.b[1] = d[0];
                iandb.b[0] = d[1];
                accelerometer.x = iandb.i;

                iandb.b[1] = d[2];
                iandb.b[0] = d[3];
                accelerometer.y = iandb.i;

                iandb.b[1] = d[4];
                iandb.b[0] = d[5];
                accelerometer.z = iandb.i;

                accelerometer.vector = (uint32_t)accelerometer.x * (uint32_t)accelerometer.x +
                                       (uint32_t)accelerometer.y * (uint32_t)accelerometer.y +
                                       (uint32_t)accelerometer.z * (uint32_t)accelerometer.z;
                
                printf( "[%u s] ", timer_GetOneSecondTime() ); //DBG
                printf( "STATUS_REG = 0x%02x acc_x = 0x%04x acc_y = 0x%04x acc_z = 0x%04x v = %d acc_oldv = %d\n",
                        status,
                        accelerometer.x, accelerometer.y, accelerometer.z,
                        accelerometer.vector,
                        accelerometer.oldvector                             );
            }
        }
        return true;
    }
    else
    {
        return false;
    }

}//lis2de12_getxyz()
 

Here is a sample of the debug output

[14 s] STATUS_REG = 0xff acc_x = 0x0000 acc_y = 0x0000 acc_z = 0x0000 v = 0 acc_oldv = 0
[15 s] STATUS_REG = 0xff acc_x = 0x0000 acc_y = 0x0000 acc_z = 0x0000 v = 0 acc_oldv = 0
[15 s] STATUS_REG = 0xff acc_x = 0x0000 acc_y = 0x0000 acc_z = 0x0000 v = 0 acc_oldv = 0
[15 s] STATUS_REG = 0xff acc_x = 0x0000 acc_y = 0x0000 acc_z = 0x0000 v = 0 acc_oldv = 0
[15 s] STATUS_REG = 0xff acc_x = 0x0000 acc_y = 0x0000 acc_z = 0x0000 v = 0 acc_oldv = 0
[15 s] STATUS_REG = 0xff acc_x = 0x0000 acc_y = 0x0000 acc_z = 0x0000 v = 0 acc_oldv = 0
[15 s] STATUS_REG = 0xff acc_x = 0x0000 acc_y = 0x0000 acc_z = 0x0000 v = 0 acc_oldv = 0

It must be something to do with the way I am reading the FIFO content because when I read individual registers content all seems to be OK.
Please advise.
Kind regards
Mohamed
Parents Reply Children
No Data
Related