sensor: bmm150: Add I2C-base or SPI-base interface in build time
move DT_DRV_COMPAT to bmm150.h. so that can be decide which interface to use. define struct bmm150_bus_io interface for bmm150_i2c.c and bmm150_spi.c in bmm150.h. redefined bus operation interface in bmm150.c, this allow the driver to decide which interface to use during construction. Signed-off-by: Weiwei Guo <guoweiwei@syriusrobotics.com>
This commit is contained in:
parent
012ae578e1
commit
08ece57b9e
9 changed files with 326 additions and 68 deletions
|
|
@ -1,5 +1,4 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library()
|
||||
|
||||
zephyr_library_sources(bmm150.c)
|
||||
zephyr_library_sources(bmm150.c bmm150_i2c.c bmm150_spi.c)
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT bosch_bmm150
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
#include "bmm150.h"
|
||||
|
||||
|
|
@ -36,15 +34,59 @@ static const struct bmm150_preset {
|
|||
[BMM150_HIGH_ACCURACY_PRESET] = { 47, 83, 20 }
|
||||
};
|
||||
|
||||
static inline int bmm150_bus_check(const struct device *dev)
|
||||
{
|
||||
const struct bmm150_config *cfg = dev->config;
|
||||
|
||||
return cfg->bus_io->check(&cfg->bus);
|
||||
}
|
||||
|
||||
static inline int bmm150_reg_read(const struct device *dev,
|
||||
uint8_t start, uint8_t *buf, int size)
|
||||
{
|
||||
const struct bmm150_config *cfg = dev->config;
|
||||
|
||||
return cfg->bus_io->read(&cfg->bus, start, buf, size);
|
||||
}
|
||||
|
||||
static inline int bmm150_reg_write(const struct device *dev, uint8_t reg,
|
||||
uint8_t val)
|
||||
{
|
||||
const struct bmm150_config *cfg = dev->config;
|
||||
|
||||
return cfg->bus_io->write(&cfg->bus, reg, val);
|
||||
}
|
||||
|
||||
int bmm150_reg_update_byte(const struct device *dev, uint8_t reg,
|
||||
uint8_t mask, uint8_t value)
|
||||
{
|
||||
int ret = 0;
|
||||
uint8_t old_value, new_value;
|
||||
|
||||
ret = bmm150_reg_read(dev, reg, &old_value, 1);
|
||||
|
||||
if (ret < 0) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
new_value = (old_value & ~mask) | (value & mask);
|
||||
|
||||
if (new_value == old_value) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return bmm150_reg_write(dev, reg, new_value);
|
||||
failed:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bmm150_set_power_mode(const struct device *dev,
|
||||
enum bmm150_power_modes mode,
|
||||
int state)
|
||||
{
|
||||
const struct bmm150_config *config = dev->config;
|
||||
|
||||
switch (mode) {
|
||||
case BMM150_POWER_MODE_SUSPEND:
|
||||
if (i2c_reg_update_byte_dt(&config->i2c,
|
||||
if (bmm150_reg_update_byte(dev,
|
||||
BMM150_REG_POWER,
|
||||
BMM150_MASK_POWER_CTL,
|
||||
!state) < 0) {
|
||||
|
|
@ -54,14 +96,14 @@ static int bmm150_set_power_mode(const struct device *dev,
|
|||
|
||||
return 0;
|
||||
case BMM150_POWER_MODE_SLEEP:
|
||||
return i2c_reg_update_byte_dt(&config->i2c,
|
||||
return bmm150_reg_update_byte(dev,
|
||||
BMM150_REG_OPMODE_ODR,
|
||||
BMM150_MASK_OPMODE,
|
||||
BMM150_MODE_SLEEP <<
|
||||
BMM150_SHIFT_OPMODE);
|
||||
break;
|
||||
case BMM150_POWER_MODE_NORMAL:
|
||||
return i2c_reg_update_byte_dt(&config->i2c,
|
||||
return bmm150_reg_update_byte(dev,
|
||||
BMM150_REG_OPMODE_ODR,
|
||||
BMM150_MASK_OPMODE,
|
||||
BMM150_MODE_NORMAL <<
|
||||
|
|
@ -75,12 +117,11 @@ static int bmm150_set_power_mode(const struct device *dev,
|
|||
|
||||
static int bmm150_set_odr(const struct device *dev, uint8_t val)
|
||||
{
|
||||
const struct bmm150_config *config = dev->config;
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0U; i < ARRAY_SIZE(bmm150_samp_freq_table); ++i) {
|
||||
if (val <= bmm150_samp_freq_table[i].freq) {
|
||||
return i2c_reg_update_byte_dt(&config->i2c,
|
||||
return bmm150_reg_update_byte(dev,
|
||||
BMM150_REG_OPMODE_ODR,
|
||||
BMM150_MASK_ODR,
|
||||
(bmm150_samp_freq_table[i].reg_val <<
|
||||
|
|
@ -97,8 +138,7 @@ static int bmm150_read_rep_xy(const struct device *dev)
|
|||
const struct bmm150_config *config = dev->config;
|
||||
uint8_t reg_val;
|
||||
|
||||
if (i2c_reg_read_byte_dt(&config->i2c,
|
||||
BMM150_REG_REP_XY, ®_val) < 0) {
|
||||
if (bmm150_reg_read(dev, BMM150_REG_REP_XY, ®_val, 1) < 0) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
|
@ -113,8 +153,7 @@ static int bmm150_read_rep_z(const struct device *dev)
|
|||
const struct bmm150_config *config = dev->config;
|
||||
uint8_t reg_val;
|
||||
|
||||
if (i2c_reg_read_byte_dt(&config->i2c,
|
||||
BMM150_REG_REP_Z, ®_val) < 0) {
|
||||
if (bmm150_reg_read(dev, BMM150_REG_REP_Z, ®_val, 1) < 0) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
|
@ -160,8 +199,7 @@ static int bmm150_read_odr(const struct device *dev)
|
|||
const struct bmm150_config *config = dev->config;
|
||||
uint8_t i, odr_val, reg_val;
|
||||
|
||||
if (i2c_reg_read_byte_dt(&config->i2c,
|
||||
BMM150_REG_OPMODE_ODR, ®_val) < 0) {
|
||||
if (bmm150_reg_read(dev, BMM150_REG_OPMODE_ODR, ®_val, 1) < 0) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
|
@ -184,7 +222,7 @@ static int bmm150_write_rep_xy(const struct device *dev, int val)
|
|||
struct bmm150_data *data = dev->data;
|
||||
const struct bmm150_config *config = dev->config;
|
||||
|
||||
if (i2c_reg_update_byte_dt(&config->i2c,
|
||||
if (bmm150_reg_update_byte(dev,
|
||||
BMM150_REG_REP_XY,
|
||||
BMM150_REG_REP_DATAMASK,
|
||||
BMM150_REPXY_TO_REGVAL(val)) < 0) {
|
||||
|
|
@ -203,7 +241,7 @@ static int bmm150_write_rep_z(const struct device *dev, int val)
|
|||
struct bmm150_data *data = dev->data;
|
||||
const struct bmm150_config *config = dev->config;
|
||||
|
||||
if (i2c_reg_update_byte_dt(&config->i2c,
|
||||
if (bmm150_reg_update_byte(dev,
|
||||
BMM150_REG_REP_Z,
|
||||
BMM150_REG_REP_DATAMASK,
|
||||
BMM150_REPZ_TO_REGVAL(val)) < 0) {
|
||||
|
|
@ -286,7 +324,6 @@ static int bmm150_sample_fetch(const struct device *dev,
|
|||
{
|
||||
|
||||
struct bmm150_data *drv_data = dev->data;
|
||||
const struct bmm150_config *config = dev->config;
|
||||
uint16_t values[BMM150_AXIS_XYZR_MAX];
|
||||
int16_t raw_x, raw_y, raw_z;
|
||||
uint16_t rhall;
|
||||
|
|
@ -294,9 +331,7 @@ static int bmm150_sample_fetch(const struct device *dev,
|
|||
__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL ||
|
||||
chan == SENSOR_CHAN_MAGN_XYZ);
|
||||
|
||||
if (i2c_burst_read_dt(&config->i2c,
|
||||
BMM150_REG_X_L, (uint8_t *)values,
|
||||
sizeof(values)) < 0) {
|
||||
if (bmm150_reg_read(dev, BMM150_REG_X_L, (uint8_t *)values, sizeof(values)) < 0) {
|
||||
LOG_ERR("failed to read sample");
|
||||
return -EIO;
|
||||
}
|
||||
|
|
@ -483,28 +518,31 @@ static const struct sensor_driver_api bmm150_api_funcs = {
|
|||
static int bmm150_init_chip(const struct device *dev)
|
||||
{
|
||||
struct bmm150_data *data = dev->data;
|
||||
const struct bmm150_config *config = dev->config;
|
||||
uint8_t chip_id;
|
||||
struct bmm150_preset preset;
|
||||
|
||||
if (bmm150_set_power_mode(dev, BMM150_POWER_MODE_NORMAL, 0) < 0) {
|
||||
LOG_ERR("failed to bring up device from normal mode");
|
||||
return -EIO;
|
||||
/* Soft reset chip */
|
||||
if (bmm150_reg_update_byte(dev, BMM150_REG_POWER, BMM150_MASK_SOFT_RESET,
|
||||
BMM150_SOFT_RESET) < 0) {
|
||||
LOG_ERR("failed reset chip");
|
||||
goto err_poweroff;
|
||||
}
|
||||
|
||||
if (bmm150_set_power_mode(dev, BMM150_POWER_MODE_SUSPEND, 1) < 0) {
|
||||
LOG_ERR("failed to bring up device in suspend mode");
|
||||
return -EIO;
|
||||
}
|
||||
/* Sleep for 1ms after software reset */
|
||||
k_sleep(K_MSEC(1));
|
||||
|
||||
/* Suspend mode to sleep mode */
|
||||
if (bmm150_set_power_mode(dev, BMM150_POWER_MODE_SUSPEND, 0)
|
||||
< 0) {
|
||||
LOG_ERR("failed to bring up device from suspend mode");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (i2c_reg_read_byte_dt(&config->i2c,
|
||||
BMM150_REG_CHIP_ID, &chip_id) < 0) {
|
||||
/* Sleep for 3ms from suspend to sleep mode */
|
||||
k_sleep(K_MSEC(3));
|
||||
|
||||
/* Read chip ID */
|
||||
if (bmm150_reg_read(dev, BMM150_REG_CHIP_ID, &chip_id, 1) < 0) {
|
||||
LOG_ERR("failed reading chip id");
|
||||
goto err_poweroff;
|
||||
}
|
||||
|
|
@ -514,6 +552,7 @@ static int bmm150_init_chip(const struct device *dev)
|
|||
goto err_poweroff;
|
||||
}
|
||||
|
||||
/* Setting preset mode */
|
||||
preset = bmm150_presets_table[BMM150_DEFAULT_PRESET];
|
||||
if (bmm150_set_odr(dev, preset.odr) < 0) {
|
||||
LOG_ERR("failed to set ODR to %d",
|
||||
|
|
@ -521,30 +560,27 @@ static int bmm150_init_chip(const struct device *dev)
|
|||
goto err_poweroff;
|
||||
}
|
||||
|
||||
if (i2c_reg_write_byte_dt(&config->i2c,
|
||||
BMM150_REG_REP_XY,
|
||||
BMM150_REPXY_TO_REGVAL(preset.rep_xy))
|
||||
if (bmm150_reg_write(dev, BMM150_REG_REP_XY, BMM150_REPXY_TO_REGVAL(preset.rep_xy))
|
||||
< 0) {
|
||||
LOG_ERR("failed to set REP XY to %d",
|
||||
preset.rep_xy);
|
||||
goto err_poweroff;
|
||||
}
|
||||
|
||||
if (i2c_reg_write_byte_dt(&config->i2c,
|
||||
BMM150_REG_REP_Z,
|
||||
BMM150_REPZ_TO_REGVAL(preset.rep_z)) < 0) {
|
||||
if (bmm150_reg_write(dev, BMM150_REG_REP_Z, BMM150_REPZ_TO_REGVAL(preset.rep_z)) < 0) {
|
||||
LOG_ERR("failed to set REP Z to %d",
|
||||
preset.rep_z);
|
||||
goto err_poweroff;
|
||||
}
|
||||
|
||||
/* Set chip normal mode */
|
||||
if (bmm150_set_power_mode(dev, BMM150_POWER_MODE_NORMAL, 1)
|
||||
< 0) {
|
||||
LOG_ERR("failed to power on device");
|
||||
}
|
||||
|
||||
if (i2c_burst_read_dt(&config->i2c,
|
||||
BMM150_REG_TRIM_START, (uint8_t *)&data->tregs,
|
||||
/* Reads the trim registers of the sensor */
|
||||
if (bmm150_reg_read(dev, BMM150_REG_TRIM_START, (uint8_t *)&data->tregs,
|
||||
sizeof(data->tregs)) < 0) {
|
||||
LOG_ERR("failed to read trim regs");
|
||||
goto err_poweroff;
|
||||
|
|
@ -574,12 +610,12 @@ err_poweroff:
|
|||
|
||||
static int bmm150_init(const struct device *dev)
|
||||
{
|
||||
const struct bmm150_config *const config =
|
||||
dev->config;
|
||||
int err = 0;
|
||||
|
||||
if (!device_is_ready(config->i2c.bus)) {
|
||||
LOG_ERR("I2C bus device not ready");
|
||||
return -ENODEV;
|
||||
err = bmm150_bus_check(dev);
|
||||
if (err < 0) {
|
||||
LOG_DBG("bus check failed: %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (bmm150_init_chip(dev) < 0) {
|
||||
|
|
@ -590,15 +626,37 @@ static int bmm150_init(const struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define BMM150_DEFINE(inst) \
|
||||
static struct bmm150_data bmm150_data_##inst; \
|
||||
\
|
||||
static const struct bmm150_config bmm150_config_##inst = { \
|
||||
.i2c = I2C_DT_SPEC_INST_GET(inst), \
|
||||
}; \
|
||||
\
|
||||
SENSOR_DEVICE_DT_INST_DEFINE(inst, bmm150_init, NULL, \
|
||||
&bmm150_data_##inst, &bmm150_config_##inst, POST_KERNEL, \
|
||||
CONFIG_SENSOR_INIT_PRIORITY, &bmm150_api_funcs); \
|
||||
/* Initializes a struct bmm150_config for an instance on a SPI bus. */
|
||||
#define BMM150_CONFIG_SPI(inst) \
|
||||
.bus.spi = SPI_DT_SPEC_INST_GET(inst, BMM150_SPI_OPERATION, 0), \
|
||||
.bus_io = &bmm150_bus_io_spi,
|
||||
|
||||
/* Initializes a struct bmm150_config for an instance on an I2C bus. */
|
||||
#define BMM150_CONFIG_I2C(inst) \
|
||||
.bus.i2c = I2C_DT_SPEC_INST_GET(inst), \
|
||||
.bus_io = &bmm150_bus_io_i2c,
|
||||
|
||||
#define BMM150_BUS_CFG(inst) \
|
||||
COND_CODE_1(DT_INST_ON_BUS(inst, i2c), \
|
||||
(BMM150_CONFIG_I2C(inst)), \
|
||||
(BMM150_CONFIG_SPI(inst)))
|
||||
|
||||
/*
|
||||
* Main instantiation macro, which selects the correct bus-specific
|
||||
* instantiation macros for the instance.
|
||||
*/
|
||||
#define BMM150_DEFINE(inst) \
|
||||
static struct bmm150_data bmm150_data_##inst; \
|
||||
static const struct bmm150_config bmm150_config_##inst = { \
|
||||
BMM150_BUS_CFG(inst) \
|
||||
}; \
|
||||
SENSOR_DEVICE_DT_INST_DEFINE(inst, \
|
||||
bmm150_init, NULL, \
|
||||
&bmm150_data_##inst, \
|
||||
&bmm150_config_##inst, \
|
||||
POST_KERNEL, \
|
||||
CONFIG_SENSOR_INIT_PRIORITY, \
|
||||
&bmm150_api_funcs);
|
||||
|
||||
/* Create the struct device for every status "okay" node in the devicetree. */
|
||||
DT_INST_FOREACH_STATUS_OKAY(BMM150_DEFINE)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,47 @@
|
|||
#ifndef ZEPHYR_DRIVERS_SENSOR_BMM150_BMM150_H_
|
||||
#define ZEPHYR_DRIVERS_SENSOR_BMM150_BMM150_H_
|
||||
|
||||
#include <zephyr/types.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/drivers/spi.h>
|
||||
#include <zephyr/drivers/i2c.h>
|
||||
|
||||
#define DT_DRV_COMPAT bosch_bmm150
|
||||
|
||||
#define BMM150_BUS_SPI DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
|
||||
#define BMM150_BUS_I2C DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
|
||||
|
||||
union bmm150_bus {
|
||||
#if BMM150_BUS_SPI
|
||||
struct spi_dt_spec spi;
|
||||
#endif
|
||||
#if BMM150_BUS_I2C
|
||||
struct i2c_dt_spec i2c;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef int (*bmm150_bus_check_fn)(const union bmm150_bus *bus);
|
||||
typedef int (*bmm150_reg_read_fn)(const union bmm150_bus *bus,
|
||||
uint8_t start, uint8_t *buf, int size);
|
||||
typedef int (*bmm150_reg_write_fn)(const union bmm150_bus *bus,
|
||||
uint8_t reg, uint8_t val);
|
||||
|
||||
struct bmm150_bus_io {
|
||||
bmm150_bus_check_fn check;
|
||||
bmm150_reg_read_fn read;
|
||||
bmm150_reg_write_fn write;
|
||||
};
|
||||
|
||||
#if BMM150_BUS_SPI
|
||||
#define BMM150_SPI_OPERATION (SPI_WORD_SET(8) | SPI_TRANSFER_MSB | \
|
||||
SPI_MODE_CPOL | SPI_MODE_CPHA)
|
||||
extern const struct bmm150_bus_io bmm150_bus_io_spi;
|
||||
#endif
|
||||
|
||||
#if BMM150_BUS_I2C
|
||||
extern const struct bmm150_bus_io bmm150_bus_io_i2c;
|
||||
#endif
|
||||
|
||||
#include <zephyr/types.h>
|
||||
#include <zephyr/drivers/i2c.h>
|
||||
|
|
@ -41,6 +82,8 @@
|
|||
|
||||
#define BMM150_REG_POWER 0x4B
|
||||
#define BMM150_MASK_POWER_CTL BIT(0)
|
||||
#define BMM150_MASK_SOFT_RESET (BIT(1) | BIT(7))
|
||||
#define BMM150_SOFT_RESET 0x81
|
||||
|
||||
#define BMM150_REG_OPMODE_ODR 0x4C
|
||||
#define BMM150_MASK_OPMODE (BIT(2) | BIT(1))
|
||||
|
|
@ -66,7 +109,7 @@
|
|||
#define BMM150_REGVAL_TO_REPXY(regval) (((regval) * 2) + 1)
|
||||
#define BMM150_REGVAL_TO_REPZ(regval) ((regval) + 1)
|
||||
#define BMM150_REPXY_TO_REGVAL(rep) (((rep) - 1) / 2)
|
||||
#define BMM150_REPZ_TO_REGVAL(rep) ((rep) - 1)
|
||||
#define BMM150_REPZ_TO_REGVAL(rep) BMM150_REPXY_TO_REGVAL(rep)
|
||||
|
||||
#define BMM150_REG_INT 0x4D
|
||||
|
||||
|
|
@ -92,11 +135,6 @@
|
|||
#define BMM150_MAGN_SET_ATTR
|
||||
#endif
|
||||
|
||||
|
||||
struct bmm150_config {
|
||||
struct i2c_dt_spec i2c;
|
||||
};
|
||||
|
||||
struct bmm150_trim_regs {
|
||||
int8_t x1;
|
||||
int8_t y1;
|
||||
|
|
@ -114,6 +152,11 @@ struct bmm150_trim_regs {
|
|||
uint8_t xy1;
|
||||
} __packed;
|
||||
|
||||
struct bmm150_config {
|
||||
union bmm150_bus bus;
|
||||
const struct bmm150_bus_io *bus_io;
|
||||
};
|
||||
|
||||
struct bmm150_data {
|
||||
struct k_sem sem;
|
||||
struct bmm150_trim_regs tregs;
|
||||
|
|
@ -153,4 +196,7 @@ enum bmm150_presets {
|
|||
#define BMM150_DEFAULT_PRESET BMM150_HIGH_ACCURACY_PRESET
|
||||
#endif
|
||||
|
||||
int bmm150_reg_update_byte(const struct device *dev, uint8_t reg,
|
||||
uint8_t mask, uint8_t value);
|
||||
|
||||
#endif /* __SENSOR_BMM150_H__ */
|
||||
|
|
|
|||
40
drivers/sensor/bmm150/bmm150_i2c.c
Normal file
40
drivers/sensor/bmm150/bmm150_i2c.c
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017 Intel Corporation
|
||||
* Copyright (c) 2017 IpTronix S.r.l.
|
||||
* Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Bus-specific functionality for BMM150s accessed via I2C.
|
||||
*/
|
||||
|
||||
#include "bmm150.h"
|
||||
|
||||
#if BMM150_BUS_I2C
|
||||
|
||||
static int bmm150_bus_check_i2c(const union bmm150_bus *bus)
|
||||
{
|
||||
return i2c_is_ready_dt(&bus->i2c) ? 0 : -ENODEV;
|
||||
}
|
||||
|
||||
static int bmm150_reg_read_i2c(const union bmm150_bus *bus,
|
||||
uint8_t start, uint8_t *buf, int size)
|
||||
{
|
||||
return i2c_burst_read_dt(&bus->i2c, start, buf, size);
|
||||
}
|
||||
|
||||
static int bmm150_reg_write_i2c(const union bmm150_bus *bus,
|
||||
uint8_t reg, uint8_t val)
|
||||
{
|
||||
return i2c_reg_write_byte_dt(&bus->i2c, reg, val);
|
||||
}
|
||||
|
||||
const struct bmm150_bus_io bmm150_bus_io_i2c = {
|
||||
.check = bmm150_bus_check_i2c,
|
||||
.read = bmm150_reg_read_i2c,
|
||||
.write = bmm150_reg_write_i2c,
|
||||
};
|
||||
|
||||
#endif /* BMM150_BUS_I2C */
|
||||
93
drivers/sensor/bmm150/bmm150_spi.c
Normal file
93
drivers/sensor/bmm150/bmm150_spi.c
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017 Intel Corporation
|
||||
* Copyright (c) 2017 IpTronix S.r.l.
|
||||
* Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Bus-specific functionality for BMM150s accessed via SPI.
|
||||
*/
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
#include "bmm150.h"
|
||||
|
||||
#if BMM150_BUS_SPI
|
||||
|
||||
LOG_MODULE_DECLARE(BMM150, CONFIG_SENSOR_LOG_LEVEL);
|
||||
|
||||
static int bmm150_bus_check_spi(const union bmm150_bus *bus)
|
||||
{
|
||||
return spi_is_ready_dt(&bus->spi) ? 0 : -ENODEV;
|
||||
}
|
||||
|
||||
static int bmm150_reg_read_spi(const union bmm150_bus *bus,
|
||||
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 = ARRAY_SIZE(rx_buf)
|
||||
};
|
||||
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_dt(&bus->spi, &tx, &rx);
|
||||
if (ret) {
|
||||
LOG_DBG("spi_transceive FAIL %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bmm150_reg_write_spi(const union bmm150_bus *bus,
|
||||
uint8_t reg, uint8_t val)
|
||||
{
|
||||
uint8_t cmd[] = { reg & 0x7F, val };
|
||||
const struct spi_buf tx_buf = {
|
||||
.buf = cmd,
|
||||
.len = sizeof(cmd)
|
||||
};
|
||||
const struct spi_buf_set tx = {
|
||||
.buffers = &tx_buf,
|
||||
.count = 1
|
||||
};
|
||||
int ret;
|
||||
|
||||
ret = spi_write_dt(&bus->spi, &tx);
|
||||
if (ret) {
|
||||
LOG_DBG("spi_write FAIL %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct bmm150_bus_io bmm150_bus_io_spi = {
|
||||
.check = bmm150_bus_check_spi,
|
||||
.read = bmm150_reg_read_spi,
|
||||
.write = bmm150_reg_write_spi,
|
||||
};
|
||||
|
||||
#endif /* BMM150_BUS_SPI */
|
||||
10
dts/bindings/sensor/bosch,bmm150-i2c.yaml
Normal file
10
dts/bindings/sensor/bosch,bmm150-i2c.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# Copyright (c) 2019, Linaro Limited
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: |
|
||||
Bosch BMM150 Geomagnetic sensor. See more info at:
|
||||
https://www.bosch-sensortec.com/bst/products/all_products/bmm150
|
||||
|
||||
compatible: "bosch,bmm150"
|
||||
|
||||
include: ["i2c-device.yaml", "bosch,bmm150.yaml"]
|
||||
10
dts/bindings/sensor/bosch,bmm150-spi.yaml
Normal file
10
dts/bindings/sensor/bosch,bmm150-spi.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# Copyright (c) 2019, Linaro Limited
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: |
|
||||
Bosch BMM150 Geomagnetic sensor. See more info at:
|
||||
https://www.bosch-sensortec.com/bst/products/all_products/bmm150
|
||||
|
||||
compatible: "bosch,bmm150"
|
||||
|
||||
include: ["spi-device.yaml", "bosch,bmm150.yaml"]
|
||||
|
|
@ -1,10 +1,6 @@
|
|||
# Copyright (c) 2019, Linaro Limited
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: |
|
||||
Bosch BMM150 Geomagnetic sensor. See more info at:
|
||||
https://www.bosch-sensortec.com/bst/products/all_products/bmm150
|
||||
# Common fields for BMM150
|
||||
|
||||
compatible: "bosch,bmm150"
|
||||
|
||||
include: [sensor-device.yaml, i2c-device.yaml]
|
||||
include: sensor-device.yaml
|
||||
|
|
|
|||
|
|
@ -354,3 +354,9 @@ test_spi_max31865: max31865@2a {
|
|||
high-threshold = <32767>;
|
||||
filter-50hz;
|
||||
};
|
||||
|
||||
test_spi_bmm150: bmm150@2b {
|
||||
compatible = "bosch,bmm150";
|
||||
reg = <0x2b>;
|
||||
spi-max-frequency = <0>;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue