Skip to main content
Visitor II
August 23, 2019
Question

Issue with I2C communication between LSM6DSO and nRF9160-DK.

  • August 23, 2019
  • 1 reply
  • 894 views

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.

    This topic has been closed for replies.

    1 reply

    ASoni.2Author
    Visitor II
    February 7, 2020

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