2019-02-15 04:23 AM
I'm using the STEVAL-MKI153V1 evalulation board together with a Nucleo F443RE board and the STM reference driver implementation from github.
The code is basically the read_simple.c example provided by STM adapted to mbed.
I've checked the I²C communication with a logic analyzer, all good.
Typically it outputs something like:
X=-3856 Y=-3856 Z=-3856
X=-3856 Y=-3856 Z=-3856
X=-3856 Y=-3856 Z=-3856
X=-3856 Y=-3856 Z=-3856
X=-3856 Y=-3856 Z=-3856
X=-3856 Y=-3856 Z=-3856
X=0 Y=0 Z=0
X=-3856 Y=-3856 Z=-3856
#include <h3lis331dl_reg.h>
#include <string.h>
I2C i2c(PB_9, PB_8);
Serial serial(SERIAL_TX, SERIAL_RX, 9600);
#define TWI_ADDR (H3LIS331DL_I2C_ADD_H)
static axis3bit16_t data_raw_acceleration;
static float acceleration_mg[3];
static uint8_t whoamI;
static uint8_t tx_buffer[1000];
int32_t platform_write(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len)
{
uint8_t buffer[10] = {0};
buffer[0]= reg; // | 0x80;
memcpy(&buffer[1], bufp, len);
return i2c.write(TWI_ADDR, (char*)buffer, len+1, false);
}
static int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len)
{
i2c.write(TWI_ADDR, (char*)®, 1, true);
return i2c.read(TWI_ADDR, (char*)bufp, len);
}
int main() {
h3lis331dl_ctx_t dev_ctx;
/* Initialize mems driver interface */
dev_ctx.write_reg = platform_write;
dev_ctx.read_reg = platform_read;
i2c.frequency(400000);
serial.printf("Starting up\n");
/* Check device ID */
whoamI = 0;
do {
h3lis331dl_device_id_get(&dev_ctx, &whoamI);
if ( whoamI != H3LIS331DL_ID ) {
serial.printf("Device not found 0x32 != %x\n", whoamI);
wait(2.0f);
}
}
while( whoamI != H3LIS331DL_ID );
serial.printf("Device found.\n");
/* Enable Block Data Update */
h3lis331dl_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
/* Set full scale */
h3lis331dl_full_scale_set(&dev_ctx, H3LIS331DL_200g);
/* Configure filtering chain */
h3lis331dl_hp_path_set(&dev_ctx, H3LIS331DL_HP_DISABLE);
/* Set Output Data Rate */
h3lis331dl_data_rate_set(&dev_ctx, H3LIS331DL_ODR_5Hz);
serial.printf("Device set up, running loop..\n\n");
/* Read samples in polling mode (no int) */
while(1) {
/* Read output only if new value is available */
h3lis331dl_reg_t reg;
h3lis331dl_status_reg_get(&dev_ctx, ®.status_reg);
if (reg.status_reg.zyxda) {
/* Read acceleration data */
memset(data_raw_acceleration.u8bit, 0x00, 3*sizeof(int16_t));
h3lis331dl_acceleration_raw_get(&dev_ctx, data_raw_acceleration.u8bit);
serial.printf("X=%d Y=%d Z=%d\n",
data_raw_acceleration.i16bit[0],
data_raw_acceleration.i16bit[1],
data_raw_acceleration.i16bit[2]);
}
}
}
2019-02-15 06:48 AM
Found the error.
The chip doesn't support automatic address incrementation on block read so to read multiple registers at once is not working. Therefore my I²C implementation reads the X_OUT_L register over and over. Since the others are not read the registers are never refreshed with new readings and return the old value over and over.