This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to fully configure i2c sensor working with NCS bluetooth?

We are in the process to add spectral sensor to zephyr based BLE sample, but following the tutorial to add overlay or copying other sensor configurations not helped much. Either it causes device tree error or some configuration error or label not registered.

Please help find any suitable guide to know all modifications needed to make new sensor visible for main script in BLE.

Thank you.

Parents
  • Hello,

    the most useful guide is probably the Zephyr devicetree guide. It would also be helpful if you could post the overlay file and tell what you are doing, to identify the issue.

  • I tried all possibilities modifying; 

    DTS->Bindings, Devicetree.h, drivers, overlay, board.dts, but no progress in adding adxl345 sensor to custom 52840 board nor BMI160 to NRF52840 development kit.

    device_get_binding(DT_LABEL(DT_INST(0,adi_adxl345) is always NULL and DT_NODE_HAS_STATUS(ADXL345,okay) is always NULL.

    Driver->adxl345->cmake

     

    # Copyright (c) 2019 Brett Witherspoon
    #
    # SPDX-License-Identifier: Apache-2.0
    
    cmake_minimum_required(VERSION 3.13.1)
    
    find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
    project(adxl345)
    
    target_sources(app PRIVATE src/main.c)
    

    Driver -> adxl_345.c

    /*
     * Copyright (c) 2020 Antmicro <www.antmicro.com>
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #define DT_DRV_COMPAT adi_adxl345
    
    #include <drivers/sensor.h>
    #include <init.h>
    #include <drivers/gpio.h>
    #include <drivers/i2c.h>
    #include <logging/log.h>
    #include <sys/__assert.h>
    
    #include "adxl345.h"
    
    LOG_MODULE_REGISTER(ADXL345, CONFIG_SENSOR_LOG_LEVEL);
    
    static int adxl345_read_sample(const struct device *dev,
    			       struct adxl345_sample *sample)
    {
    	struct adxl345_dev_data *data = dev->data;
    	int16_t raw_x, raw_y, raw_z;
    	uint8_t axis_data[6];
    
    	int rc = i2c_burst_read(data->i2c_master,
    				data->i2c_addr,
    				ADXL345_X_AXIS_DATA_0_REG,
    				axis_data,
    				6);
    
    	if (rc < 0) {
    		LOG_ERR("Samples read failed with rc=%d\n", rc);
    		return rc;
    	}
    
    	raw_x = axis_data[0] | (axis_data[1] << 8);
    	raw_y = axis_data[2] | (axis_data[3] << 8);
    	raw_z = axis_data[4] | (axis_data[5] << 8);
    
    	sample->x = raw_x;
    	sample->y = raw_y;
    	sample->z = raw_z;
    
    	return 0;
    }
    
    static void adxl345_accel_convert(struct sensor_value *val, int16_t sample)
    {
    	if (sample & BIT(9)) {
    		sample |= ADXL345_COMPLEMENT;
    	}
    
    	val->val1 = (sample * 1000) / 32;
    	val->val2 = 0;
    }
    
    static int adxl345_sample_fetch(const struct device *dev,
    				enum sensor_channel chan)
    {
    	struct adxl345_dev_data *data = dev->data;
    	struct adxl345_sample sample;
    	uint8_t samples_count;
    	int rc;
    
    	data->sample_number = 0;
    	rc = i2c_reg_read_byte(data->i2c_master, data->i2c_addr,
    		ADXL345_FIFO_STATUS_REG, &samples_count);
    	if (rc < 0) {
    		LOG_ERR("Failed to read FIFO status rc = %d\n", rc);
    		return rc;
    	}
    
    	__ASSERT_NO_MSG(samples_count <= ARRAY_SIZE(data->bufx));
    
    	for (uint8_t s = 0; s < samples_count; s++) {
    		rc = adxl345_read_sample(dev, &sample);
    		if (rc < 0) {
    			LOG_ERR("Failed to fetch sample rc=%d\n", rc);
    			return rc;
    		}
    		data->bufx[s] = sample.x;
    		data->bufy[s] = sample.y;
    		data->bufz[s] = sample.z;
    	}
    
    	return samples_count;
    }
    
    static int adxl345_channel_get(const struct device *dev,
    			       enum sensor_channel chan,
    			       struct sensor_value *val)
    {
    	struct adxl345_dev_data *data = dev->data;
    
    	if (data->sample_number >= ARRAY_SIZE(data->bufx)) {
    		data->sample_number = 0;
    	}
    
    	switch (chan) {
    	case SENSOR_CHAN_ACCEL_X:
    		adxl345_accel_convert(val, data->bufx[data->sample_number]);
    		data->sample_number++;
    		break;
    	case SENSOR_CHAN_ACCEL_Y:
    		adxl345_accel_convert(val, data->bufy[data->sample_number]);
    		data->sample_number++;
    		break;
    	case SENSOR_CHAN_ACCEL_Z:
    		adxl345_accel_convert(val, data->bufz[data->sample_number]);
    		data->sample_number++;
    		break;
    	case SENSOR_CHAN_ACCEL_XYZ:
    		adxl345_accel_convert(val++, data->bufx[data->sample_number]);
    		adxl345_accel_convert(val++, data->bufy[data->sample_number]);
    		adxl345_accel_convert(val,   data->bufz[data->sample_number]);
    		data->sample_number++;
    		break;
    	default:
    		return -ENOTSUP;
    	}
    
    	return 0;
    }
    
    static const struct sensor_driver_api adxl345_api_funcs = {
    	.sample_fetch = adxl345_sample_fetch,
    	.channel_get = adxl345_channel_get,
    };
    
    static int adxl345_init(const struct device *dev)
    {
            printf("-------------------------- Entered init --------------------");
    	int rc;
    	struct adxl345_dev_data *data = dev->data;
    	const struct adxl345_dev_config *cfg = dev->config;
    	uint8_t dev_id;
    
    	data->sample_number = 0;
    	data->i2c_master = device_get_binding(cfg->i2c_master_name);
    	data->i2c_addr = cfg->i2c_addr;
    
    	if (!data->i2c_master) {
    		LOG_ERR("Failed to get I2C master\n");
    		return -ENODEV;
    	}
            printf("I@C Address = %x \n",data->i2c_addr);
    	rc = i2c_reg_read_byte(data->i2c_master, data->i2c_addr,
    		ADXL345_DEVICE_ID_REG, &dev_id);
    	if (rc < 0 || dev_id != ADXL345_PART_ID) {
    		LOG_ERR("Read PART ID failed: 0x%x\n", rc);
    		return -ENODEV;
    	}
    
    	rc = i2c_reg_write_byte(data->i2c_master, data->i2c_addr,
    		ADXL345_FIFO_CTL_REG, ADXL345_FIFO_STREAM_MODE);
    	if (rc < 0) {
    		LOG_ERR("FIFO enable failed\n");
    		return -EIO;
    	}
    
    	rc = i2c_reg_write_byte(data->i2c_master, data->i2c_addr,
    		ADXL345_DATA_FORMAT_REG, ADXL345_RANGE_16G);
    	if (rc < 0) {
    		LOG_ERR("Data format set failed\n");
    		return -EIO;
    	}
    
    	rc = i2c_reg_write_byte(data->i2c_master, data->i2c_addr,
    		ADXL345_RATE_REG, ADXL345_RATE_25HZ);
    	if (rc < 0) {
    		LOG_ERR("Rate setting failed\n");
    		return -EIO;
    	}
    
    	rc = i2c_reg_write_byte(data->i2c_master, data->i2c_addr,
    		ADXL345_POWER_CTL_REG, ADXL345_ENABLE_MEASURE_BIT);
    	if (rc < 0) {
    		LOG_ERR("Enable measure bit failed\n");
    		return -EIO;
    	}
    
    	return 0;
    }
    
    static struct adxl345_dev_data adxl345_data;
    static const struct adxl345_dev_config adxl345_config = {
    #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
    	.i2c_master_name = DT_INST_BUS_LABEL(0),
    	.i2c_addr = 0x53,
    #else
    #error "BUS MACRO NOT DEFINED IN DTS"
    #endif
    
    };
    DEVICE_AND_API_INIT(adxl345, DT_INST_LABEL(0), adxl345_init,
    		    &adxl345_data, &adxl345_config, POST_KERNEL,
    		    CONFIG_SENSOR_INIT_PRIORITY, &adxl345_api_funcs);
    

    Drivers->adxl345->Kconfig

    # ADXL345, 3-Axis, +/-16g Digital Accelerometer
    
    # Copyright (c) 2020 Antmicro <www.antmicro.com>
    # SPDX-License-Identifier: Apache-2.0
    config ADXL345
    	bool "ADXL345 Three Axis I2C accelerometer"
    	depends on I2C
    	help
    	  Enable driver for ADXL345 Three-Axis Digital Accelerometer.
    

    2. ncs->nrf->samples->bluetooth->mesh->adxl345->

    nrf52840dk_nrf52840.overlay overlay file:

    /*
     * Copyright (c) 2020, Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    &i2c0 {
    	compatible = "nordic,nrf-twim";
    	status = "okay";
    	sda-pin = <17>;
    	scl-pin = <13>;
    	clock-frequency = <I2C_BITRATE_FAST>;
    	adxl345@53 {
    		compatible = "adi,adxl345";
    		label = "ADXL345";
    		reg = <0x53>;
    		status = "okay";
    	};
    };
    
    
    

    # Copyright (c) 2019 Brett Witherspoon
    #
    # SPDX-License-Identifier: Apache-2.0
    
    cmake_minimum_required(VERSION 3.13.1)
    
    find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
    project(adxl345)
    
    target_sources(app PRIVATE src/main.c)
    

    sample.yaml

    sample:
      name: adxl345 sample
      description: ADXL345 accelerometer sample application
    tests:
      sample.sensor.adxl345:
        harness: sensor
        tags: sensors
        depends_on: i2c
        platform_allow: nrf52840dk_nrf52840
    

    Proj.conf

    CONFIG_STDOUT_CONSOLE=y
    CONFIG_I2C=y
    CONFIG_SENSOR=y
    CONFIG_ADXL345=y
    
    CONFIG_USE_SEGGER_RTT=y
    CONFIG_RTT_CONSOLE=y
    CONFIG_LOG_BACKEND_UART=y
    CONFIG_SERIAL=y
    CONFIG_UART_CONSOLE=n
    CONFIG_PRINTK=y
    CONFIG_CONSOLE=y
    
    
    

    main.c

    /*
     * Copyright (c) 2019 Brett Witherspoon
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr.h>
    #include <stdio.h>
    #include <device.h>
    #include <drivers/sensor.h>
    #include <drivers/gpio.h>
    #include <drivers/i2c.h>
    K_SEM_DEFINE(sem, 0, 1);
    #define adxl_sdo 20
    #define adxl_cs  15
    static void trigger_handler(const struct device *dev,
    			    struct sensor_trigger *trig)
    {
    	switch (trig->type) {
    	case SENSOR_TRIG_DATA_READY:
    		if (sensor_sample_fetch(dev) < 0) {
    			printf("Sample fetch error\n");
    			return;
    		}
    		k_sem_give(&sem);
    		break;
    	case SENSOR_TRIG_THRESHOLD:
    		printf("Threshold trigger\n");
    		break;
    	default:
    		printf("Unknown trigger\n");
    	}
    }
    const struct device *gpio_dev;
    void i2c_init(){
      gpio_pin_configure(gpio_dev,adxl_sdo,GPIO_PULL_DOWN);
      gpio_pin_configure(gpio_dev,adxl_cs,GPIO_PULL_DOWN);
      gpio_pin_set(gpio_dev,adxl_sdo,0);
      gpio_pin_set(gpio_dev,adxl_cs,1);
    
    }
    void main(void)
    {
    	struct sensor_value accel[3];
            if(DT_NODE_HAS_STATUS(ADXL345,okay)){
            printf("Device found\n");
            }
    	const struct device *dev = device_get_binding(DT_LABEL(DT_INST(0, adi_adxl345)));
    	if (dev == NULL) {
    		printf("Device get binding device\n");
    		return;
    	}
    
    	while (true) {
    
    			if (sensor_sample_fetch(dev) < 0) {
    				printf("Sample fetch error\n");
    				return;
    			}
    
    
    		if (sensor_channel_get(dev, SENSOR_CHAN_ACCEL_X, &accel[0]) < 0) {
    			printf("Channel get error\n");
    			return;
    		}
    
    		if (sensor_channel_get(dev, SENSOR_CHAN_ACCEL_Y, &accel[1]) < 0) {
    			printf("Channel get error\n");
    			return;
    		}
    
    		if (sensor_channel_get(dev, SENSOR_CHAN_ACCEL_Z, &accel[2]) < 0) {
    			printf("Channel get error\n");
    			return;
    		}
    
    		printf("x: %.1f, y: %.1f, z: %.1f (m/s^2)\n",
    		       sensor_value_to_double(&accel[0]),
    		       sensor_value_to_double(&accel[1]),
    		       sensor_value_to_double(&accel[2]));
    	}
    }
    

    Above is my project configuration files.

    I am trying to read ADXL345 accelerometer value from NRF52840 custom board. The device is not getting detected. Similar configuration I have used for BMI160 with NRF52840 development kit but there also device binding is NULL.

    Please help me find the missing modifications for getting the sensor working.

Reply
  • I tried all possibilities modifying; 

    DTS->Bindings, Devicetree.h, drivers, overlay, board.dts, but no progress in adding adxl345 sensor to custom 52840 board nor BMI160 to NRF52840 development kit.

    device_get_binding(DT_LABEL(DT_INST(0,adi_adxl345) is always NULL and DT_NODE_HAS_STATUS(ADXL345,okay) is always NULL.

    Driver->adxl345->cmake

     

    # Copyright (c) 2019 Brett Witherspoon
    #
    # SPDX-License-Identifier: Apache-2.0
    
    cmake_minimum_required(VERSION 3.13.1)
    
    find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
    project(adxl345)
    
    target_sources(app PRIVATE src/main.c)
    

    Driver -> adxl_345.c

    /*
     * Copyright (c) 2020 Antmicro <www.antmicro.com>
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #define DT_DRV_COMPAT adi_adxl345
    
    #include <drivers/sensor.h>
    #include <init.h>
    #include <drivers/gpio.h>
    #include <drivers/i2c.h>
    #include <logging/log.h>
    #include <sys/__assert.h>
    
    #include "adxl345.h"
    
    LOG_MODULE_REGISTER(ADXL345, CONFIG_SENSOR_LOG_LEVEL);
    
    static int adxl345_read_sample(const struct device *dev,
    			       struct adxl345_sample *sample)
    {
    	struct adxl345_dev_data *data = dev->data;
    	int16_t raw_x, raw_y, raw_z;
    	uint8_t axis_data[6];
    
    	int rc = i2c_burst_read(data->i2c_master,
    				data->i2c_addr,
    				ADXL345_X_AXIS_DATA_0_REG,
    				axis_data,
    				6);
    
    	if (rc < 0) {
    		LOG_ERR("Samples read failed with rc=%d\n", rc);
    		return rc;
    	}
    
    	raw_x = axis_data[0] | (axis_data[1] << 8);
    	raw_y = axis_data[2] | (axis_data[3] << 8);
    	raw_z = axis_data[4] | (axis_data[5] << 8);
    
    	sample->x = raw_x;
    	sample->y = raw_y;
    	sample->z = raw_z;
    
    	return 0;
    }
    
    static void adxl345_accel_convert(struct sensor_value *val, int16_t sample)
    {
    	if (sample & BIT(9)) {
    		sample |= ADXL345_COMPLEMENT;
    	}
    
    	val->val1 = (sample * 1000) / 32;
    	val->val2 = 0;
    }
    
    static int adxl345_sample_fetch(const struct device *dev,
    				enum sensor_channel chan)
    {
    	struct adxl345_dev_data *data = dev->data;
    	struct adxl345_sample sample;
    	uint8_t samples_count;
    	int rc;
    
    	data->sample_number = 0;
    	rc = i2c_reg_read_byte(data->i2c_master, data->i2c_addr,
    		ADXL345_FIFO_STATUS_REG, &samples_count);
    	if (rc < 0) {
    		LOG_ERR("Failed to read FIFO status rc = %d\n", rc);
    		return rc;
    	}
    
    	__ASSERT_NO_MSG(samples_count <= ARRAY_SIZE(data->bufx));
    
    	for (uint8_t s = 0; s < samples_count; s++) {
    		rc = adxl345_read_sample(dev, &sample);
    		if (rc < 0) {
    			LOG_ERR("Failed to fetch sample rc=%d\n", rc);
    			return rc;
    		}
    		data->bufx[s] = sample.x;
    		data->bufy[s] = sample.y;
    		data->bufz[s] = sample.z;
    	}
    
    	return samples_count;
    }
    
    static int adxl345_channel_get(const struct device *dev,
    			       enum sensor_channel chan,
    			       struct sensor_value *val)
    {
    	struct adxl345_dev_data *data = dev->data;
    
    	if (data->sample_number >= ARRAY_SIZE(data->bufx)) {
    		data->sample_number = 0;
    	}
    
    	switch (chan) {
    	case SENSOR_CHAN_ACCEL_X:
    		adxl345_accel_convert(val, data->bufx[data->sample_number]);
    		data->sample_number++;
    		break;
    	case SENSOR_CHAN_ACCEL_Y:
    		adxl345_accel_convert(val, data->bufy[data->sample_number]);
    		data->sample_number++;
    		break;
    	case SENSOR_CHAN_ACCEL_Z:
    		adxl345_accel_convert(val, data->bufz[data->sample_number]);
    		data->sample_number++;
    		break;
    	case SENSOR_CHAN_ACCEL_XYZ:
    		adxl345_accel_convert(val++, data->bufx[data->sample_number]);
    		adxl345_accel_convert(val++, data->bufy[data->sample_number]);
    		adxl345_accel_convert(val,   data->bufz[data->sample_number]);
    		data->sample_number++;
    		break;
    	default:
    		return -ENOTSUP;
    	}
    
    	return 0;
    }
    
    static const struct sensor_driver_api adxl345_api_funcs = {
    	.sample_fetch = adxl345_sample_fetch,
    	.channel_get = adxl345_channel_get,
    };
    
    static int adxl345_init(const struct device *dev)
    {
            printf("-------------------------- Entered init --------------------");
    	int rc;
    	struct adxl345_dev_data *data = dev->data;
    	const struct adxl345_dev_config *cfg = dev->config;
    	uint8_t dev_id;
    
    	data->sample_number = 0;
    	data->i2c_master = device_get_binding(cfg->i2c_master_name);
    	data->i2c_addr = cfg->i2c_addr;
    
    	if (!data->i2c_master) {
    		LOG_ERR("Failed to get I2C master\n");
    		return -ENODEV;
    	}
            printf("I@C Address = %x \n",data->i2c_addr);
    	rc = i2c_reg_read_byte(data->i2c_master, data->i2c_addr,
    		ADXL345_DEVICE_ID_REG, &dev_id);
    	if (rc < 0 || dev_id != ADXL345_PART_ID) {
    		LOG_ERR("Read PART ID failed: 0x%x\n", rc);
    		return -ENODEV;
    	}
    
    	rc = i2c_reg_write_byte(data->i2c_master, data->i2c_addr,
    		ADXL345_FIFO_CTL_REG, ADXL345_FIFO_STREAM_MODE);
    	if (rc < 0) {
    		LOG_ERR("FIFO enable failed\n");
    		return -EIO;
    	}
    
    	rc = i2c_reg_write_byte(data->i2c_master, data->i2c_addr,
    		ADXL345_DATA_FORMAT_REG, ADXL345_RANGE_16G);
    	if (rc < 0) {
    		LOG_ERR("Data format set failed\n");
    		return -EIO;
    	}
    
    	rc = i2c_reg_write_byte(data->i2c_master, data->i2c_addr,
    		ADXL345_RATE_REG, ADXL345_RATE_25HZ);
    	if (rc < 0) {
    		LOG_ERR("Rate setting failed\n");
    		return -EIO;
    	}
    
    	rc = i2c_reg_write_byte(data->i2c_master, data->i2c_addr,
    		ADXL345_POWER_CTL_REG, ADXL345_ENABLE_MEASURE_BIT);
    	if (rc < 0) {
    		LOG_ERR("Enable measure bit failed\n");
    		return -EIO;
    	}
    
    	return 0;
    }
    
    static struct adxl345_dev_data adxl345_data;
    static const struct adxl345_dev_config adxl345_config = {
    #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
    	.i2c_master_name = DT_INST_BUS_LABEL(0),
    	.i2c_addr = 0x53,
    #else
    #error "BUS MACRO NOT DEFINED IN DTS"
    #endif
    
    };
    DEVICE_AND_API_INIT(adxl345, DT_INST_LABEL(0), adxl345_init,
    		    &adxl345_data, &adxl345_config, POST_KERNEL,
    		    CONFIG_SENSOR_INIT_PRIORITY, &adxl345_api_funcs);
    

    Drivers->adxl345->Kconfig

    # ADXL345, 3-Axis, +/-16g Digital Accelerometer
    
    # Copyright (c) 2020 Antmicro <www.antmicro.com>
    # SPDX-License-Identifier: Apache-2.0
    config ADXL345
    	bool "ADXL345 Three Axis I2C accelerometer"
    	depends on I2C
    	help
    	  Enable driver for ADXL345 Three-Axis Digital Accelerometer.
    

    2. ncs->nrf->samples->bluetooth->mesh->adxl345->

    nrf52840dk_nrf52840.overlay overlay file:

    /*
     * Copyright (c) 2020, Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    &i2c0 {
    	compatible = "nordic,nrf-twim";
    	status = "okay";
    	sda-pin = <17>;
    	scl-pin = <13>;
    	clock-frequency = <I2C_BITRATE_FAST>;
    	adxl345@53 {
    		compatible = "adi,adxl345";
    		label = "ADXL345";
    		reg = <0x53>;
    		status = "okay";
    	};
    };
    
    
    

    # Copyright (c) 2019 Brett Witherspoon
    #
    # SPDX-License-Identifier: Apache-2.0
    
    cmake_minimum_required(VERSION 3.13.1)
    
    find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
    project(adxl345)
    
    target_sources(app PRIVATE src/main.c)
    

    sample.yaml

    sample:
      name: adxl345 sample
      description: ADXL345 accelerometer sample application
    tests:
      sample.sensor.adxl345:
        harness: sensor
        tags: sensors
        depends_on: i2c
        platform_allow: nrf52840dk_nrf52840
    

    Proj.conf

    CONFIG_STDOUT_CONSOLE=y
    CONFIG_I2C=y
    CONFIG_SENSOR=y
    CONFIG_ADXL345=y
    
    CONFIG_USE_SEGGER_RTT=y
    CONFIG_RTT_CONSOLE=y
    CONFIG_LOG_BACKEND_UART=y
    CONFIG_SERIAL=y
    CONFIG_UART_CONSOLE=n
    CONFIG_PRINTK=y
    CONFIG_CONSOLE=y
    
    
    

    main.c

    /*
     * Copyright (c) 2019 Brett Witherspoon
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr.h>
    #include <stdio.h>
    #include <device.h>
    #include <drivers/sensor.h>
    #include <drivers/gpio.h>
    #include <drivers/i2c.h>
    K_SEM_DEFINE(sem, 0, 1);
    #define adxl_sdo 20
    #define adxl_cs  15
    static void trigger_handler(const struct device *dev,
    			    struct sensor_trigger *trig)
    {
    	switch (trig->type) {
    	case SENSOR_TRIG_DATA_READY:
    		if (sensor_sample_fetch(dev) < 0) {
    			printf("Sample fetch error\n");
    			return;
    		}
    		k_sem_give(&sem);
    		break;
    	case SENSOR_TRIG_THRESHOLD:
    		printf("Threshold trigger\n");
    		break;
    	default:
    		printf("Unknown trigger\n");
    	}
    }
    const struct device *gpio_dev;
    void i2c_init(){
      gpio_pin_configure(gpio_dev,adxl_sdo,GPIO_PULL_DOWN);
      gpio_pin_configure(gpio_dev,adxl_cs,GPIO_PULL_DOWN);
      gpio_pin_set(gpio_dev,adxl_sdo,0);
      gpio_pin_set(gpio_dev,adxl_cs,1);
    
    }
    void main(void)
    {
    	struct sensor_value accel[3];
            if(DT_NODE_HAS_STATUS(ADXL345,okay)){
            printf("Device found\n");
            }
    	const struct device *dev = device_get_binding(DT_LABEL(DT_INST(0, adi_adxl345)));
    	if (dev == NULL) {
    		printf("Device get binding device\n");
    		return;
    	}
    
    	while (true) {
    
    			if (sensor_sample_fetch(dev) < 0) {
    				printf("Sample fetch error\n");
    				return;
    			}
    
    
    		if (sensor_channel_get(dev, SENSOR_CHAN_ACCEL_X, &accel[0]) < 0) {
    			printf("Channel get error\n");
    			return;
    		}
    
    		if (sensor_channel_get(dev, SENSOR_CHAN_ACCEL_Y, &accel[1]) < 0) {
    			printf("Channel get error\n");
    			return;
    		}
    
    		if (sensor_channel_get(dev, SENSOR_CHAN_ACCEL_Z, &accel[2]) < 0) {
    			printf("Channel get error\n");
    			return;
    		}
    
    		printf("x: %.1f, y: %.1f, z: %.1f (m/s^2)\n",
    		       sensor_value_to_double(&accel[0]),
    		       sensor_value_to_double(&accel[1]),
    		       sensor_value_to_double(&accel[2]));
    	}
    }
    

    Above is my project configuration files.

    I am trying to read ADXL345 accelerometer value from NRF52840 custom board. The device is not getting detected. Similar configuration I have used for BMI160 with NRF52840 development kit but there also device binding is NULL.

    Please help me find the missing modifications for getting the sensor working.

Children
  • For a start, you can try changing i2c0 to either i2c1 or i2c2. There are conflicting memory addresses between i2c0 and uart0, so you should use a different i2c peripheral instance.

  • I am using NRF52840- zephyr (i2c_burst_read) and BMP388 sensor using I2C. I am successfully able to setup register enabling required feature and able to read the sensor data from I2C. However, the data read from data register doesn't change. The hexadecimal value read from arduino with same sensor board is completely different from that read in nrf52840 over i2c. Please help me know if I am missing ay fundamental understanding reading data value over i2c. I am reading register 0x04 with Length 6. Arduino reads the same address with length 6 and gets different value from register and it is changing but nrf52840 gets different value and unchanging. (I have used i2c1 in board overlay)

  • I modified example BME280 with bmp388 configurations and at the end even I forcefully written required pwr, odr and osr values. Attaching the .c and .h files. I am sorry for not maintaining readable script. Very much haphazard.

    /* bme280.c - Driver for Bosch BME280 temperature and pressure sensor */
    
    /*
     * Copyright (c) 2016, 2017 Intel Corporation
     * Copyright (c) 2017 IpTronix S.r.l.
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <kernel.h>
    #include <drivers/sensor.h>
    #include <init.h>
    #include <drivers/gpio.h>
    #include <drivers/i2c.h>
    #include <drivers/spi.h>
    #include <sys/byteorder.h>
    #include <sys/__assert.h>
    
    #include <logging/log.h>
    
    #include "bme280.h"
    #include <zephyr.h>
    #include <math.h>
    
    #define DT_DRV_COMPAT bosch_bme280
    
    #define BME280_BUS_SPI DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
    #define BME280_BUS_I2C DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
    
    LOG_MODULE_REGISTER(BME280, CONFIG_SENSOR_LOG_LEVEL);
    
    #if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0
    #warning "BME280 driver enabled without any devices"
    #endif
    const struct device *dev1;
    /*
     * This driver is an example of why devices should be resolvable at
     * link time instead of only at runtime via device_get_binding().
     *
     * We only need to store 'bus' and 'spi_cs' in RAM because we can't
     * resolve devices at link time. They should be moved to ROM if that
     * becomes possible. That would in turn enable several further
     * cleanups.
     */
    
    struct bme280_spi_cfg {
    	struct spi_config spi_cfg;
    	const char *cs_gpios_label;
    };
    
    union bme280_bus_config {
    #if BME280_BUS_SPI
    	const struct bme280_spi_cfg *spi_cfg;
    #endif
    #if BME280_BUS_I2C
    	uint16_t i2c_addr;
    #endif
    };
    
    struct bme280_config {
    	const char *bus_label;
    	const struct bme280_reg_io *reg_io;
    	const union bme280_bus_config bus_config;
    };
    
    typedef int (*bme280_reg_read_fn)(const struct device *bus,
    				  const union bme280_bus_config *bus_config,
    				  uint8_t start, uint8_t *buf, int size);
    typedef int (*bme280_reg_write_fn)(const struct device *bus,
    				   const union bme280_bus_config *bus_config,
    				   uint8_t reg, uint8_t val);
    
    struct bme280_reg_io {
    	bme280_reg_read_fn read;
    	bme280_reg_write_fn write;
    };
    
    static inline struct bme280_data *to_data(const struct device *dev)
    {
    	return dev->data;
    }
    
    static inline const struct bme280_config *to_config(const struct device *dev)
    {
    	return dev->config;
    }
    
    static inline const struct device *to_bus(const struct device *dev)
    {
    	return to_data(dev)->bus;
    }
    
    static inline const union bme280_bus_config *to_bus_config(const struct device *dev)
    {
    	return &to_config(dev)->bus_config;
    }
    
    #if BME280_BUS_SPI
    static inline const struct spi_config *
    to_spi_config(const union bme280_bus_config *bus_config)
    {
    	return &bus_config->spi_cfg->spi_cfg;
    }
    
    static int bme280_reg_read_spi(const struct device *bus,
    			       const union bme280_bus_config *bus_config,
    			       uint8_t start, uint8_t *buf, int size)
    {
    	uint8_t addr;
    	const struct spi_buf tx_buf = {
    		.buf = &addr,
    		.len = 1
    	};
    	const struct spi_buf_set tx = {
    		.buffers = &tx_buf,
    		.count = 1
    	};
    	struct spi_buf rx_buf[2];
    	const struct spi_buf_set rx = {
    		.buffers = rx_buf,
    		.count = 2
    	};
    	int i;
    
    	rx_buf[0].buf = NULL;
    	rx_buf[0].len = 1;
    
    	rx_buf[1].len = 1;
    
    	for (i = 0; i < size; i++) {
    		int ret;
    
    		addr = (start + i) | 0x80;
    		rx_buf[1].buf = &buf[i];
    
    		ret = spi_transceive(bus, to_spi_config(bus_config), &tx, &rx);
    		if (ret) {
    			LOG_DBG("spi_transceive FAIL %d\n", ret);
    			return ret;
    		}
    	}
    
    	return 0;
    }
    
    static int bme280_reg_write_spi(const struct device *bus,
    				const union bme280_bus_config *bus_config,
    				uint8_t reg, uint8_t val)
    {
    	uint8_t cmd[2] = { reg & 0x7F, val };
    	const struct spi_buf tx_buf = {
    		.buf = cmd,
    		.len = 2
    	};
    	const struct spi_buf_set tx = {
    		.buffers = &tx_buf,
    		.count = 1
    	};
    	int ret;
    
    	ret = spi_write(bus, to_spi_config(bus_config), &tx);
    	if (ret) {
    		LOG_DBG("spi_write FAIL %d\n", ret);
    		return ret;
    	}
    	return 0;
    }
    
    static const struct bme280_reg_io bme280_reg_io_spi = {
    	.read = bme280_reg_read_spi,
    	.write = bme280_reg_write_spi,
    };
    #endif /* BME280_BUS_SPI */
    
    #if BME280_BUS_I2C
    static int bme280_reg_read_i2c(const struct device *bus,
    			       const union bme280_bus_config *bus_config,
    			       uint8_t start, uint8_t *buf, int size)
    {
    	return i2c_burst_read(bus, bus_config->i2c_addr,start, buf, size);
    
                                  //return i2c_read(bus,buf, size, bus_config->i2c_addr);
    
    }
    
    static int bme280_reg_write_i2c(const struct device *bus,
    				const union bme280_bus_config *bus_config,
    				uint8_t reg, uint8_t val)
    {
    	return i2c_reg_write_byte(bus, bus_config->i2c_addr,
    				  reg, val);
    }
    
    static const struct bme280_reg_io bme280_reg_io_i2c = {
    	.read = bme280_reg_read_i2c,
    	.write = bme280_reg_write_i2c,
    };
    #endif /* BME280_BUS_I2C */
    
    static inline int bme280_reg_read(const struct device *dev,
    				  uint8_t start, uint8_t *buf, int size)
    {
    	return to_config(dev)->reg_io->read(to_bus(dev), to_bus_config(dev),
    					    start, buf, size);
    }
    
    static inline int bme280_reg_write(const struct device *dev, uint8_t reg,
    				   uint8_t val)
    {
            printf("ADDR = %X\n",reg);
    	return to_config(dev)->reg_io->write(to_bus(dev), to_bus_config(dev),
    					     reg, val);
    }
    
    
    
    /* * @brief This internal API is used to compensate the raw temperature data and
     * return the compensated temperature data in double data type.
     */
    /*##########################################################################################################################*/
    /*##########################################################################################################################*/
    
    double bmp3_pow(double base, uint8_t power)
    {
      double pow_output = 1;
    
      while (power != 0) {
        pow_output = base * pow_output;
        power--;
      }
    
      return pow_output;
    }
    
    
    int8_t set_config()
    {
        int8_t rslt;
        /* Used to select the settings user needs to change */
        uint16_t settings_sel;
    
        /* Select the pressure and temperature sensor to be enabled */
        devv.settings.press_en = BMP3_ENABLE;
        devv.settings.temp_en = BMP3_ENABLE;
        /* Select the output data rate and oversampling settings for pressure and temperature */
        devv.settings.odr_filter.press_os = BMP3_NO_OVERSAMPLING;
        devv.settings.odr_filter.temp_os = BMP3_NO_OVERSAMPLING;
        devv.settings.odr_filter.odr = BMP3_ODR_200_HZ;
        /* Assign the settings which needs to be set in the sensor */
        settings_sel = BMP3_PRESS_EN_SEL | BMP3_TEMP_EN_SEL | BMP3_PRESS_OS_SEL | BMP3_TEMP_OS_SEL | BMP3_ODR_SEL;
        rslt = bmp3_set_sensor_settings(settings_sel);
    
        /* Set the power mode to normal mode */
        devv.settings.op_mode = BMP3_NORMAL_MODE;
        rslt = bmp3_set_op_mode();
    
        return rslt;
    }
    
    float readTemperature(){
      uint8_t sensor_comp;
      sensor_comp = BMP3_TEMP;
      struct bmp3_data data12;
      bmp3_get_sensor_data(sensor_comp, &data12);
      printf("Read Temperature = %f\n",data12.temperature);
      return data12.temperature;
    }
    
    float readPressure(){
      uint8_t sensor_comp;
      sensor_comp = BMP3_PRESS;
      struct bmp3_data data12;
      bmp3_get_sensor_data(sensor_comp, &data12);
      printf("Read Pressure = %f\n",data12.pressure);
      return data12.pressure;
    }
    
    /*!
     * @brief This API reads the data from the given register address of the sensor.
     */
    int8_t bmp3_get_regs(const struct device *dev, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
    {
        int err;
        //devv.read(devv.devv_id, reg_addr, reg_data, len);
        //printk("Entered Get Regs\n");
        uint16_t temp_len = len +1;
      uint16_t i;
      uint8_t temp_buff[len + 1];
      //-----SPI-----
      if (devv.intf == BMP3_SPI_INTF) {
        reg_addr = reg_addr | 0x80;
        //dev.read(dev.dev_id, reg_addr, temp_buff, temp_len);
        err = bme280_reg_read(dev1, reg_addr, temp_buff, temp_len);
        for (i = 0; i < len; i++){
          reg_data[i] = temp_buff[i + 1];
        }
      }
      //-----I2C-----
      else if(devv.intf == BMP3_I2C_INTF){
        //dev.read(dev.dev_id, reg_addr, reg_data, len);
        err = bme280_reg_read(dev1, reg_addr, reg_data, len);
      }
      return 0;
        //printk("Register Reading ;length = %d, Register = %X, Reg Data = %d\n",len,reg_addr,reg_data);
        //int ar_len = sizeof(reg_data)/sizeof(reg_data[0]);
        //for(int i;i<ar_len;i++){
        //    printk("%d",reg_data[i]);
        //}  
        //printk("\n");
        //for(int i;i<=ar_len;i++){
        //    printk("%d",reg_data[i]);
        //}  
        //printk("\n");
    
        //    for(int i;i<=ar_len;i++){
        //    printk("%x",reg_data[i]);
        //}  
        //printk("\n");
    }
    
    /*!
    /*!
     * @brief This API writes the given data to the register address
     * of the sensor.
     */
    int8_t bmp3_set_regs(const struct device *dev,uint8_t *reg_addr, const uint8_t *reg_data, uint8_t len)
    {
      int8_t rslt;
      uint8_t temp_buff[len * 2];
      uint16_t temp_len;
      uint8_t reg_addr_cnt;
    
      // Check for arguments validity 
      if ((reg_addr != NULL) && (reg_data != NULL) && (len != 0)) {
        temp_buff[0] = reg_data[0];
        if (devv.intf == BMP3_SPI_INTF) {
          for (reg_addr_cnt = 0; reg_addr_cnt < len; reg_addr_cnt++)
            reg_addr[reg_addr_cnt] = reg_addr[reg_addr_cnt] & 0x7F;
        }
        //rslt = devv.write(devv.devv_id, reg_addr[0], temp_buff, len);
        rslt = bme280_reg_write(dev1, reg_addr[0], temp_buff);
      }
      return rslt;
    }
    
    /*!
     * @brief This API sets the power control(pressure enable and
     * temperature enable), over sampling, odr and filter
     * settings in the sensor.
     */
    int8_t bmp3_set_sensor_settings(uint32_t desired_settings)
    {
      int8_t rslt;
      if (POWER_CNTL&desired_settings) {
        /* Set the power control settings */
        rslt = set_pwr_ctrl_settings(desired_settings);
      }
      return rslt;
    }
    
    /*!
     * @brief This API performs the soft reset of the sensor.
     */
    int8_t reset(const struct device *dev)
    {
      int8_t rslt;
      uint8_t reg_addr = BMP3_CMD_ADDR;
      /* 0xB6 is the soft reset command */
      uint8_t soft_rst_cmd = 0xB6;
      uint8_t cmd_rdy_status;
      uint8_t cmd_err_status;
    
      /* Check for command ready status */
      //DBG();
      rslt = bmp3_get_regs(dev1,BMP3_SENS_STATUS_REG_ADDR, &cmd_rdy_status, 1);
      /* devvice is ready to accept new command */
      if ((cmd_rdy_status & BMP3_CMD_RDY) && (rslt == BMP3_OK)) {
        /* Write the soft reset command in the sensor */
        printf("Writing soft reset commands = REgister = %X, Value = %X\n",reg_addr,soft_rst_cmd);
        rslt = bmp3_set_regs(dev1,&reg_addr, &soft_rst_cmd, 1);
        /* Proceed if everything is fine until now */
    //    DBG();
        if (rslt == BMP3_OK) {
          /* Wait for 2 ms */
          K_MSEC(2);
          //devv.delay_ms(2);
          /* Read for command error status */
          rslt = bmp3_get_regs(dev1,BMP3_ERR_REG_ADDR, &cmd_err_status, 1);
          /* check for command error status */
          if ((cmd_err_status & BMP3_CMD_ERR) || (rslt != BMP3_OK)) {
            /* Command not written hence return
               error */
               printf("Command not written\n");
            rslt = BMP3_E_CMD_EXEC_FAILED;
          }
        }
      } else {
        rslt = BMP3_E_CMD_EXEC_FAILED;
      }
      return rslt;
    }
    
    
    /*!
     * @brief This API sets the power mode of the sensor.
     */
    int8_t bmp3_set_op_mode()
    {
      int8_t rslt;
      //rslt = write_power_mode();
      return rslt;
    }
    /*!
     * @brief This internal API writes the power mode in the sensor.
     */
    
    /*!
     * @brief This API reads the pressure, temperature or both data from the
     * sensor, compensates the data and store it in the bmp3_data structure
     * instance passed by the user.
     */
    
    int8_t bmp3_get_sensor_data(uint8_t sensor_comp, struct bmp3_data *comp_data)
    {
      int8_t rslt;
      /* Array to store the pressure and temperature data read from
      the sensor */
      uint8_t reg_data[BMP3_P_T_DATA_LEN] = {0};
      struct bmp3_uncomp_data uncomp_data = {0};
      //int arr_len = sizeof(reg_data)/sizeof(reg_data[0]);
      //for (int i;i<=arr_len;i++){
      //  printf("Calib %d = %d\n",i,reg_data[i]);
      //}
      if ((comp_data != NULL)) {
        /* Read the pressure and temperature data from the sensor */
        //DBG();
        rslt = bmp3_get_regs(dev1,BMP3_DATA_ADDR, reg_data, BMP3_P_T_DATA_LEN);
          //    printk("Uncompensated Data\n");
          //int ar_len = sizeof(reg_data)/sizeof(reg_data[0]);
          //for(int i;i<=ar_len;i++){
          //  printk("%d",reg_data[i]);
          //}  
        if (rslt == BMP3_OK) {
          /* Parse the read data from the sensor */
          parse_sensor_data(reg_data, &uncomp_data);
          /* Compensate the pressure/temperature/both data read
             from the sensor */
          rslt = compensate_data(sensor_comp, &uncomp_data, comp_data, &devv.calib_data);
        }
      } else {
        rslt = BMP3_E_NULL_PTR;
      }
    
      return rslt;
    }
    
    
    int8_t write_power_mode()
    {
      int8_t rslt;
      uint8_t reg_addr = BMP3_PWR_CTRL_ADDR;
      uint8_t op_mode = devv.settings.op_mode;
      /* Temporary variable to store the value read from op-mode register */
      uint8_t op_mode_reg_val;
    
      /* Read the power mode register */
      //DBG();
      rslt = bmp3_get_regs(dev1,reg_addr, &op_mode_reg_val, 1);
      /* Set the power mode */
      if (rslt == BMP3_OK) {
        op_mode_reg_val = BMP3_SET_BITS(op_mode_reg_val, BMP3_OP_MODE, op_mode);
        op_mode_reg_val = 51;
        /* Write the power mode in the register */
        printf("Write Power Mode Writing = %X to addr = %X\n",op_mode_reg_val,reg_addr);
        rslt = bmp3_set_regs(dev1,&reg_addr, &op_mode_reg_val, 1);
        printf("Write Power Mode Writing = %X to addr = %X\n",op_mode_reg_val,reg_addr);
        
      }
    
      return rslt;
    }
    
    /* * @brief This API sets the pressure enable and temperature enable
     * settings of the sensor.
     */
    /*!
     * @brief This internal API reads the calibration data from the sensor, parse
     * it then compensates it and store in the devvice structure.
     */
    int8_t get_calib_data(const struct device *dev)
    {
      int8_t rslt;
      uint8_t reg_addr = BMP3_CALIB_DATA_ADDR;
      /* Array to store calibration data */
      uint8_t calib_data[BMP3_CALIB_DATA_LEN] = {0};
      
      /* Read the calibration data from the sensor */
      //DBG();
      rslt = bmp3_get_regs(dev,reg_addr, calib_data, BMP3_CALIB_DATA_LEN);
      /* Parse calibration data and store it in devvice structure */
      parse_calib_data(calib_data);
      int arr_len = sizeof(calib_data)/sizeof(calib_data[0]);
      //for (int i;i<=arr_len;i++){
      //  printf("Calib %d = %d\n",i,calib_data[i]);
      //}
      return rslt;
    }
    
    
    int8_t set_pwr_ctrl_settings(uint32_t desired_settings)
    {
      int8_t rslt;
      uint8_t reg_addr = BMP3_PWR_CTRL_ADDR;
      uint8_t reg_data;
      //DBG();
      rslt = bmp3_get_regs(dev1,reg_addr, &reg_data, 1);
      if (rslt == BMP3_OK) {
        if (desired_settings & BMP3_PRESS_EN_SEL) {
          /* Set the pressure enable settings in the
          register variable */
          reg_data = BMP3_SET_BITS_POS_0(reg_data, BMP3_PRESS_EN, devv.settings.press_en);
          printf("Inside PWR ctrl111 = %d\n",reg_data);
        }
        if (desired_settings & BMP3_TEMP_EN_SEL) {
          /* Set the temperature enable settings in the
          register variable */
          reg_data = BMP3_SET_BITS(reg_data, BMP3_TEMP_EN, devv.settings.temp_en);
          printf("Inside PWR ctrl = %d\n",reg_data);
        }
        /* Write the power control settings in the register */
        reg_data = 51;
        printf("PWR Control Settings WRITING Return = %d, Writed =%d to REG = %X\n",rslt,reg_data,reg_addr);
        rslt = bmp3_set_regs(dev1,&reg_addr, &reg_data, 1);
        
        //rslt = bme280_reg_read(dev, BME280_REG_COMP_START,
    			 //     op_, sizeof(buf));
      }
    
      return rslt;
    }
    
    /*!
     *  @brief This internal API is used to parse the pressure or temperature or
     *  both the data and store it in the bmp3_uncomp_data structure instance.
     */
    void parse_sensor_data(const uint8_t *reg_data, struct bmp3_uncomp_data *uncomp_data)
    {
      /* Temporary variables to store the sensor data */
      uint32_t data_xlsb;
      uint32_t data_lsb;
      uint32_t data_msb;
    
      /* Store the parsed register values for pressure data */
      data_xlsb = (uint32_t)reg_data[0];
      data_lsb = (uint32_t)reg_data[1] << 8;
      data_msb = (uint32_t)reg_data[2] << 16;
      uncomp_data->pressure = data_msb | data_lsb | data_xlsb;
      //printf("Parse Sensor Data\n");
      //uncomp_data->pressure  = reg_data[2]&reg_data[1]&reg_data[0];
      //uncomp_data->temperature = reg_data[5]&reg_data[4]&reg_data[3];
      //uncomp_data->temperature = (reg_data[5] << 16) | (reg_data[4] << 8) | (reg_data[3]);
      //Serial.println(uncomp_data->pressure);
      /* Store the parsed register values for temperature data */
      data_xlsb = (uint32_t)reg_data[3];
      data_lsb = (uint32_t)reg_data[4] << 8;
      data_msb = (uint32_t)reg_data[5] << 16;
      uncomp_data->temperature = data_msb | data_lsb | data_xlsb;
    
      //Serial.println(uncomp_data->temperature);
    }
    
    /*!
     * @brief This internal API is used to compensate the pressure or temperature
     * or both the data according to the component selected by the user.
     */
    int8_t compensate_data(uint8_t sensor_comp, const struct bmp3_uncomp_data *uncomp_data,
                 struct bmp3_data *comp_data, struct bmp3_calib_data *calib_data)
    {
      int8_t rslt = BMP3_OK;
    
      if ((uncomp_data != NULL) && (comp_data != NULL) && (calib_data != NULL)) {
        /* If pressure or temperature component is selected */
        if (sensor_comp & (BMP3_PRESS | BMP3_TEMP)) {
          /* Compensate the temperature data */
          comp_data->temperature = compensate_temperature(uncomp_data, calib_data);
        }
        if (sensor_comp & BMP3_PRESS) {
          /* Compensate the pressure data */
          comp_data->pressure = compensate_pressure(uncomp_data, calib_data);
        }
      } else {
        rslt = BMP3_E_NULL_PTR;
      }
    
      return rslt;
    }
    /*##########################################################################################################################*/
    /*##########################################################################################################################*/
    
    
    /*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
    /*!
     *  @brief This internal API is used to parse the calibration data, compensates
     *  it and store it in devvice structure
     */
    void parse_calib_data(const uint8_t *reg_data)
    {
      /* Temporary variable to store the aligned trim data */
      struct bmp3_reg_calib_data *reg_calib_data = &devv.calib_data.reg_calib_data;
      struct bmp3_quantized_calib_data *quantized_calib_data = &devv.calib_data.quantized_calib_data;
      /* Temporary variable */
      double temp_var;
    
      /* 1 / 2^8 */
      temp_var = 0.00390625f;
      reg_calib_data->par_t1 = BMP3_CONCAT_BYTES(reg_data[1], reg_data[0]);
      quantized_calib_data->par_t1 = ((double)reg_calib_data->par_t1 / temp_var);
    
      reg_calib_data->par_t2 = BMP3_CONCAT_BYTES(reg_data[3], reg_data[2]);
      temp_var = 1073741824.0f;
      quantized_calib_data->par_t2 = ((double)reg_calib_data->par_t2 / temp_var);
    
      reg_calib_data->par_t3 = (int8_t)reg_data[4];
      temp_var = 281474976710656.0f;
      quantized_calib_data->par_t3 = ((double)reg_calib_data->par_t3 / temp_var);
    
      reg_calib_data->par_p1 = (int16_t)BMP3_CONCAT_BYTES(reg_data[6], reg_data[5]);
    
      temp_var = 1048576.0f;
      quantized_calib_data->par_p1 = ((double)(reg_calib_data->par_p1 - (16384)) / temp_var);
    
      reg_calib_data->par_p2 = (int16_t)BMP3_CONCAT_BYTES(reg_data[8], reg_data[7]);
      temp_var = 536870912.0f;
      quantized_calib_data->par_p2 = ((double)(reg_calib_data->par_p2 - (16384)) / temp_var);
    
      reg_calib_data->par_p3 = (int8_t)reg_data[9];
      temp_var = 4294967296.0f;
      quantized_calib_data->par_p3 = ((double)reg_calib_data->par_p3 / temp_var);
    
      reg_calib_data->par_p4 = (int8_t)reg_data[10];
      temp_var = 137438953472.0f;
      quantized_calib_data->par_p4 = ((double)reg_calib_data->par_p4 / temp_var);
    
      reg_calib_data->par_p5 = BMP3_CONCAT_BYTES(reg_data[12], reg_data[11]);
      /* 1 / 2^3 */
      temp_var = 0.125f;
      quantized_calib_data->par_p5 = ((double)reg_calib_data->par_p5 / temp_var);
    
      reg_calib_data->par_p6 = BMP3_CONCAT_BYTES(reg_data[14],  reg_data[13]);
      temp_var = 64.0f;
      quantized_calib_data->par_p6 = ((double)reg_calib_data->par_p6 / temp_var);
    
      reg_calib_data->par_p7 = (int8_t)reg_data[15];
      temp_var = 256.0f;
      quantized_calib_data->par_p7 = ((double)reg_calib_data->par_p7 / temp_var);
    
      reg_calib_data->par_p8 = (int8_t)reg_data[16];
      temp_var = 32768.0f;
      quantized_calib_data->par_p8 = ((double)reg_calib_data->par_p8 / temp_var);
    
      reg_calib_data->par_p9 = (int16_t)BMP3_CONCAT_BYTES(reg_data[18], reg_data[17]);
      temp_var = 281474976710656.0f;
      quantized_calib_data->par_p9 = ((double)reg_calib_data->par_p9 / temp_var);
    
      reg_calib_data->par_p10 = (int8_t)reg_data[19];
      temp_var = 281474976710656.0f;
      quantized_calib_data->par_p10 = ((double)reg_calib_data->par_p10 / temp_var);
    
      reg_calib_data->par_p11 = (int8_t)reg_data[20];
      temp_var = 36893488147419103232.0f;
      quantized_calib_data->par_p11 = ((double)reg_calib_data->par_p11 / temp_var);
    }
    
    /*!
     * @brief This internal API is used to compensate the raw temperature data and
     * return the compensated temperature data in double data type.
     */
    double compensate_temperature(const struct bmp3_uncomp_data *uncomp_data,
                struct bmp3_calib_data *calib_data)
    {
      //printf("Compensate Temperature &&&&&&&&&&&&&&&&&&&&&\n");
      uint32_t uncomp_temp = uncomp_data->temperature;
      double partial_data1;
      double partial_data2;
    
      partial_data1 = (double)(uncomp_temp - calib_data->quantized_calib_data.par_t1);
      partial_data1 = (double)(uncomp_temp - calib_data->quantized_calib_data.par_t1);
      partial_data2 = (double)(partial_data1 * calib_data->quantized_calib_data.par_t2);
      /* Update the compensated temperature in calib structure since this is
         needed for pressure calculation */
      calib_data->quantized_calib_data.t_lin = partial_data2 + (partial_data1 * partial_data1)
                  * calib_data->quantized_calib_data.par_t3;
    
      /* Return compensated temperature */
      return calib_data->quantized_calib_data.t_lin;
    }
    
    /*!
     * @brief This internal API is used to compensate the raw pressure data and
     * return the compensated pressure data in double data type.
     */
    
    double compensate_pressure(const struct bmp3_uncomp_data *uncomp_data,
              const struct bmp3_calib_data *calib_data)
    {
      const struct bmp3_quantized_calib_data *quantized_calib_data = &calib_data->quantized_calib_data;
      /* Variable to store the compensated pressure */
      double comp_press;
      /* Temporary variables used for compensation */
      double partial_data1;
      double partial_data2;
      double partial_data3;
      double partial_data4;
      double partial_out1;
      double partial_out2;
      
      partial_data1 = quantized_calib_data->par_p6 * quantized_calib_data->t_lin;
      partial_data2 = quantized_calib_data->par_p7 * bmp3_pow(quantized_calib_data->t_lin, 2);
      partial_data3 = quantized_calib_data->par_p8 * bmp3_pow(quantized_calib_data->t_lin, 3);
      partial_out1 = quantized_calib_data->par_p5 + partial_data1 + partial_data2 + partial_data3;
      
      
      partial_data1 = quantized_calib_data->par_p2 * quantized_calib_data->t_lin;
      partial_data2 = quantized_calib_data->par_p3 * bmp3_pow(quantized_calib_data->t_lin, 2);
      partial_data3 = quantized_calib_data->par_p4 * bmp3_pow(quantized_calib_data->t_lin, 3);
      partial_out2 = uncomp_data->pressure *
          (quantized_calib_data->par_p1 + partial_data1 + partial_data2 + partial_data3);
          
      
      
      partial_data1 = bmp3_pow((double)uncomp_data->pressure, 2);
      partial_data2 = quantized_calib_data->par_p9 + quantized_calib_data->par_p10 * quantized_calib_data->t_lin;
      partial_data3 = partial_data1 * partial_data2;
      partial_data4 = partial_data3 + bmp3_pow((double)uncomp_data->pressure, 3) * quantized_calib_data->par_p11;
      comp_press = partial_out1 + partial_out2 + partial_data4;
      return comp_press;
    }
    /*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
    /*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
    //float pow(float x, float y){
    
    //}
    //double pow(double x, double n){
    //  double ret = x;
    //  int i;
    //  if(n){
    //    for(i=0;i<n-1;i++){
    //      ret = x*ret;
    //    }
    //  }
    //  else{
    //    ret = 1;
    //  }
    //  return ret;
    //}
    
    uint8_t * readRaw(int check){
        int8_t rslt;
        uint8_t reg_data[BMP3_P_T_DATA_LEN] = {0};
        struct bmp3_uncomp_data uncomp_data = {0};
        rslt = bmp3_get_regs(dev1,BMP3_DATA_ADDR, reg_data, BMP3_P_T_DATA_LEN);
        parse_sensor_data(reg_data, &uncomp_data);
        printf("Raw Reading --------------------- \n");
        if(check == 0){
        return uncomp_data.temperature;
        }
        else if(check == 1){
            return uncomp_data.pressure;
        }
        else{
            return reg_data;
        }
    }
    float  readRaw1(int check){
        int8_t rslt;
        uint8_t reg_data[BMP3_P_T_DATA_LEN] = {0};
        struct bmp3_uncomp_data uncomp_data = {0};
        rslt = bmp3_get_regs(dev1,BMP3_DATA_ADDR, reg_data, BMP3_P_T_DATA_LEN);
        parse_sensor_data(reg_data, &uncomp_data);
        printf("Raw Reading --------------------- \n");
        if(check == 0){
        return uncomp_data.temperature;
        }
        else {
            return uncomp_data.pressure;
        }
    }
    
    float readCalibratedAltitude(float seaLevel)
    {
      float pressure = readPressure();
      return (1.0 - pow((float)pressure / seaLevel, 0.190284))* 287.15 / 0.0065;
    }
    
    float readSeaLevel(float altitude)
    {
      float pressure = readPressure();
      printk("Pressure while sealevel = %d\n",pressure);
      return (pressure / pow(1.0 - (altitude / 44330.0), 5.255));
    }
    
    float readAltitude(void)
    {
      float pressure = readPressure();
      return (1.0 - pow((float)pressure / 101325, 0.190284)) * 287.15 / 0.0065;
    }
    
    void INTEnable(){
      uint8_t reg_data = 0x40;
      uint8_t reg_addr = BMP3_INT_CTRL_ADDR;
      bmp3_set_regs(dev1,&reg_addr, &reg_data, 1);
    }
    /*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
    /*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
    /*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
    float sealevel;
    
    static int bme280_sample_fetch(const struct device *dev,
    			       enum sensor_channel chan)
    {
    	struct bme280_data *data = to_data(dev);
    	uint8_t buf[6] = {0};
            //struct bmp3_uncomp_data uncomp_data = {0};
    
    	int32_t adc_press, adc_temp, adc_humidity;
    	int size = 6;
    	int ret;
    
    	__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);
    
    #ifdef CONFIG_BME280_MODE_FORCED
    	ret = bme280_reg_write(dev, BME280_REG_CTRL_MEAS, BME280_CTRL_MEAS_VAL);
    	if (ret < 0) {
    		return ret;
    	}
    
    	do {
    		k_sleep(K_MSEC(3));
    		ret = bme280_reg_read(dev, BME280_REG_STATUS, buf, 1);
    		if (ret < 0) {
    			return ret;
    		}
    	} while (buf[0] & 0x08);
    #endif        
            data->comp_temp = readTemperature();
            //data->comp_press = readCalibratedAltitude(sealevel);
            data->comp_press = readPressure();
            int k = 2;
            float press,temp;
            if(k==0 | k==1){
              if(k == 0){
               temp = readRaw1(k);
                printf("------------------- Temperature -------------------- = %f\n",temp);
              }
              else{
              press = readRaw1(k);
              printf("------------------- Pressure -------------------- = %f\n",press);
              }
            }
            else{
            uint8_t *myarr = readRaw(k);
            printf("------------------- ARRAY --------------------\n");
            for(int i = 0; i < 6; i++)
              {
                printf("%X\n",myarr[i]);
              }
            }
            //data->comp_press = readAltitude();
    	//if (data->chip_id == BME280_CHIP_ID) {
    	//	size = 8;
    	//}
    	//ret = bme280_reg_read(dev, BME280_REG_PRESS_MSB, buf, size);
    	//if (ret < 0) {
    	//	return ret;
    	//}
            
    
    	return 0;
    }
    
    static int bme280_channel_get(const struct device *dev,
    			      enum sensor_channel chan,
    			      struct sensor_value *val)
    {
    	struct bme280_data *data = to_data(dev);
    	switch (chan) {
    	case SENSOR_CHAN_AMBIENT_TEMP:
    		/*
    		 * data->comp_temp has a resolution of 0.01 degC.  So
    		 * 5123 equals 51.23 degC.
    		 */
    
                            //data->comp_temp = readTemperature();
    
    		val->val1 = data->comp_temp;
    		val->val2 = data->comp_temp; //% 100.0 * 10000.0;
    		break;
    	case SENSOR_CHAN_PRESS:
    		/*
    		 * data->comp_press has 24 integer bits and 8
    		 * fractional.  Output value of 24674867 represents
    		 * 24674867/256 = 96386.2 Pa = 963.862 hPa
    		 */
                    //data->comp_press = readPressure();
    		//val->val1 = (data->comp_press >> 8)/1000U;
                    //data->comp_press = readCalibratedAltitude(sealevel);
                    //data->comp_press = readAltitude();
    
                    val->val1 = data->comp_press;
                    //val->val2 = (data->comp_press >> 8) % 1000.0 * 1000U + (((data->comp_press & 0xff) * 1000U) >> 8);
    		break;
    	case SENSOR_CHAN_HUMIDITY:
    		/*
    		 * data->comp_humidity has 22 integer bits and 10
    		 * fractional.  Output value of 47445 represents
    		 * 47445/1024 = 46.333 %RH
    		 */
    		//val->val1 = (data->comp_humidity >> 10);
    		//val->val2 = (((data->comp_humidity & 0x3ff) * 1000U * 1000U) >> 10);
    		break;
    	default:
    		return -EINVAL;
    	}
    
    	return 0;
    }
    
    static const struct sensor_driver_api bme280_api_funcs = {
    	.sample_fetch = bme280_sample_fetch,
    	.channel_get = bme280_channel_get,
    };
    
    static int bme280_read_compensation(const struct device *dev)
    {
    	//struct bme280_data *data = to_data(dev);
            struct bme280_data *data = to_data(dev);
    	uint16_t buf[21];
    	//uint8_t hbuf[7];
    	int err = 0;
            //printf("Size of Bufer Data = %i\n",sizeof(buf));
    	err = bme280_reg_read(dev, BME280_REG_COMP_START,
    			      buf, sizeof(buf));
           
    	if (err < 0) {
    		LOG_DBG("COMP_START read failed: %d", err);
    		return err;
    	}
    	return 0;
    }
    
    static int bme280_chip_init(const struct device *dev)
    {
    	struct bme280_data *data = to_data(dev);
    	int err;
    
            printk("------------------ Getting Started ----------------- \n");
            printf("%x, %x, %x\n",dev->api,dev->config,dev->data);
            printf("%x, %x, %x\n",dev1->api,dev1->config,dev1->data);
    
    	err = bme280_reg_read(dev, BME280_REG_ID, &data->chip_id, 1);
    	if (err < 0) {
    		LOG_DBG("ID read failed: %d", err);
    		return err;
    	}
    
    	if (data->chip_id == BME280_CHIP_ID) {
    		LOG_DBG("ID OK");
    	}
    	 else {
    		LOG_DBG("bad chip id 0x%x", data->chip_id);
    		return -ENOTSUP;
    	}
    
    	//err = bme280_read_compensation(dev);
    	//if (err < 0) {
    	//	return err;
    	//}
    
    	return 0;
    }
    
    #if BME280_BUS_SPI
    static inline int bme280_is_on_spi(const struct device *dev)
    {
    	return to_config(dev)->reg_io == &bme280_reg_io_spi;
    }
    
    static inline int bme280_spi_init(const struct device *dev)
    {
    	struct bme280_data *data = to_data(dev);
    	const struct bme280_spi_cfg *spi_cfg = to_bus_config(dev)->spi_cfg;
    
    	if (spi_cfg->cs_gpios_label != NULL) {
    		data->spi_cs.gpio_dev = device_get_binding(
    			spi_cfg->cs_gpios_label);
    		if (!data->spi_cs.gpio_dev) {
    			LOG_DBG("can't get GPIO SPI CS device %s",
    				spi_cfg->cs_gpios_label);
    			return -ENODEV;
    		}
    	} else {
    		LOG_DBG("no chip select set");
    	}
    
    	return 0;
    }
    #else
    static inline int bme280_is_on_spi(const struct device *dev)
    {
    	return 0;
    }
    
    static inline int bme280_spi_init(const struct device *dev)
    {
    	return 0;
    }
    #endif
    void set_iic_addr(uint8_t addr){
    _addr = addr;
    }
    
    int bme280_init(const struct device *dev)
    {
    	const char *name = dev->name;
    	struct bme280_data *data = to_data(dev);
    	const struct bme280_config *config = to_config(dev);
    	int rc;
            int *ptr=&dev1;
            *ptr = dev;
    	LOG_DBG("initializing %s", name);
    
    	data->bus = device_get_binding(config->bus_label);
    	if (!data->bus) {
    		LOG_DBG("bus \"%s\" not found", config->bus_label);
    		rc = -EINVAL;
    		goto done;
    	}
    
    	if (bme280_is_on_spi(dev)) {
    		rc = bme280_spi_init(dev);
    		if (rc < 0) {
    			rc = -EINVAL;
    			goto done;
    		}
    	}
    
    	rc = bme280_chip_init(dev);
    	if (rc < 0) {
    		rc = -EINVAL;
    		goto done;
    	}
    
    	rc = 0;
    
    done:
    	if (rc == 0) {
    		LOG_DBG("%s OK", name);
    	} else {
    		LOG_DBG("%s failed", name);
    	}
            set_iic_addr(BMP3_I2C_ADDR_PRIM);
            devv.dev_id = _addr;
            devv.intf = BMP3_I2C_INTF;
    
      int8_t rslt;
      uint8_t chip_id = 0;
      /* Read the chip-id of bmp3 sensor */
    
      devv.dev_id = _addr;
      rslt = bmp3_get_regs(dev1,BMP3_CHIP_ID_ADDR, &chip_id, 1);
      /* Proceed if everything is fine until now */
    
        /******************* Power Settings *******************/
        rslt = bmp3_set_regs(dev1,BMP3_PWR_CTRL_ADDR, 33, 1); // Or 33 Hex
        rslt = bmp3_set_regs(dev1,BMP3_OSR_ADDR, 0, 1); // Or 000000 Hex
        K_MSEC(5);
      if (rslt == BMP3_OK) {
        /* Check for chip id validity */
        if (chip_id == BMP3_CHIP_ID) {
          devv.chip_id = chip_id;
          /* Reset the sensor */
          rslt = reset(dev1);
          if (rslt == BMP3_OK) {
            /* Read the calibration data */
            printf("Calibrating\n");
            rslt = get_calib_data(dev1);
          }
        } else {
          rslt = BMP3_E_DEV_NOT_FOUND;
          return rslt;
        }
      }
    
      //set_config();
    
        uint8_t cmd_rdy_status;
        bmp3_get_regs(dev1,BMP3_SENS_STATUS_REG_ADDR, &cmd_rdy_status, 1);
       printf("Sensor Stataus register = %X, Value = %X\n",BMP3_SENS_STATUS_REG_ADDR,cmd_rdy_status);
    //    uint8_t reg_return;
    //      uint8_t reg_data;
    //rslt = bmp3_get_regs(dev1,BMP3_PWR_CTRL_ADDR, &reg_data, 1);
    //    printf("PWR Control Settings READ Return = %d, Register = %X, Reg_Data = %d\n",rslt,BMP3_PWR_CTRL_ADDR,reg_data);
        
    //rslt = bmp3_get_regs(dev1,BMP3_PWR_CTRL_ADDR, &reg_return, 1);
    //    printf("Write Power Mode Returned = %d, Register = %X, Reg data = %d\n",rslt, BMP3_PWR_CTRL_ADDR,reg_return);
    
    
    
    
            sealevel = readSeaLevel(920);
            printf("Sealevel = %f\n",sealevel);
    
    	return rc;
    
    }
    
    /*
     * Device creation macro, shared by BME280_DEFINE_SPI() and
     * BME280_DEFINE_I2C().
     */
    
    #define BME280_DEVICE_INIT(inst)					\
    	DEVICE_AND_API_INIT(bme280_##inst,				\
    			    DT_INST_LABEL(inst),			\
    			    bme280_init,				\
    			    &bme280_data_##inst,			\
    			    &bme280_config_##inst,			\
    			    POST_KERNEL,				\
    			    CONFIG_SENSOR_INIT_PRIORITY,		\
    			    &bme280_api_funcs);
    
    /*
     * Instantiation macros used when a device is on a SPI bus.
     */
    
    #define BME280_HAS_CS(inst) DT_INST_SPI_DEV_HAS_CS_GPIOS(inst)
    
    #define BME280_DATA_SPI_CS(inst)					\
    	{ .spi_cs = {							\
    		.gpio_pin = DT_INST_SPI_DEV_CS_GPIOS_PIN(inst),		\
    		.gpio_dt_flags = DT_INST_SPI_DEV_CS_GPIOS_FLAGS(inst),	\
    		},							\
    	}
    
    #define BME280_DATA_SPI(inst)						\
    	COND_CODE_1(BME280_HAS_CS(inst),				\
    		    (BME280_DATA_SPI_CS(inst)),				\
    		    ({}))
    
    #define BME280_SPI_CS_PTR(inst)						\
    	COND_CODE_1(BME280_HAS_CS(inst),				\
    		    (&(bme280_data_##inst.spi_cs)),			\
    		    (NULL))
    
    #define BME280_SPI_CS_LABEL(inst)					\
    	COND_CODE_1(BME280_HAS_CS(inst),				\
    		    (DT_INST_SPI_DEV_CS_GPIOS_LABEL(inst)), (NULL))
    
    #define BME280_SPI_CFG(inst)						\
    	(&(struct bme280_spi_cfg) {					\
    		.spi_cfg = {						\
    			.frequency =					\
    				DT_INST_PROP(inst, spi_max_frequency),	\
    			.operation = (SPI_WORD_SET(8) |			\
    				      SPI_TRANSFER_MSB |		\
    				      SPI_MODE_CPOL |			\
    				      SPI_MODE_CPHA),			\
    			.slave = DT_INST_REG_ADDR(inst),		\
    			.cs = BME280_SPI_CS_PTR(inst),			\
    		},							\
    		.cs_gpios_label = BME280_SPI_CS_LABEL(inst),		\
    	})
    
    #define BME280_CONFIG_SPI(inst)						\
    	{								\
    		.bus_label = DT_INST_BUS_LABEL(inst),			\
    		.reg_io = &bme280_reg_io_spi,				\
    		.bus_config = { .spi_cfg = BME280_SPI_CFG(inst)	}	\
    	}
    
    #define BME280_DEFINE_SPI(inst)						\
    	static struct bme280_data bme280_data_##inst =			\
    		BME280_DATA_SPI(inst);					\
    	static const struct bme280_config bme280_config_##inst =	\
    		BME280_CONFIG_SPI(inst);				\
    	BME280_DEVICE_INIT(inst)
    
    /*
     * Instantiation macros used when a device is on an I2C bus.
     */
    
    #define BME280_CONFIG_I2C(inst)						\
    	{								\
    		.bus_label = DT_INST_BUS_LABEL(inst),			\
    		.reg_io = &bme280_reg_io_i2c,				\
    		.bus_config =  { .i2c_addr = DT_INST_REG_ADDR(inst), }	\
    	}
    
    #define BME280_DEFINE_I2C(inst)						\
    	static struct bme280_data bme280_data_##inst;			\
    	static const struct bme280_config bme280_config_##inst =	\
    		BME280_CONFIG_I2C(inst);				\
    	BME280_DEVICE_INIT(inst)
    
    /*
     * Main instantiation macro. Use of COND_CODE_1() selects the right
     * bus-specific macro at preprocessor time.
     */
    
    #define BME280_DEFINE(inst)						\
    	COND_CODE_1(DT_INST_ON_BUS(inst, spi),				\
    		    (BME280_DEFINE_SPI(inst)),				\
    		    (BME280_DEFINE_I2C(inst)))
    
    DT_INST_FOREACH_STATUS_OKAY(BME280_DEFINE)
    bme280.h

  • new said:
    Arduino reads the same address with length 6 and gets different value from register and it is changing but nrf52840 gets different value and unchanging. (I have used i2c1 in board overlay)

     Can you use a logic analyzer to check the data that is being sent and received in both cases? Check the SDA and SCL pins.

Related