sensor: hmc5883l: convert to device tree
This commit converts the existing hcm5883l 3-axis magnetometer driver to use device tree for the I2C and GPIO selection. It also adds a basic sample application for this sensor, using the frdm-k64f development board to demonstrate how the interrupt GPIO pin and I2C bus can be selected. Signed-off-by: Kevin Townsend <kevin@ktownsend.com>
This commit is contained in:
parent
30fc72a50e
commit
740f6868a5
12 changed files with 166 additions and 62 deletions
|
@ -9,19 +9,6 @@ menuconfig HMC5883L
|
|||
|
||||
if HMC5883L
|
||||
|
||||
config HMC5883L_NAME
|
||||
string "Driver name"
|
||||
default "HMC5883L"
|
||||
help
|
||||
Device name with which the HMC5883L sensor is identified.
|
||||
|
||||
config HMC5883L_I2C_MASTER_DEV_NAME
|
||||
string "I2C master where HMC5883L is connected"
|
||||
default "I2C_0"
|
||||
help
|
||||
Specify the device name of the I2C master device to which HMC5883L
|
||||
is connected.
|
||||
|
||||
choice
|
||||
prompt "Trigger mode"
|
||||
default HMC5883L_TRIGGER_GLOBAL_THREAD
|
||||
|
@ -46,22 +33,6 @@ endchoice
|
|||
config HMC5883L_TRIGGER
|
||||
bool
|
||||
|
||||
config HMC5883L_GPIO_DEV_NAME
|
||||
string "GPIO device"
|
||||
default "GPIO_0"
|
||||
depends on HMC5883L_TRIGGER
|
||||
help
|
||||
The device name of the GPIO device to which the HMC5883L interrupt
|
||||
pin is connected.
|
||||
|
||||
config HMC5883L_GPIO_PIN_NUM
|
||||
int "Interrupt GPIO pin number"
|
||||
default 0
|
||||
depends on HMC5883L_TRIGGER
|
||||
help
|
||||
The number of the GPIO on which the interrupt signal from the
|
||||
HMC5883L chip will be received.
|
||||
|
||||
config HMC5883L_THREAD_PRIORITY
|
||||
int "Thread priority"
|
||||
depends on HMC5883L_TRIGGER_OWN_THREAD
|
||||
|
|
|
@ -59,7 +59,8 @@ static int hmc5883l_sample_fetch(struct device *dev, enum sensor_channel chan)
|
|||
__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);
|
||||
|
||||
/* fetch magnetometer sample */
|
||||
if (i2c_burst_read(drv_data->i2c, HMC5883L_I2C_ADDR,
|
||||
if (i2c_burst_read(drv_data->i2c,
|
||||
DT_INST_0_HONEYWELL_HMC5883L_BASE_ADDRESS,
|
||||
HMC5883L_REG_DATA_START, (u8_t *)buf, 6) < 0) {
|
||||
LOG_ERR("Failed to fetch megnetometer sample.");
|
||||
return -EIO;
|
||||
|
@ -85,15 +86,17 @@ int hmc5883l_init(struct device *dev)
|
|||
struct hmc5883l_data *drv_data = dev->driver_data;
|
||||
u8_t chip_cfg[3], id[3], idx;
|
||||
|
||||
drv_data->i2c = device_get_binding(CONFIG_HMC5883L_I2C_MASTER_DEV_NAME);
|
||||
drv_data->i2c = device_get_binding(
|
||||
DT_INST_0_HONEYWELL_HMC5883L_BUS_NAME);
|
||||
if (drv_data->i2c == NULL) {
|
||||
LOG_ERR("Failed to get pointer to %s device.",
|
||||
CONFIG_HMC5883L_I2C_MASTER_DEV_NAME);
|
||||
DT_INST_0_HONEYWELL_HMC5883L_BUS_NAME);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* check chip ID */
|
||||
if (i2c_burst_read(drv_data->i2c, HMC5883L_I2C_ADDR,
|
||||
if (i2c_burst_read(drv_data->i2c,
|
||||
DT_INST_0_HONEYWELL_HMC5883L_BASE_ADDRESS,
|
||||
HMC5883L_REG_CHIP_ID, id, 3) < 0) {
|
||||
LOG_ERR("Failed to read chip ID.");
|
||||
return -EIO;
|
||||
|
@ -136,7 +139,8 @@ int hmc5883l_init(struct device *dev)
|
|||
chip_cfg[1] = drv_data->gain_idx << HMC5883L_GAIN_SHIFT;
|
||||
chip_cfg[2] = HMC5883L_MODE_CONTINUOUS;
|
||||
|
||||
if (i2c_burst_write(drv_data->i2c, HMC5883L_I2C_ADDR,
|
||||
if (i2c_burst_write(drv_data->i2c,
|
||||
DT_INST_0_HONEYWELL_HMC5883L_BASE_ADDRESS,
|
||||
HMC5883L_REG_CONFIG_A, chip_cfg, 3) < 0) {
|
||||
LOG_ERR("Failed to configure chip.");
|
||||
return -EIO;
|
||||
|
@ -154,6 +158,6 @@ int hmc5883l_init(struct device *dev)
|
|||
|
||||
struct hmc5883l_data hmc5883l_driver;
|
||||
|
||||
DEVICE_AND_API_INIT(hmc5883l, CONFIG_HMC5883L_NAME, hmc5883l_init,
|
||||
&hmc5883l_driver, NULL, POST_KERNEL,
|
||||
DEVICE_AND_API_INIT(hmc5883l, DT_INST_0_HONEYWELL_HMC5883L_LABEL,
|
||||
hmc5883l_init, &hmc5883l_driver, NULL, POST_KERNEL,
|
||||
CONFIG_SENSOR_INIT_PRIORITY, &hmc5883l_driver_api);
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
#include <zephyr/types.h>
|
||||
#include <drivers/gpio.h>
|
||||
|
||||
#define HMC5883L_I2C_ADDR 0x1E
|
||||
|
||||
#define HMC5883L_REG_CONFIG_A 0x00
|
||||
#define HMC5883L_ODR_SHIFT 2
|
||||
|
||||
|
@ -30,11 +28,11 @@
|
|||
#define HMC5883L_CHIP_ID_B '4'
|
||||
#define HMC5883L_CHIP_ID_C '3'
|
||||
|
||||
static const char * const hmc5883l_odr_strings[] = {
|
||||
static const char *const hmc5883l_odr_strings[] = {
|
||||
"0.75", "1.5", "3", "7.5", "15", "30", "75"
|
||||
};
|
||||
|
||||
static const char * const hmc5883l_fs_strings[] = {
|
||||
static const char *const hmc5883l_fs_strings[] = {
|
||||
"0.88", "1.3", "1.9", "2.5", "4", "4.7", "5.6", "8.1"
|
||||
};
|
||||
|
||||
|
|
|
@ -23,7 +23,8 @@ int hmc5883l_trigger_set(struct device *dev,
|
|||
|
||||
__ASSERT_NO_MSG(trig->type == SENSOR_TRIG_DATA_READY);
|
||||
|
||||
gpio_pin_disable_callback(drv_data->gpio, CONFIG_HMC5883L_GPIO_PIN_NUM);
|
||||
gpio_pin_disable_callback(drv_data->gpio,
|
||||
DT_INST_0_HONEYWELL_HMC5883L_INT_GPIOS_PIN);
|
||||
|
||||
drv_data->data_ready_handler = handler;
|
||||
if (handler == NULL) {
|
||||
|
@ -32,7 +33,8 @@ int hmc5883l_trigger_set(struct device *dev,
|
|||
|
||||
drv_data->data_ready_trigger = *trig;
|
||||
|
||||
gpio_pin_enable_callback(drv_data->gpio, CONFIG_HMC5883L_GPIO_PIN_NUM);
|
||||
gpio_pin_enable_callback(drv_data->gpio,
|
||||
DT_INST_0_HONEYWELL_HMC5883L_INT_GPIOS_PIN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -45,7 +47,8 @@ static void hmc5883l_gpio_callback(struct device *dev,
|
|||
|
||||
ARG_UNUSED(pins);
|
||||
|
||||
gpio_pin_disable_callback(dev, CONFIG_HMC5883L_GPIO_PIN_NUM);
|
||||
gpio_pin_disable_callback(dev,
|
||||
DT_INST_0_HONEYWELL_HMC5883L_INT_GPIOS_PIN);
|
||||
|
||||
#if defined(CONFIG_HMC5883L_TRIGGER_OWN_THREAD)
|
||||
k_sem_give(&drv_data->gpio_sem);
|
||||
|
@ -64,7 +67,8 @@ static void hmc5883l_thread_cb(void *arg)
|
|||
&drv_data->data_ready_trigger);
|
||||
}
|
||||
|
||||
gpio_pin_enable_callback(drv_data->gpio, CONFIG_HMC5883L_GPIO_PIN_NUM);
|
||||
gpio_pin_enable_callback(drv_data->gpio,
|
||||
DT_INST_0_HONEYWELL_HMC5883L_INT_GPIOS_PIN);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HMC5883L_TRIGGER_OWN_THREAD
|
||||
|
@ -97,20 +101,22 @@ int hmc5883l_init_interrupt(struct device *dev)
|
|||
struct hmc5883l_data *drv_data = dev->driver_data;
|
||||
|
||||
/* setup data ready gpio interrupt */
|
||||
drv_data->gpio = device_get_binding(CONFIG_HMC5883L_GPIO_DEV_NAME);
|
||||
drv_data->gpio = device_get_binding(
|
||||
DT_INST_0_HONEYWELL_HMC5883L_INT_GPIOS_CONTROLLER);
|
||||
if (drv_data->gpio == NULL) {
|
||||
LOG_ERR("Failed to get pointer to %s device.",
|
||||
CONFIG_HMC5883L_GPIO_DEV_NAME);
|
||||
DT_INST_0_HONEYWELL_HMC5883L_INT_GPIOS_CONTROLLER);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
gpio_pin_configure(drv_data->gpio, CONFIG_HMC5883L_GPIO_PIN_NUM,
|
||||
gpio_pin_configure(drv_data->gpio,
|
||||
DT_INST_0_HONEYWELL_HMC5883L_INT_GPIOS_PIN,
|
||||
GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE |
|
||||
GPIO_INT_ACTIVE_LOW | GPIO_INT_DEBOUNCE);
|
||||
|
||||
gpio_init_callback(&drv_data->gpio_cb,
|
||||
hmc5883l_gpio_callback,
|
||||
BIT(CONFIG_HMC5883L_GPIO_PIN_NUM));
|
||||
BIT(DT_INST_0_HONEYWELL_HMC5883L_INT_GPIOS_PIN));
|
||||
|
||||
if (gpio_add_callback(drv_data->gpio, &drv_data->gpio_cb) < 0) {
|
||||
LOG_ERR("Failed to set gpio callback.");
|
||||
|
@ -130,7 +136,8 @@ int hmc5883l_init_interrupt(struct device *dev)
|
|||
drv_data->dev = dev;
|
||||
#endif
|
||||
|
||||
gpio_pin_enable_callback(drv_data->gpio, CONFIG_HMC5883L_GPIO_PIN_NUM);
|
||||
gpio_pin_enable_callback(drv_data->gpio,
|
||||
DT_INST_0_HONEYWELL_HMC5883L_INT_GPIOS_PIN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
17
dts/bindings/sensor/honeywell,hmc5883l.yaml
Normal file
17
dts/bindings/sensor/honeywell,hmc5883l.yaml
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Copyright (c) 2019 Linaro Limited
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
title: Honeywell MEMS sensors HMC5883L
|
||||
|
||||
description: |
|
||||
This binding gives a base representation of the HMC5883L 3-axis
|
||||
magnetometer sensor
|
||||
|
||||
compatible: "honeywell,hmc5883l"
|
||||
|
||||
include: i2c-device.yaml
|
||||
|
||||
properties:
|
||||
int-gpios:
|
||||
type: phandle-array
|
||||
required: false
|
8
samples/sensor/hmc5883l/CMakeLists.txt
Normal file
8
samples/sensor/hmc5883l/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.13.1)
|
||||
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
|
||||
project(hmc5883l)
|
||||
|
||||
FILE(GLOB app_sources src/*.c)
|
||||
target_sources(app PRIVATE ${app_sources})
|
5
samples/sensor/hmc5883l/README.txt
Normal file
5
samples/sensor/hmc5883l/README.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
Title: hmc5883l
|
||||
|
||||
Description:
|
||||
|
||||
A simple example using the hmc5883l 3-axis magnetometer sensor.
|
14
samples/sensor/hmc5883l/boards/frdm_k64f.overlay
Normal file
14
samples/sensor/hmc5883l/boards/frdm_k64f.overlay
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Linaro Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
&i2c0 {
|
||||
hmc5883l@1e {
|
||||
compatible = "honeywell,hmc5883l";
|
||||
reg = <0x1E>;
|
||||
int-gpios = <&gpioc 12 0>;
|
||||
label = "HMC5883L";
|
||||
};
|
||||
};
|
5
samples/sensor/hmc5883l/prj.conf
Normal file
5
samples/sensor/hmc5883l/prj.conf
Normal file
|
@ -0,0 +1,5 @@
|
|||
CONFIG_I2C=y
|
||||
CONFIG_GPIO=y
|
||||
CONFIG_SENSOR=y
|
||||
CONFIG_HMC5883L=y
|
||||
CONFIG_HMC5883L_TRIGGER_GLOBAL_THREAD=y
|
8
samples/sensor/hmc5883l/sample.yaml
Normal file
8
samples/sensor/hmc5883l/sample.yaml
Normal file
|
@ -0,0 +1,8 @@
|
|||
sample:
|
||||
name: HMC5883L Sensor Sample
|
||||
tests:
|
||||
sample.sensor.hmc5883l:
|
||||
harness: sensor
|
||||
tags: sensors
|
||||
depends_on: i2c gpio
|
||||
filter: dt_compat_enabled("honeywell,hmc5883l")
|
58
samples/sensor/hmc5883l/src/main.c
Normal file
58
samples/sensor/hmc5883l/src/main.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Linaro Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <device.h>
|
||||
#include <drivers/sensor.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/printk.h>
|
||||
|
||||
|
||||
static s32_t read_sensor(struct device *sensor)
|
||||
{
|
||||
struct sensor_value val[3];
|
||||
s32_t ret = 0;
|
||||
|
||||
ret = sensor_sample_fetch(sensor);
|
||||
if (ret) {
|
||||
printk("sensor_sample_fetch failed ret %d\n", ret);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = sensor_channel_get(sensor, SENSOR_CHAN_MAGN_XYZ, val);
|
||||
if (ret < 0) {
|
||||
printf("Cannot read sensor channels\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
printf("( x y z ) = ( %f %f %f )\n", sensor_value_to_double(&val[0]),
|
||||
sensor_value_to_double(&val[1]),
|
||||
sensor_value_to_double(&val[2]));
|
||||
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
dev = device_get_binding(DT_INST_0_HONEYWELL_HMC5883L_LABEL);
|
||||
|
||||
if (dev == NULL) {
|
||||
printk("Could not get %s device at I2C addr 0x%02X\n",
|
||||
DT_INST_0_HONEYWELL_HMC5883L_LABEL,
|
||||
DT_INST_0_HONEYWELL_HMC5883L_BASE_ADDRESS);
|
||||
return;
|
||||
}
|
||||
|
||||
printk("device is %p, name is %s\n", dev, dev->config->name);
|
||||
|
||||
while (1) {
|
||||
read_sensor(dev);
|
||||
k_sleep(K_MSEC(1000));
|
||||
}
|
||||
}
|
|
@ -399,6 +399,15 @@
|
|||
#define DT_INST_0_BOSCH_BMC150_MAGN_DRDY_GPIOS_PIN 0
|
||||
#endif
|
||||
|
||||
#ifndef DT_INST_0_HONEYWELL_HMC5883L_LABEL
|
||||
#define DT_INST_0_HONEYWELL_HMC5883L_LABEL ""
|
||||
#define DT_INST_0_HONEYWELL_HMC5883L_BASE_ADDRESS 0
|
||||
#define DT_INST_0_HONEYWELL_HMC5883L_BUS_NAME ""
|
||||
#define DT_INST_0_HONEYWELL_HMC5883L_INT_GPIOS_CONTROLLER ""
|
||||
#define DT_INST_0_HONEYWELL_HMC5883L_INT_GPIOS_FLAGS 0
|
||||
#define DT_INST_0_HONEYWELL_HMC5883L_INT_GPIOS_PIN 0
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_HAS_DTS_I2C */
|
||||
|
||||
#ifndef DT_ADXL372_DEV_NAME
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue