2019-08-23 04:15 AM
Hi,
I am trying to interface the LSM6DSO (STEVAL-MKI196V1) sensor with nrf9160-DK using the code below.
I tried similar code for the BMI160 sensor and it is working fine with nRF9160-DK.
Moreover, I tried working on LSM6DSO sensor with P-Nucleo-WB55 board and it works fine.
#include <nrf9160.h>
#include <zephyr.h>
#include <device.h>
#include <misc/printk.h>
#include <i2c.h>
#include <gpio.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "lsm6dso_reg.h"
#ifdef CONFIG_SOC_NRF9160
#define I2C_DEV "I2C_3"
#else
#define I2C_DEV "I2C_1"
#endif
static axis3bit16_t data_raw_acceleration;
static float acceleration_mg[3];
static uint8_t whoamI, rst;
struct device *LSM6DSO_I2C;
lsm6dso_ctx_t dev_ctx;
uint8_t init_i2c(){
LSM6DSO_I2C = device_get_binding(I2C_DEV);
if (!LSM6DSO_I2C) {
printf("ERROR SETTING UP I2C\r\n");
return -1;
} else {
i2c_configure(LSM6DSO_I2C, I2C_SPEED_SET(I2C_SPEED_STANDARD));
printf("I2C CONFIGURED\r\n");
return 0;
}
}
static int32_t platform_write(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len){
int8_t ret = 0;
uint8_t data[len+1];
data[0] = reg;
for(uint16_t i=0; i<len; i++){
data[i+1] = bufp[i];
}
ret = i2c_write(LSM6DSO_I2C, data, len+1, LSM6DSO_I2C_ADD_L);
return ret;
}
static int32_t platform_read(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len){
int8_t ret = 0;
ret = i2c_write(LSM6DSO_I2C, ®, len, LSM6DSO_I2C_ADD_L);
if(ret == 0){
ret = i2c_read(LSM6DSO_I2C, bufp, len, LSM6DSO_I2C_ADD_L);
}
return ret;
}
void LSM6DSO_init(void){
dev_ctx.write_reg = platform_write;
dev_ctx.read_reg = platform_read;
dev_ctx.handle = &LSM6DSO_I2C;
lsm6dso_device_id_get(&dev_ctx, &whoamI);
if(whoamI != LSM6DSO_ID)
while(1);
printf("DEVICE ID GET\r\n");
lsm6dso_reset_set(&dev_ctx, PROPERTY_ENABLE);
do {
lsm6dso_reset_get(&dev_ctx, &rst);
} while (rst);
printf("RESET SET\r\n");
lsm6dso_i3c_disable_set(&dev_ctx, LSM6DSO_I3C_DISABLE);
lsm6dso_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
lsm6dso_xl_data_rate_set(&dev_ctx, LSM6DSO_XL_ODR_12Hz5);
lsm6dso_xl_full_scale_set(&dev_ctx, LSM6DSO_2g);
lsm6dso_xl_hp_path_on_out_set(&dev_ctx, LSM6DSO_LP_ODR_DIV_100);
lsm6dso_xl_filter_lp2_set(&dev_ctx, PROPERTY_ENABLE);
printf("SENSOR CONFIGURED\r\n");
}
static void read_sensor_data(){
uint8_t reg;
lsm6dso_xl_flag_data_ready_get(&dev_ctx, ®);
if(reg){
memset(data_raw_acceleration.u8bit, 0x00, 3 * sizeof(int16_t));
lsm6dso_acceleration_raw_get(&dev_ctx, data_raw_acceleration.u8bit);
acceleration_mg[0] = lsm6dso_from_fs2_to_mg(data_raw_acceleration.i16bit[0]);
acceleration_mg[1] = lsm6dso_from_fs2_to_mg(data_raw_acceleration.i16bit[1]);
acceleration_mg[2] = lsm6dso_from_fs2_to_mg(data_raw_acceleration.i16bit[2]);
printf("Ax: %4.2f, Ay: %4.2f, Az: %4.2f\r\n", acceleration_mg[0], acceleration_mg[1], acceleration_mg[2]);
}
}
void main(void){
init_i2c();
LSM6DSO_init();
while(1){
read_sensor_data();
k_sleep(500);
}
}
If I comment the following part in the code,
lsm6dso_device_id_get(&dev_ctx, &whoamI);
//if(whoamI != LSM6DSO_ID)
// while(1);
//printf("DEVICE ID GET\r\n");
lsm6dso_reset_set(&dev_ctx, PROPERTY_ENABLE);
, the program proceeds to the next stage but only gives zeros.
Can you please guide me on this issue?
I think the problem is with the i2c read and write function. Am I initialising read and write function properly?
I used following Sensor Drivers and Sample Code to come up with the above stated code.
Kind regards,
Aakash Soni.
2020-02-07 03:04 AM
Hello, Just solved this issue. I had to shift LSM6DSO_I2C_ADD_L to right by 1 bit.