Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BMA280 Sample Code #22198

Closed
md-jamal opened this issue Jan 25, 2020 · 8 comments
Closed

BMA280 Sample Code #22198

md-jamal opened this issue Jan 25, 2020 · 8 comments
Assignees
Labels

Comments

@md-jamal
Copy link

Hi Guys,
I see we have BMA280 Support in zephyrproject/zephyr/drivers/sensor/bma280, but there is no sample in Samples folder.

So, i tried to create a sample project for it.

  1. Created a folder in samples/sensor/bma280.
  2. Copied CMakeLists.txt from samples/sensor/bme280
  3. Created prj.conf file with the following content:
CONFIG_STDOUT_CONSOLE=y
CONFIG_I2C=y
CONFIG_SENSOR=y
CONFIG_BMA280=y
  1. Created sam_e70_xplained.overlay file with the following content:
&i2c0 {
  bma280@18 {
    label = "bma280";
    compatible = "bosch,bma280";
    #address-cells = <1>;
    #size-cells = <1>;
    reg = <0x18>;
  };
};

  1. Created src folder and inside it main.c with the following content.
/*
 * Copyright (c) 2012-2014 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <device.h>
#include <drivers/sensor.h>

void main(void)
{
	struct device *dev = device_get_binding(CONFIG_BMA280_NAME);
	printk("BMA280 Name:%s\n", CONFIG_BMA280_NAME);
	if (dev == NULL) {
		printk("Could not get BMA280 device\n");
		return;
	}

	printk("dev %p name %s\n", dev, dev->config->name);

	while (1) {
		static struct sensor_value accel_x, accel_y, accel_z;
		sensor_sample_fetch(dev);
		sensor_channel_get(dev, SENSOR_CHAN_ACCEL_X, &accel_x);
		sensor_channel_get(dev, SENSOR_CHAN_ACCEL_Y, &accel_y);
		sensor_channel_get(dev, SENSOR_CHAN_ACCEL_Z, &accel_z);


		printk("x:%u\t y:%u\t z:%u\n", accel_x.val1, accel_y.val1, accel_z.val1);

		k_sleep(K_MSEC(1000));
	}
}

Flashing the program and seeing the console logs. it fails with "Could not get BMA280 device"
There is some silly mistake i made, can you please help me in it.

@LeBlue
Copy link

LeBlue commented Jan 27, 2020

The device_get_binding fails, if some driver is not complied in or if the sensor cannot be initialized, that is at least the chip id register cannot be read via I2C or returns an unexpected value.

The bma280 has two variants, default and bmc150 (differentiated in chip id). Additionally the i2c address differs for different packages (e.g. bmx055 contains 3 different sensors with one of them being bma280 compatible) and wiring (up to 3 pins pulled low or high on reset on bmx055, 1 pin on plain bma280).

I2C address and variant are configured via Kconfig (old style) or device tree (new style), this was changed in:
1a5368a

For the I2C address and chip id you have to look it up in the sensor data sheet. If you cannot find out the wiring, just try different adresses in the data sheet.

I once put this together for the calliope_mini board which has a bmx055 with integrated bma280/bmc-150 variant, which i got to work by adjusting the parameters mentioned above: https://github.com/LeBlue/zephyr/commits/board-calliope-mini
It was done with the old style Kconfig.

@md-jamal
Copy link
Author

I pulled the latest changes and move to device tree option.

/*
 * Copyright (c) 2012-2014 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <device.h>
#include <drivers/sensor.h>

void main(void)
{
	struct device *dev = device_get_binding(DT_INST_0_BOSCH_BMA280_LABEL);
	printk("BMA280 Name:%s\n", DT_INST_0_BOSCH_BMA280_LABEL);
	if (dev == NULL) {
		printk("Could not get BME280 device\n");
		return;
	}

	printk("dev %p name %s\n", dev, dev->config->name);

	while (1) {
		static struct sensor_value accel_x, accel_y, accel_z;
		sensor_sample_fetch(dev);
		sensor_channel_get(dev, SENSOR_CHAN_ACCEL_X, &accel_x);
		sensor_channel_get(dev, SENSOR_CHAN_ACCEL_Y, &accel_y);
		sensor_channel_get(dev, SENSOR_CHAN_ACCEL_Z, &accel_z);


		printk("x:%u\t y:%u\t z:%u\n", accel_x.val1, accel_y.val1, accel_z.val1);

		k_sleep(K_MSEC(1000));
	}
}

Device Tree correctly specifies the I2C Address which is 0x18 in my case.

DT_ATMEL_SAM_I2C_TWIHS_40018000_BOSCH_BMA280_18_BASE_ADDRESS=0x18
DT_INST_0_BOSCH_BMA280_BASE_ADDRESS=0x18
# Specifies that the driver should adapt to the accelerometer
# capability provided by the BMC150 6-axis eCompass.  This affects
# the chip ID and the resolution of the measurements.
DT_ATMEL_SAM_I2C_TWIHS_40018000_BOSCH_BMA280_18_IS_BMC150=0
DT_INST_0_BOSCH_BMA280_IS_BMC150=0
# Human readable string describing the device (used by Zephyr for API name)
DT_ATMEL_SAM_I2C_TWIHS_40018000_BOSCH_BMA280_18_LABEL="bma280"
DT_INST_0_BOSCH_BMA280_LABEL="bma280"
DT_ATMEL_SAM_I2C_TWIHS_40018000_BOSCH_BMA280_18_BUS_NAME="I2C_0"
DT_INST_0_BOSCH_BMA280_BUS_NAME="I2C_0"
DT_BOSCH_BMA280_BUS_I2C=1
DT_INST_0_BOSCH_BMA280=1

It still fails at the same stage: device_get_binding.. Any more inputs to debug will be appreciated. Is there any way to check whether a particular address is present or not , like i2cdetect on linux

@LeBlue
Copy link

LeBlue commented Jan 28, 2020

@md-jamal either set a breakpoint on bma280_init or enable the sensor debug messages: https://docs.zephyrproject.org/latest/reference/kconfig/choice_168.html#choice-168

@md-jamal
Copy link
Author

How can we set a breakpoint in zephyr? Sorry i just started using zephyr

@md-jamal
Copy link
Author

I got it working after adding the following into device tree overlay.

&i2c0 {
  bma280@18 {
    label = "bma280";
    compatible = "bosch,bma280";
    #address-cells = <1>;
    #size-cells = <1>;
    reg = <0x18>;
    status = "okay";
    is-bmc150; 
    int1-gpios = <&portb 3 0>;
  };
};

I want to use the interrupt mechanism, i don't want to continuously poll for data, i have added int1-gpios in overlay, what all modifications i should make it to switch to interrupt.

@md-jamal
Copy link
Author

I am looking into drivers/sensor/bma280/Kconfig file
What does this mean?

config BMA280_TRIGGER
	bool

@MaureenHelm
Copy link
Member

This is a hidden (internal) Kconfig symbol that gets selected when you set CONFIG_BMA280_TRIGGER_GLOBAL_THREAD=y or CONFIG_BMA280_TRIGGER_OWN_THREAD=y in your application. You need to set one of them to use the sensor interrupt.

@MaureenHelm MaureenHelm self-assigned this Jul 21, 2020
@github-actions
Copy link

This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants