drivers/sensor: lis2mdl: Add multi-instance support
Add multi-instance support and make use of the stmemsc i2c/spi read/write routine that has been introduced to simplify the ST sensor drivers code. Moreover, move spi-full-duplex property from Kconfig inside Device Tree, so that each LIS2MDL instance can be configured selectively in accordance to how it is used in h/w. Signed-off-by: Armando Visconti <armando.visconti@st.com>
This commit is contained in:
parent
34fb892fb5
commit
fcb0953309
10 changed files with 210 additions and 351 deletions
|
@ -13,10 +13,6 @@ if SPI
|
||||||
config SPI_STM32_INTERRUPT
|
config SPI_STM32_INTERRUPT
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config LIS2MDL_SPI_FULL_DUPLEX
|
|
||||||
default y
|
|
||||||
depends on LIS2MDL
|
|
||||||
|
|
||||||
endif # SPI
|
endif # SPI
|
||||||
|
|
||||||
endif # BOARD_SENSORTILE_BOX
|
endif # BOARD_SENSORTILE_BOX
|
||||||
|
|
|
@ -158,6 +158,7 @@
|
||||||
lis2mdl@0 {
|
lis2mdl@0 {
|
||||||
compatible = "st,lis2mdl";
|
compatible = "st,lis2mdl";
|
||||||
spi-max-frequency = <1000000>;
|
spi-max-frequency = <1000000>;
|
||||||
|
spi-full-duplex;
|
||||||
reg = <0>;
|
reg = <0>;
|
||||||
label = "LIS2MDL";
|
label = "LIS2MDL";
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,6 +6,6 @@
|
||||||
|
|
||||||
zephyr_library()
|
zephyr_library()
|
||||||
zephyr_library_sources_ifdef(CONFIG_LIS2MDL lis2mdl.c)
|
zephyr_library_sources_ifdef(CONFIG_LIS2MDL lis2mdl.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_LIS2MDL lis2mdl_i2c.c)
|
|
||||||
zephyr_library_sources_ifdef(CONFIG_LIS2MDL lis2mdl_spi.c)
|
|
||||||
zephyr_library_sources_ifdef(CONFIG_LIS2MDL_TRIGGER lis2mdl_trigger.c)
|
zephyr_library_sources_ifdef(CONFIG_LIS2MDL_TRIGGER lis2mdl_trigger.c)
|
||||||
|
|
||||||
|
zephyr_library_include_directories(../stmemsc)
|
||||||
|
|
|
@ -53,8 +53,4 @@ config LIS2MDL_MAG_ODR_RUNTIME
|
||||||
bool "Set magnetometer sampling frequency (ODR) at runtime (default: 10 Hz)"
|
bool "Set magnetometer sampling frequency (ODR) at runtime (default: 10 Hz)"
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config LIS2MDL_SPI_FULL_DUPLEX
|
|
||||||
bool "Enable SPI 4wire mode (separated MISO and MOSI lines)"
|
|
||||||
depends on SPI
|
|
||||||
|
|
||||||
endif # LIS2MDL
|
endif # LIS2MDL
|
||||||
|
|
|
@ -34,7 +34,8 @@ LOG_MODULE_REGISTER(LIS2MDL, CONFIG_SENSOR_LOG_LEVEL);
|
||||||
static int lis2mdl_set_odr(const struct device *dev,
|
static int lis2mdl_set_odr(const struct device *dev,
|
||||||
const struct sensor_value *val)
|
const struct sensor_value *val)
|
||||||
{
|
{
|
||||||
struct lis2mdl_data *lis2mdl = dev->data;
|
const struct lis2mdl_config *cfg = dev->config;
|
||||||
|
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
||||||
lis2mdl_odr_t odr;
|
lis2mdl_odr_t odr;
|
||||||
|
|
||||||
switch (val->val1) {
|
switch (val->val1) {
|
||||||
|
@ -54,7 +55,7 @@ static int lis2mdl_set_odr(const struct device *dev,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lis2mdl_data_rate_set(lis2mdl->ctx, odr)) {
|
if (lis2mdl_data_rate_set(ctx, odr)) {
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +67,8 @@ static int lis2mdl_set_hard_iron(const struct device *dev,
|
||||||
enum sensor_channel chan,
|
enum sensor_channel chan,
|
||||||
const struct sensor_value *val)
|
const struct sensor_value *val)
|
||||||
{
|
{
|
||||||
struct lis2mdl_data *lis2mdl = dev->data;
|
const struct lis2mdl_config *cfg = dev->config;
|
||||||
|
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
int16_t offset[3];
|
int16_t offset[3];
|
||||||
|
|
||||||
|
@ -75,7 +77,7 @@ static int lis2mdl_set_hard_iron(const struct device *dev,
|
||||||
val++;
|
val++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return lis2mdl_mag_user_offset_set(lis2mdl->ctx, offset);
|
return lis2mdl_mag_user_offset_set(ctx, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lis2mdl_channel_get_mag(const struct device *dev,
|
static void lis2mdl_channel_get_mag(const struct device *dev,
|
||||||
|
@ -187,9 +189,11 @@ static int get_single_mode_raw_data(const struct device *dev,
|
||||||
int16_t *raw_mag)
|
int16_t *raw_mag)
|
||||||
{
|
{
|
||||||
struct lis2mdl_data *lis2mdl = dev->data;
|
struct lis2mdl_data *lis2mdl = dev->data;
|
||||||
|
const struct lis2mdl_config *cfg = dev->config;
|
||||||
|
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
rc = lis2mdl_operating_mode_set(lis2mdl->ctx, LIS2MDL_SINGLE_TRIGGER);
|
rc = lis2mdl_operating_mode_set(ctx, LIS2MDL_SINGLE_TRIGGER);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
LOG_ERR("set single mode failed");
|
LOG_ERR("set single mode failed");
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -202,7 +206,7 @@ static int get_single_mode_raw_data(const struct device *dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fetch raw data sample */
|
/* fetch raw data sample */
|
||||||
rc = lis2mdl_magnetic_raw_get(lis2mdl->ctx, raw_mag);
|
rc = lis2mdl_magnetic_raw_get(ctx, raw_mag);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
LOG_ERR("Failed to read sample");
|
LOG_ERR("Failed to read sample");
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -213,11 +217,12 @@ static int get_single_mode_raw_data(const struct device *dev,
|
||||||
static int lis2mdl_sample_fetch_mag(const struct device *dev)
|
static int lis2mdl_sample_fetch_mag(const struct device *dev)
|
||||||
{
|
{
|
||||||
struct lis2mdl_data *lis2mdl = dev->data;
|
struct lis2mdl_data *lis2mdl = dev->data;
|
||||||
const struct lis2mdl_config *const config = dev->config;
|
const struct lis2mdl_config *cfg = dev->config;
|
||||||
|
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
||||||
int16_t raw_mag[3];
|
int16_t raw_mag[3];
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (config->single_mode) {
|
if (cfg->single_mode) {
|
||||||
rc = get_single_mode_raw_data(dev, raw_mag);
|
rc = get_single_mode_raw_data(dev, raw_mag);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
LOG_ERR("Failed to read raw data");
|
LOG_ERR("Failed to read raw data");
|
||||||
|
@ -227,7 +232,7 @@ static int lis2mdl_sample_fetch_mag(const struct device *dev)
|
||||||
lis2mdl->mag[1] = sys_le16_to_cpu(raw_mag[1]);
|
lis2mdl->mag[1] = sys_le16_to_cpu(raw_mag[1]);
|
||||||
lis2mdl->mag[2] = sys_le16_to_cpu(raw_mag[2]);
|
lis2mdl->mag[2] = sys_le16_to_cpu(raw_mag[2]);
|
||||||
|
|
||||||
if (config->cancel_offset) {
|
if (cfg->cancel_offset) {
|
||||||
/* The second measurement is needed when offset
|
/* The second measurement is needed when offset
|
||||||
* cancellation is enabled in the single mode. Then the
|
* cancellation is enabled in the single mode. Then the
|
||||||
* average of the first measurement done above and this
|
* average of the first measurement done above and this
|
||||||
|
@ -251,7 +256,7 @@ static int lis2mdl_sample_fetch_mag(const struct device *dev)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* fetch raw data sample */
|
/* fetch raw data sample */
|
||||||
rc = lis2mdl_magnetic_raw_get(lis2mdl->ctx, raw_mag);
|
rc = lis2mdl_magnetic_raw_get(ctx, raw_mag);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
LOG_ERR("Failed to read sample");
|
LOG_ERR("Failed to read sample");
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -266,10 +271,12 @@ static int lis2mdl_sample_fetch_mag(const struct device *dev)
|
||||||
static int lis2mdl_sample_fetch_temp(const struct device *dev)
|
static int lis2mdl_sample_fetch_temp(const struct device *dev)
|
||||||
{
|
{
|
||||||
struct lis2mdl_data *lis2mdl = dev->data;
|
struct lis2mdl_data *lis2mdl = dev->data;
|
||||||
|
const struct lis2mdl_config *cfg = dev->config;
|
||||||
|
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
||||||
int16_t raw_temp;
|
int16_t raw_temp;
|
||||||
|
|
||||||
/* fetch raw temperature sample */
|
/* fetch raw temperature sample */
|
||||||
if (lis2mdl_temperature_raw_get(lis2mdl->ctx, &raw_temp) < 0) {
|
if (lis2mdl_temperature_raw_get(ctx, &raw_temp) < 0) {
|
||||||
LOG_ERR("Failed to read sample");
|
LOG_ERR("Failed to read sample");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
@ -312,70 +319,25 @@ static const struct sensor_driver_api lis2mdl_driver_api = {
|
||||||
.channel_get = lis2mdl_channel_get,
|
.channel_get = lis2mdl_channel_get,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int lis2mdl_init_interface(const struct device *dev)
|
|
||||||
{
|
|
||||||
const struct lis2mdl_config *const config = dev->config;
|
|
||||||
struct lis2mdl_data *lis2mdl = dev->data;
|
|
||||||
|
|
||||||
lis2mdl->bus = device_get_binding(config->master_dev_name);
|
|
||||||
if (!lis2mdl->bus) {
|
|
||||||
LOG_ERR("Could not get pointer to %s device",
|
|
||||||
config->master_dev_name);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return config->bus_init(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct lis2mdl_config lis2mdl_dev_config = {
|
|
||||||
.master_dev_name = DT_INST_BUS_LABEL(0),
|
|
||||||
.single_mode = DT_INST_PROP(0, single_mode),
|
|
||||||
.cancel_offset = DT_INST_PROP(0, cancel_offset),
|
|
||||||
|
|
||||||
#ifdef CONFIG_LIS2MDL_TRIGGER
|
|
||||||
.gpio_name = DT_INST_GPIO_LABEL(0, irq_gpios),
|
|
||||||
.gpio_pin = DT_INST_GPIO_PIN(0, irq_gpios),
|
|
||||||
.gpio_flags = DT_INST_GPIO_FLAGS(0, irq_gpios),
|
|
||||||
#endif /* CONFIG_LIS2MDL_TRIGGER */
|
|
||||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
|
|
||||||
.bus_init = lis2mdl_spi_init,
|
|
||||||
.spi_conf.frequency = DT_INST_PROP(0, spi_max_frequency),
|
|
||||||
.spi_conf.operation = (SPI_OP_MODE_MASTER | SPI_MODE_CPOL |
|
|
||||||
SPI_MODE_CPHA | SPI_WORD_SET(8) |
|
|
||||||
SPI_LINES_SINGLE),
|
|
||||||
.spi_conf.slave = DT_INST_REG_ADDR(0),
|
|
||||||
#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0)
|
|
||||||
.gpio_cs_port = DT_INST_SPI_DEV_CS_GPIOS_LABEL(0),
|
|
||||||
.cs_gpio = DT_INST_SPI_DEV_CS_GPIOS_PIN(0),
|
|
||||||
.cs_gpio_flags = DT_INST_SPI_DEV_CS_GPIOS_FLAGS(0),
|
|
||||||
|
|
||||||
.spi_conf.cs = &lis2mdl_data.cs_ctrl,
|
|
||||||
#else
|
|
||||||
.spi_conf.cs = NULL,
|
|
||||||
#endif
|
|
||||||
#elif DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
|
|
||||||
.bus_init = lis2mdl_i2c_init,
|
|
||||||
.i2c_slv_addr = DT_INST_REG_ADDR(0),
|
|
||||||
#else
|
|
||||||
#error "BUS MACRO NOT DEFINED IN DTS"
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
static int lis2mdl_init(const struct device *dev)
|
static int lis2mdl_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
struct lis2mdl_data *lis2mdl = dev->data;
|
struct lis2mdl_data *lis2mdl = dev->data;
|
||||||
const struct lis2mdl_config *const config = dev->config;
|
const struct lis2mdl_config *cfg = dev->config;
|
||||||
|
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
||||||
uint8_t wai;
|
uint8_t wai;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
lis2mdl->dev = dev;
|
lis2mdl->dev = dev;
|
||||||
|
|
||||||
if (lis2mdl_init_interface(dev)) {
|
if (cfg->spi_4wires) {
|
||||||
return -EINVAL;
|
/* Set SPI 4wires if it's the case */
|
||||||
|
if (lis2mdl_spi_mode_set(ctx, LIS2MDL_SPI_4_WIRE) < 0) {
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check chip ID */
|
/* check chip ID */
|
||||||
if (lis2mdl_device_id_get(lis2mdl->ctx, &wai) < 0) {
|
if (lis2mdl_device_id_get(ctx, &wai) < 0) {
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,37 +347,37 @@ static int lis2mdl_init(const struct device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reset sensor configuration */
|
/* reset sensor configuration */
|
||||||
if (lis2mdl_reset_set(lis2mdl->ctx, PROPERTY_ENABLE) < 0) {
|
if (lis2mdl_reset_set(ctx, PROPERTY_ENABLE) < 0) {
|
||||||
LOG_ERR("s/w reset failed");
|
LOG_ERR("s/w reset failed");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
k_busy_wait(100);
|
k_busy_wait(100);
|
||||||
|
|
||||||
#if CONFIG_LIS2MDL_SPI_FULL_DUPLEX
|
if (cfg->spi_4wires) {
|
||||||
/* After s/w reset set SPI 4wires again if the case */
|
/* After s/w reset set SPI 4wires again if the case */
|
||||||
if (lis2mdl_spi_mode_set(lis2mdl->ctx, LIS2MDL_SPI_4_WIRE) < 0) {
|
if (lis2mdl_spi_mode_set(ctx, LIS2MDL_SPI_4_WIRE) < 0) {
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* enable BDU */
|
/* enable BDU */
|
||||||
if (lis2mdl_block_data_update_set(lis2mdl->ctx, PROPERTY_ENABLE) < 0) {
|
if (lis2mdl_block_data_update_set(ctx, PROPERTY_ENABLE) < 0) {
|
||||||
LOG_ERR("setting bdu failed");
|
LOG_ERR("setting bdu failed");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set Output Data Rate */
|
/* Set Output Data Rate */
|
||||||
if (lis2mdl_data_rate_set(lis2mdl->ctx, LIS2MDL_ODR_10Hz)) {
|
if (lis2mdl_data_rate_set(ctx, LIS2MDL_ODR_10Hz)) {
|
||||||
LOG_ERR("set odr failed");
|
LOG_ERR("set odr failed");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->cancel_offset) {
|
if (cfg->cancel_offset) {
|
||||||
/* Set offset cancellation, common for both single and
|
/* Set offset cancellation, common for both single and
|
||||||
* and continuous mode.
|
* and continuous mode.
|
||||||
*/
|
*/
|
||||||
if (lis2mdl_set_rst_mode_set(lis2mdl->ctx,
|
if (lis2mdl_set_rst_mode_set(ctx,
|
||||||
LIS2MDL_SENS_OFF_CANC_EVERY_ODR)) {
|
LIS2MDL_SENS_OFF_CANC_EVERY_ODR)) {
|
||||||
LOG_ERR("reset sensor mode failed");
|
LOG_ERR("reset sensor mode failed");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
@ -423,16 +385,16 @@ static int lis2mdl_init(const struct device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable temperature compensation */
|
/* Enable temperature compensation */
|
||||||
if (lis2mdl_offset_temp_comp_set(lis2mdl->ctx, PROPERTY_ENABLE)) {
|
if (lis2mdl_offset_temp_comp_set(ctx, PROPERTY_ENABLE)) {
|
||||||
LOG_ERR("enable temp compensation failed");
|
LOG_ERR("enable temp compensation failed");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->cancel_offset && config->single_mode) {
|
if (cfg->cancel_offset && cfg->single_mode) {
|
||||||
/* Set OFF_CANC_ONE_SHOT bit. This setting is only needed in
|
/* Set OFF_CANC_ONE_SHOT bit. This setting is only needed in
|
||||||
* the single-mode when offset cancellation is enabled.
|
* the single-mode when offset cancellation is enabled.
|
||||||
*/
|
*/
|
||||||
rc = lis2mdl_set_rst_sensor_single_set(lis2mdl->ctx,
|
rc = lis2mdl_set_rst_sensor_single_set(ctx,
|
||||||
PROPERTY_ENABLE);
|
PROPERTY_ENABLE);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
LOG_ERR("Set offset cancelaltion failed");
|
LOG_ERR("Set offset cancelaltion failed");
|
||||||
|
@ -440,16 +402,16 @@ static int lis2mdl_init(const struct device *dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->single_mode) {
|
if (cfg->single_mode) {
|
||||||
/* Set drdy on pin 7 */
|
/* Set drdy on pin 7 */
|
||||||
rc = lis2mdl_drdy_on_pin_set(lis2mdl->ctx, 1);
|
rc = lis2mdl_drdy_on_pin_set(ctx, 1);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
LOG_ERR("set drdy on pin failed!");
|
LOG_ERR("set drdy on pin failed!");
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reboot sensor after setting the configuration registers */
|
/* Reboot sensor after setting the configuration registers */
|
||||||
rc = lis2mdl_boot_set(lis2mdl->ctx, 1);
|
rc = lis2mdl_boot_set(ctx, 1);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
LOG_ERR("Reboot failed.");
|
LOG_ERR("Reboot failed.");
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -459,7 +421,7 @@ static int lis2mdl_init(const struct device *dev)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* Set device in continuous mode */
|
/* Set device in continuous mode */
|
||||||
rc = lis2mdl_operating_mode_set(lis2mdl->ctx,
|
rc = lis2mdl_operating_mode_set(ctx,
|
||||||
LIS2MDL_CONTINUOUS_MODE);
|
LIS2MDL_CONTINUOUS_MODE);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
LOG_ERR("set continuos mode failed");
|
LOG_ERR("set continuos mode failed");
|
||||||
|
@ -472,9 +434,11 @@ static int lis2mdl_init(const struct device *dev)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_LIS2MDL_TRIGGER
|
#ifdef CONFIG_LIS2MDL_TRIGGER
|
||||||
if (lis2mdl_init_interrupt(dev) < 0) {
|
if (cfg->trig_enabled) {
|
||||||
LOG_ERR("Failed to initialize interrupts");
|
if (lis2mdl_init_interrupt(dev) < 0) {
|
||||||
return -EIO;
|
LOG_ERR("Failed to initialize interrupts");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -486,14 +450,16 @@ static int lis2mdl_set_power_state(struct lis2mdl_data *lis2mdl,
|
||||||
const struct lis2mdl_config *const config,
|
const struct lis2mdl_config *const config,
|
||||||
uint32_t new_state)
|
uint32_t new_state)
|
||||||
{
|
{
|
||||||
|
const struct lis2mdl_config *cfg = dev->config;
|
||||||
|
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
|
||||||
if (new_state == PM_DEVICE_STATE_ACTIVE) {
|
if (new_state == PM_DEVICE_STATE_ACTIVE) {
|
||||||
if (config->single_mode) {
|
if (config->single_mode) {
|
||||||
status = lis2mdl_operating_mode_set(lis2mdl->ctx,
|
status = lis2mdl_operating_mode_set(ctx,
|
||||||
LIS2MDL_SINGLE_TRIGGER);
|
LIS2MDL_SINGLE_TRIGGER);
|
||||||
} else {
|
} else {
|
||||||
status = lis2mdl_operating_mode_set(lis2mdl->ctx,
|
status = lis2mdl_operating_mode_set(ctx,
|
||||||
LIS2MDL_CONTINUOUS_MODE);
|
LIS2MDL_CONTINUOUS_MODE);
|
||||||
}
|
}
|
||||||
if (status) {
|
if (status) {
|
||||||
|
@ -505,8 +471,7 @@ static int lis2mdl_set_power_state(struct lis2mdl_data *lis2mdl,
|
||||||
__ASSERT_NO_MSG(new_state == PM_DEVICE_STATE_LOW_POWER ||
|
__ASSERT_NO_MSG(new_state == PM_DEVICE_STATE_LOW_POWER ||
|
||||||
new_state == PM_DEVICE_STATE_SUSPEND ||
|
new_state == PM_DEVICE_STATE_SUSPEND ||
|
||||||
new_state == PM_DEVICE_STATE_OFF);
|
new_state == PM_DEVICE_STATE_OFF);
|
||||||
status = lis2mdl_operating_mode_set(lis2mdl->ctx,
|
status = lis2mdl_operating_mode_set(ctx, LIS2MDL_POWER_DOWN);
|
||||||
LIS2MDL_POWER_DOWN);
|
|
||||||
if (status) {
|
if (status) {
|
||||||
LOG_ERR("Power down failed");
|
LOG_ERR("Power down failed");
|
||||||
}
|
}
|
||||||
|
@ -550,6 +515,101 @@ static int lis2mdl_pm_control(const struct device *dev, uint32_t ctrl_command,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_PM_DEVICE */
|
#endif /* CONFIG_PM_DEVICE */
|
||||||
|
|
||||||
DEVICE_DT_INST_DEFINE(0, lis2mdl_init,
|
#if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0
|
||||||
lis2mdl_pm_control, &lis2mdl_data, &lis2mdl_dev_config,
|
#warning "LIS2MDL driver enabled without any devices"
|
||||||
POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &lis2mdl_driver_api);
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Device creation macro, shared by LIS2MDL_DEFINE_SPI() and
|
||||||
|
* LIS2MDL_DEFINE_I2C().
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LIS2MDL_DEVICE_INIT(inst) \
|
||||||
|
DEVICE_DT_INST_DEFINE(inst, \
|
||||||
|
lis2mdl_init, \
|
||||||
|
NULL, \
|
||||||
|
&lis2mdl_data_##inst, \
|
||||||
|
&lis2mdl_config_##inst, \
|
||||||
|
POST_KERNEL, \
|
||||||
|
CONFIG_SENSOR_INIT_PRIORITY, \
|
||||||
|
&lis2mdl_driver_api);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Instantiation macros used when a device is on a SPI bus.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_LIS2MDL_TRIGGER
|
||||||
|
#define LIS2MDL_CFG_IRQ(inst) \
|
||||||
|
.trig_enabled = true, \
|
||||||
|
.gpio_drdy = GPIO_DT_SPEC_INST_GET(inst, irq_gpios)
|
||||||
|
#else
|
||||||
|
#define LIS2MDL_CFG_IRQ(inst)
|
||||||
|
#endif /* CONFIG_LIS2MDL_TRIGGER */
|
||||||
|
|
||||||
|
#define LIS2MDL_SPI_OPERATION (SPI_WORD_SET(8) | \
|
||||||
|
SPI_OP_MODE_MASTER | \
|
||||||
|
SPI_LINES_SINGLE | \
|
||||||
|
SPI_MODE_CPOL | \
|
||||||
|
SPI_MODE_CPHA) \
|
||||||
|
|
||||||
|
#define LIS2MDL_CONFIG_SPI(inst) \
|
||||||
|
{ \
|
||||||
|
.ctx = { \
|
||||||
|
.read_reg = \
|
||||||
|
(stmdev_read_ptr) stmemsc_spi_read, \
|
||||||
|
.write_reg = \
|
||||||
|
(stmdev_write_ptr) stmemsc_spi_write, \
|
||||||
|
.handle = \
|
||||||
|
(void *)&lis2mdl_config_##inst.stmemsc_cfg, \
|
||||||
|
}, \
|
||||||
|
.stmemsc_cfg.spi = { \
|
||||||
|
.bus = DEVICE_DT_GET(DT_INST_BUS(inst)), \
|
||||||
|
.spi_cfg = SPI_CONFIG_DT_INST(inst, \
|
||||||
|
LIS2MDL_SPI_OPERATION, \
|
||||||
|
0), \
|
||||||
|
}, \
|
||||||
|
.cancel_offset = DT_INST_PROP(inst, cancel_offset), \
|
||||||
|
.single_mode = DT_INST_PROP(inst, single_mode), \
|
||||||
|
.spi_4wires = DT_INST_PROP(inst, spi_full_duplex), \
|
||||||
|
COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, irq_gpios), \
|
||||||
|
(LIS2MDL_CFG_IRQ(inst)), ()) \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Instantiation macros used when a device is on an I2C bus.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LIS2MDL_CONFIG_I2C(inst) \
|
||||||
|
{ \
|
||||||
|
.ctx = { \
|
||||||
|
.read_reg = \
|
||||||
|
(stmdev_read_ptr) stmemsc_i2c_read, \
|
||||||
|
.write_reg = \
|
||||||
|
(stmdev_write_ptr) stmemsc_i2c_write, \
|
||||||
|
.handle = \
|
||||||
|
(void *)&lis2mdl_config_##inst.stmemsc_cfg, \
|
||||||
|
}, \
|
||||||
|
.stmemsc_cfg.i2c = { \
|
||||||
|
.bus = DEVICE_DT_GET(DT_INST_BUS(inst)), \
|
||||||
|
.i2c_slv_addr = DT_INST_REG_ADDR(inst), \
|
||||||
|
}, \
|
||||||
|
.cancel_offset = DT_INST_PROP(inst, cancel_offset), \
|
||||||
|
.single_mode = DT_INST_PROP(inst, single_mode), \
|
||||||
|
COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, irq_gpios), \
|
||||||
|
(LIS2MDL_CFG_IRQ(inst)), ()) \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Main instantiation macro. Use of COND_CODE_1() selects the right
|
||||||
|
* bus-specific macro at preprocessor time.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LIS2MDL_DEFINE(inst) \
|
||||||
|
static struct lis2mdl_data lis2mdl_data_##inst; \
|
||||||
|
static const struct lis2mdl_config lis2mdl_config_##inst = \
|
||||||
|
COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
|
||||||
|
(LIS2MDL_CONFIG_SPI(inst)), \
|
||||||
|
(LIS2MDL_CONFIG_I2C(inst))); \
|
||||||
|
LIS2MDL_DEVICE_INIT(inst)
|
||||||
|
|
||||||
|
DT_INST_FOREACH_STATUS_OKAY(LIS2MDL_DEFINE)
|
||||||
|
|
|
@ -11,69 +11,53 @@
|
||||||
#ifndef __MAG_LIS2MDL_H
|
#ifndef __MAG_LIS2MDL_H
|
||||||
#define __MAG_LIS2MDL_H
|
#define __MAG_LIS2MDL_H
|
||||||
|
|
||||||
#include <drivers/spi.h>
|
|
||||||
#include <drivers/gpio.h>
|
#include <drivers/gpio.h>
|
||||||
#include <drivers/sensor.h>
|
#include <drivers/sensor.h>
|
||||||
#include <sys/util.h>
|
#include <sys/util.h>
|
||||||
|
#include <stmemsc.h>
|
||||||
#include "lis2mdl_reg.h"
|
#include "lis2mdl_reg.h"
|
||||||
|
|
||||||
union axis3bit16_t {
|
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
|
||||||
int16_t i16bit[3];
|
#include <drivers/spi.h>
|
||||||
uint8_t u8bit[6];
|
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */
|
||||||
};
|
|
||||||
|
|
||||||
union axis1bit16_t {
|
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
|
||||||
int16_t i16bit;
|
#include <drivers/i2c.h>
|
||||||
uint8_t u8bit[2];
|
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) */
|
||||||
};
|
|
||||||
|
|
||||||
struct lis2mdl_config {
|
struct lis2mdl_config {
|
||||||
char *master_dev_name;
|
stmdev_ctx_t ctx;
|
||||||
int (*bus_init)(const struct device *dev);
|
union {
|
||||||
|
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
|
||||||
|
const struct stmemsc_cfg_i2c i2c;
|
||||||
|
#endif
|
||||||
|
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
|
||||||
|
const struct stmemsc_cfg_spi spi;
|
||||||
|
#endif
|
||||||
|
} stmemsc_cfg;
|
||||||
bool cancel_offset;
|
bool cancel_offset;
|
||||||
bool single_mode;
|
bool single_mode;
|
||||||
|
bool spi_4wires;
|
||||||
|
|
||||||
#ifdef CONFIG_LIS2MDL_TRIGGER
|
#ifdef CONFIG_LIS2MDL_TRIGGER
|
||||||
char *gpio_name;
|
bool trig_enabled;
|
||||||
uint32_t gpio_pin;
|
const struct gpio_dt_spec gpio_drdy;
|
||||||
uint8_t gpio_flags;
|
|
||||||
#endif /* CONFIG_LIS2MDL_TRIGGER */
|
#endif /* CONFIG_LIS2MDL_TRIGGER */
|
||||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
|
|
||||||
uint16_t i2c_slv_addr;
|
|
||||||
#elif DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
|
|
||||||
struct spi_config spi_conf;
|
|
||||||
#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0)
|
|
||||||
const char *gpio_cs_port;
|
|
||||||
uint8_t cs_gpio;
|
|
||||||
uint8_t cs_gpio_flags;
|
|
||||||
#endif /* DT_INST_SPI_DEV_HAS_CS_GPIOS(0) */
|
|
||||||
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Sensor data */
|
/* Sensor data */
|
||||||
struct lis2mdl_data {
|
struct lis2mdl_data {
|
||||||
const struct device *dev;
|
const struct device *dev;
|
||||||
const struct device *bus;
|
|
||||||
uint16_t i2c_addr;
|
|
||||||
int16_t mag[3];
|
int16_t mag[3];
|
||||||
int16_t temp_sample;
|
int16_t temp_sample;
|
||||||
|
|
||||||
stmdev_ctx_t *ctx;
|
|
||||||
|
|
||||||
#ifdef CONFIG_PM_DEVICE
|
#ifdef CONFIG_PM_DEVICE
|
||||||
uint32_t power_state;
|
uint32_t power_state;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct k_sem fetch_sem;
|
struct k_sem fetch_sem;
|
||||||
|
|
||||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
|
|
||||||
stmdev_ctx_t ctx_i2c;
|
|
||||||
#elif DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
|
|
||||||
stmdev_ctx_t ctx_spi;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_LIS2MDL_TRIGGER
|
#ifdef CONFIG_LIS2MDL_TRIGGER
|
||||||
const struct device *gpio;
|
|
||||||
struct gpio_callback gpio_cb;
|
struct gpio_callback gpio_cb;
|
||||||
|
|
||||||
sensor_trigger_handler_t handler_drdy;
|
sensor_trigger_handler_t handler_drdy;
|
||||||
|
@ -86,14 +70,8 @@ struct lis2mdl_data {
|
||||||
struct k_work work;
|
struct k_work work;
|
||||||
#endif /* CONFIG_LIS2MDL_TRIGGER_GLOBAL_THREAD */
|
#endif /* CONFIG_LIS2MDL_TRIGGER_GLOBAL_THREAD */
|
||||||
#endif /* CONFIG_LIS2MDL_TRIGGER */
|
#endif /* CONFIG_LIS2MDL_TRIGGER */
|
||||||
#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0)
|
|
||||||
struct spi_cs_control cs_ctrl;
|
|
||||||
#endif /* DT_INST_SPI_DEV_HAS_CS_GPIOS(0) */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int lis2mdl_spi_init(const struct device *dev);
|
|
||||||
int lis2mdl_i2c_init(const struct device *dev);
|
|
||||||
|
|
||||||
#ifdef CONFIG_LIS2MDL_TRIGGER
|
#ifdef CONFIG_LIS2MDL_TRIGGER
|
||||||
int lis2mdl_init_interrupt(const struct device *dev);
|
int lis2mdl_init_interrupt(const struct device *dev);
|
||||||
int lis2mdl_trigger_set(const struct device *dev,
|
int lis2mdl_trigger_set(const struct device *dev,
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
/* ST Microelectronics LIS2MDL 3-axis magnetometer sensor
|
|
||||||
*
|
|
||||||
* Copyright (c) 2019 STMicroelectronics
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Datasheet:
|
|
||||||
* https://www.st.com/resource/en/datasheet/lis2mdl.pdf
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define DT_DRV_COMPAT st_lis2mdl
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <drivers/i2c.h>
|
|
||||||
#include <logging/log.h>
|
|
||||||
|
|
||||||
#include "lis2mdl.h"
|
|
||||||
|
|
||||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
|
|
||||||
|
|
||||||
#define LOG_LEVEL CONFIG_SENSOR_LOG_LEVEL
|
|
||||||
LOG_MODULE_DECLARE(LIS2MDL);
|
|
||||||
|
|
||||||
static int lis2mdl_i2c_read(struct lis2mdl_data *data, uint8_t reg_addr,
|
|
||||||
uint8_t *value, uint16_t len)
|
|
||||||
{
|
|
||||||
const struct lis2mdl_config *cfg = data->dev->config;
|
|
||||||
|
|
||||||
return i2c_burst_read(data->bus, cfg->i2c_slv_addr,
|
|
||||||
reg_addr, value, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int lis2mdl_i2c_write(struct lis2mdl_data *data, uint8_t reg_addr,
|
|
||||||
uint8_t *value, uint16_t len)
|
|
||||||
{
|
|
||||||
const struct lis2mdl_config *cfg = data->dev->config;
|
|
||||||
|
|
||||||
return i2c_burst_write(data->bus, cfg->i2c_slv_addr,
|
|
||||||
reg_addr, value, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
int lis2mdl_i2c_init(const struct device *dev)
|
|
||||||
{
|
|
||||||
struct lis2mdl_data *data = dev->data;
|
|
||||||
|
|
||||||
data->ctx_i2c.read_reg = (stmdev_read_ptr) lis2mdl_i2c_read;
|
|
||||||
data->ctx_i2c.write_reg = (stmdev_write_ptr) lis2mdl_i2c_write;
|
|
||||||
|
|
||||||
data->ctx = &data->ctx_i2c;
|
|
||||||
data->ctx->handle = data;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c) */
|
|
|
@ -1,135 +0,0 @@
|
||||||
/* ST Microelectronics LIS2MDL 3-axis magnetometer sensor
|
|
||||||
*
|
|
||||||
* Copyright (c) 2019 STMicroelectronics
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Datasheet:
|
|
||||||
* https://www.st.com/resource/en/datasheet/lis2mdl.pdf
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define DT_DRV_COMPAT st_lis2mdl
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include "lis2mdl.h"
|
|
||||||
#include <logging/log.h>
|
|
||||||
|
|
||||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
|
|
||||||
|
|
||||||
#define LIS2MDL_SPI_READ (1 << 7)
|
|
||||||
|
|
||||||
#define LOG_LEVEL CONFIG_SENSOR_LOG_LEVEL
|
|
||||||
LOG_MODULE_DECLARE(LIS2MDL);
|
|
||||||
|
|
||||||
static int lis2mdl_spi_read(struct lis2mdl_data *data, uint8_t reg_addr,
|
|
||||||
uint8_t *value, uint8_t len)
|
|
||||||
{
|
|
||||||
const struct lis2mdl_config *cfg = data->dev->config;
|
|
||||||
const struct spi_config *spi_cfg = &cfg->spi_conf;
|
|
||||||
uint8_t buffer_tx[2] = { reg_addr | LIS2MDL_SPI_READ, 0 };
|
|
||||||
const struct spi_buf tx_buf = {
|
|
||||||
.buf = buffer_tx,
|
|
||||||
.len = 2,
|
|
||||||
};
|
|
||||||
const struct spi_buf_set tx = {
|
|
||||||
.buffers = &tx_buf,
|
|
||||||
.count = 1
|
|
||||||
};
|
|
||||||
const struct spi_buf rx_buf[2] = {
|
|
||||||
{
|
|
||||||
.buf = NULL,
|
|
||||||
.len = 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.buf = value,
|
|
||||||
.len = len,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const struct spi_buf_set rx = {
|
|
||||||
.buffers = rx_buf,
|
|
||||||
.count = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
if (len > 64) {
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spi_transceive(data->bus, spi_cfg, &tx, &rx)) {
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int lis2mdl_spi_write(struct lis2mdl_data *data, uint8_t reg_addr,
|
|
||||||
uint8_t *value, uint8_t len)
|
|
||||||
{
|
|
||||||
const struct lis2mdl_config *cfg = data->dev->config;
|
|
||||||
const struct spi_config *spi_cfg = &cfg->spi_conf;
|
|
||||||
uint8_t buffer_tx[1] = { reg_addr & ~LIS2MDL_SPI_READ };
|
|
||||||
const struct spi_buf tx_buf[2] = {
|
|
||||||
{
|
|
||||||
.buf = buffer_tx,
|
|
||||||
.len = 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.buf = value,
|
|
||||||
.len = len,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const struct spi_buf_set tx = {
|
|
||||||
.buffers = tx_buf,
|
|
||||||
.count = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
if (len > 64) {
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spi_write(data->bus, spi_cfg, &tx)) {
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lis2mdl_spi_init(const struct device *dev)
|
|
||||||
{
|
|
||||||
struct lis2mdl_data *data = dev->data;
|
|
||||||
|
|
||||||
data->ctx_spi.read_reg = (stmdev_read_ptr) lis2mdl_spi_read;
|
|
||||||
data->ctx_spi.write_reg = (stmdev_write_ptr) lis2mdl_spi_write;
|
|
||||||
|
|
||||||
data->ctx = &data->ctx_spi;
|
|
||||||
data->ctx->handle = data;
|
|
||||||
|
|
||||||
#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0)
|
|
||||||
const struct lis2mdl_config *cfg = dev->config;
|
|
||||||
|
|
||||||
/* handle SPI CS thru GPIO if it is the case */
|
|
||||||
data->cs_ctrl.gpio_dev = device_get_binding(cfg->gpio_cs_port);
|
|
||||||
if (!data->cs_ctrl.gpio_dev) {
|
|
||||||
LOG_ERR("Unable to get GPIO SPI CS device");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->cs_ctrl.gpio_pin = cfg->cs_gpio;
|
|
||||||
data->cs_ctrl.gpio_dt_flags = cfg->cs_gpio_flags;
|
|
||||||
data->cs_ctrl.delay = 0;
|
|
||||||
|
|
||||||
LOG_DBG("SPI GPIO CS configured on %s:%u",
|
|
||||||
cfg->gpio_cs_port, cfg->cs_gpio);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_LIS2MDL_SPI_FULL_DUPLEX
|
|
||||||
/* Set SPI 4wires */
|
|
||||||
if (lis2mdl_spi_mode_set(data->ctx, LIS2MDL_SPI_4_WIRE) < 0) {
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */
|
|
|
@ -20,10 +20,12 @@ LOG_MODULE_DECLARE(LIS2MDL, CONFIG_SENSOR_LOG_LEVEL);
|
||||||
|
|
||||||
static int lis2mdl_enable_int(const struct device *dev, int enable)
|
static int lis2mdl_enable_int(const struct device *dev, int enable)
|
||||||
{
|
{
|
||||||
struct lis2mdl_data *lis2mdl = dev->data;
|
const struct lis2mdl_config *cfg = dev->config;
|
||||||
|
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
||||||
|
|
||||||
|
LOG_DBG("Set int with %d", enable);
|
||||||
/* set interrupt on mag */
|
/* set interrupt on mag */
|
||||||
return lis2mdl_drdy_on_pin_set(lis2mdl->ctx, enable);
|
return lis2mdl_drdy_on_pin_set(ctx, enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* link external trigger to event data ready */
|
/* link external trigger to event data ready */
|
||||||
|
@ -31,14 +33,21 @@ int lis2mdl_trigger_set(const struct device *dev,
|
||||||
const struct sensor_trigger *trig,
|
const struct sensor_trigger *trig,
|
||||||
sensor_trigger_handler_t handler)
|
sensor_trigger_handler_t handler)
|
||||||
{
|
{
|
||||||
|
const struct lis2mdl_config *cfg = dev->config;
|
||||||
|
stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
|
||||||
struct lis2mdl_data *lis2mdl = dev->data;
|
struct lis2mdl_data *lis2mdl = dev->data;
|
||||||
int16_t raw[3];
|
int16_t raw[3];
|
||||||
|
|
||||||
|
if (!cfg->trig_enabled) {
|
||||||
|
LOG_ERR("trigger_set op not supported");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
if (trig->chan == SENSOR_CHAN_MAGN_XYZ) {
|
if (trig->chan == SENSOR_CHAN_MAGN_XYZ) {
|
||||||
lis2mdl->handler_drdy = handler;
|
lis2mdl->handler_drdy = handler;
|
||||||
if (handler) {
|
if (handler) {
|
||||||
/* fetch raw data sample: re-trigger lost interrupt */
|
/* fetch raw data sample: re-trigger lost interrupt */
|
||||||
lis2mdl_magnetic_raw_get(lis2mdl->ctx, raw);
|
lis2mdl_magnetic_raw_get(ctx, raw);
|
||||||
|
|
||||||
return lis2mdl_enable_int(dev, 1);
|
return lis2mdl_enable_int(dev, 1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -53,7 +62,7 @@ int lis2mdl_trigger_set(const struct device *dev,
|
||||||
static void lis2mdl_handle_interrupt(const struct device *dev)
|
static void lis2mdl_handle_interrupt(const struct device *dev)
|
||||||
{
|
{
|
||||||
struct lis2mdl_data *lis2mdl = dev->data;
|
struct lis2mdl_data *lis2mdl = dev->data;
|
||||||
const struct lis2mdl_config *const config = dev->config;
|
const struct lis2mdl_config *const cfg = dev->config;
|
||||||
struct sensor_trigger drdy_trigger = {
|
struct sensor_trigger drdy_trigger = {
|
||||||
.type = SENSOR_TRIG_DATA_READY,
|
.type = SENSOR_TRIG_DATA_READY,
|
||||||
};
|
};
|
||||||
|
@ -62,12 +71,12 @@ static void lis2mdl_handle_interrupt(const struct device *dev)
|
||||||
lis2mdl->handler_drdy(dev, &drdy_trigger);
|
lis2mdl->handler_drdy(dev, &drdy_trigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->single_mode) {
|
if (cfg->single_mode) {
|
||||||
k_sem_give(&lis2mdl->fetch_sem);
|
k_sem_give(&lis2mdl->fetch_sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
gpio_pin_interrupt_configure(lis2mdl->gpio, config->gpio_pin,
|
gpio_pin_interrupt_configure_dt(&cfg->gpio_drdy,
|
||||||
GPIO_INT_EDGE_TO_ACTIVE);
|
GPIO_INT_EDGE_TO_ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lis2mdl_gpio_callback(const struct device *dev,
|
static void lis2mdl_gpio_callback(const struct device *dev,
|
||||||
|
@ -75,11 +84,11 @@ static void lis2mdl_gpio_callback(const struct device *dev,
|
||||||
{
|
{
|
||||||
struct lis2mdl_data *lis2mdl =
|
struct lis2mdl_data *lis2mdl =
|
||||||
CONTAINER_OF(cb, struct lis2mdl_data, gpio_cb);
|
CONTAINER_OF(cb, struct lis2mdl_data, gpio_cb);
|
||||||
const struct lis2mdl_config *const config = lis2mdl->dev->config;
|
const struct lis2mdl_config *const cfg = lis2mdl->dev->config;
|
||||||
|
|
||||||
ARG_UNUSED(pins);
|
ARG_UNUSED(pins);
|
||||||
|
|
||||||
gpio_pin_interrupt_configure(dev, config->gpio_pin, GPIO_INT_DISABLE);
|
gpio_pin_interrupt_configure_dt(&cfg->gpio_drdy, GPIO_INT_DISABLE);
|
||||||
|
|
||||||
#if defined(CONFIG_LIS2MDL_TRIGGER_OWN_THREAD)
|
#if defined(CONFIG_LIS2MDL_TRIGGER_OWN_THREAD)
|
||||||
k_sem_give(&lis2mdl->gpio_sem);
|
k_sem_give(&lis2mdl->gpio_sem);
|
||||||
|
@ -111,13 +120,12 @@ static void lis2mdl_work_cb(struct k_work *work)
|
||||||
int lis2mdl_init_interrupt(const struct device *dev)
|
int lis2mdl_init_interrupt(const struct device *dev)
|
||||||
{
|
{
|
||||||
struct lis2mdl_data *lis2mdl = dev->data;
|
struct lis2mdl_data *lis2mdl = dev->data;
|
||||||
const struct lis2mdl_config *const config = dev->config;
|
const struct lis2mdl_config *const cfg = dev->config;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* setup data ready gpio interrupt */
|
/* setup data ready gpio interrupt */
|
||||||
lis2mdl->gpio = device_get_binding(config->gpio_name);
|
if (!device_is_ready(cfg->gpio_drdy.port)) {
|
||||||
if (lis2mdl->gpio == NULL) {
|
LOG_ERR("Cannot get pointer to drdy_gpio device");
|
||||||
LOG_ERR("Cannot get pointer to %s device",
|
|
||||||
config->gpio_name);
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,18 +140,21 @@ int lis2mdl_init_interrupt(const struct device *dev)
|
||||||
lis2mdl->work.handler = lis2mdl_work_cb;
|
lis2mdl->work.handler = lis2mdl_work_cb;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gpio_pin_configure(lis2mdl->gpio, config->gpio_pin,
|
ret = gpio_pin_configure_dt(&cfg->gpio_drdy, GPIO_INPUT);
|
||||||
GPIO_INPUT | config->gpio_flags);
|
if (ret < 0) {
|
||||||
|
LOG_ERR("Could not configure gpio");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
gpio_init_callback(&lis2mdl->gpio_cb,
|
gpio_init_callback(&lis2mdl->gpio_cb,
|
||||||
lis2mdl_gpio_callback,
|
lis2mdl_gpio_callback,
|
||||||
BIT(config->gpio_pin));
|
BIT(cfg->gpio_drdy.pin));
|
||||||
|
|
||||||
if (gpio_add_callback(lis2mdl->gpio, &lis2mdl->gpio_cb) < 0) {
|
if (gpio_add_callback(cfg->gpio_drdy.port, &lis2mdl->gpio_cb) < 0) {
|
||||||
LOG_ERR("Could not set gpio callback");
|
LOG_ERR("Could not set gpio callback");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
return gpio_pin_interrupt_configure(lis2mdl->gpio, config->gpio_pin,
|
return gpio_pin_interrupt_configure_dt(&cfg->gpio_drdy,
|
||||||
GPIO_INT_EDGE_TO_ACTIVE);
|
GPIO_INT_EDGE_TO_ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,3 +24,9 @@ properties:
|
||||||
description: |
|
description: |
|
||||||
Set to enable the offset cancellation. Otherwise it would be
|
Set to enable the offset cancellation. Otherwise it would be
|
||||||
disabled as default.
|
disabled as default.
|
||||||
|
|
||||||
|
spi-full-duplex:
|
||||||
|
type: boolean
|
||||||
|
required: false
|
||||||
|
description: |
|
||||||
|
Enable SPI 4wires mode with separated MISO and MOSI lines
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue