cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with I2C communication between LSM6DSO and nRF9160-DK.

ASoni.2
Associate III

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, &reg, 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, &reg);
  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.

0690X00000AABTzQAP.png

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.

1 REPLY 1
ASoni.2
Associate III

Hello, Just solved this issue. I had to shift LSM6DSO_I2C_ADD_L to right by 1 bit.