Hello,
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()
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
[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.