Skip to content

Commit 2a31c4c

Browse files
asemjonovscarlescufi
authored andcommitted
sensors: icm42688 async API
Implementation of the async API for the icm42688 Signed-off-by: Al Semjonovs <[email protected]>
1 parent 8757c71 commit 2a31c4c

File tree

9 files changed

+516
-63
lines changed

9 files changed

+516
-63
lines changed

drivers/sensor/icm42688/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ zephyr_library_sources(
88
icm42688_spi.c
99
)
1010

11+
zephyr_library_sources_ifdef(CONFIG_SENSOR_ASYNC_API icm42688_rtio.c)
12+
zephyr_library_sources_ifdef(CONFIG_ICM42688_DECODER icm42688_decoder.c)
1113
zephyr_library_sources_ifdef(CONFIG_ICM42688_TRIGGER icm42688_trigger.c)
1214
zephyr_library_sources_ifdef(CONFIG_EMUL_ICM42688 icm42688_emul.c)
1315
zephyr_include_directories_ifdef(CONFIG_EMUL_ICM42688 .)

drivers/sensor/icm42688/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ config EMUL_ICM42688
2121
Enable the hardware emulator for the ICM42688. Doing so allows exercising
2222
sensor APIs for this IMU in native_posix and qemu.
2323

24+
config ICM42688_DECODER
25+
bool "ICM42688 decoder logic"
26+
default y if ICM42688
27+
help
28+
Compile the ICM42688 decoder API which allows decoding raw data returned
29+
from the sensor.
30+
2431
if ICM42688
2532

2633
choice

drivers/sensor/icm42688/icm42688.c

Lines changed: 54 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,15 @@
1313
#include <zephyr/sys/byteorder.h>
1414

1515
#include "icm42688.h"
16+
#include "icm42688_decoder.h"
1617
#include "icm42688_reg.h"
18+
#include "icm42688_rtio.h"
1719
#include "icm42688_spi.h"
1820
#include "icm42688_trigger.h"
1921

2022
#include <zephyr/logging/log.h>
2123
LOG_MODULE_REGISTER(ICM42688, CONFIG_SENSOR_LOG_LEVEL);
2224

23-
struct icm42688_sensor_data {
24-
struct icm42688_dev_data dev_data;
25-
26-
int16_t readings[7];
27-
};
28-
29-
struct icm42688_sensor_config {
30-
struct icm42688_dev_cfg dev_cfg;
31-
};
32-
3325
static void icm42688_convert_accel(struct sensor_value *val, int16_t raw_val,
3426
struct icm42688_cfg *cfg)
3527
{
@@ -47,42 +39,40 @@ static inline void icm42688_convert_temp(struct sensor_value *val, int16_t raw_v
4739
icm42688_temp_c((int32_t)raw_val, &val->val1, &val->val2);
4840
}
4941

50-
static int icm42688_channel_get(const struct device *dev, enum sensor_channel chan,
51-
struct sensor_value *val)
42+
int icm42688_channel_parse_readings(enum sensor_channel chan, int16_t readings[7],
43+
struct icm42688_cfg *cfg, struct sensor_value *val)
5244
{
53-
struct icm42688_sensor_data *data = dev->data;
54-
5545
switch (chan) {
5646
case SENSOR_CHAN_ACCEL_XYZ:
57-
icm42688_convert_accel(&val[0], data->readings[1], &data->dev_data.cfg);
58-
icm42688_convert_accel(&val[1], data->readings[2], &data->dev_data.cfg);
59-
icm42688_convert_accel(&val[2], data->readings[3], &data->dev_data.cfg);
47+
icm42688_convert_accel(&val[0], readings[1], cfg);
48+
icm42688_convert_accel(&val[1], readings[2], cfg);
49+
icm42688_convert_accel(&val[2], readings[3], cfg);
6050
break;
6151
case SENSOR_CHAN_ACCEL_X:
62-
icm42688_convert_accel(val, data->readings[1], &data->dev_data.cfg);
52+
icm42688_convert_accel(val, readings[1], cfg);
6353
break;
6454
case SENSOR_CHAN_ACCEL_Y:
65-
icm42688_convert_accel(val, data->readings[2], &data->dev_data.cfg);
55+
icm42688_convert_accel(val, readings[2], cfg);
6656
break;
6757
case SENSOR_CHAN_ACCEL_Z:
68-
icm42688_convert_accel(val, data->readings[3], &data->dev_data.cfg);
58+
icm42688_convert_accel(val, readings[3], cfg);
6959
break;
7060
case SENSOR_CHAN_GYRO_XYZ:
71-
icm42688_convert_gyro(&val[0], data->readings[4], &data->dev_data.cfg);
72-
icm42688_convert_gyro(&val[1], data->readings[5], &data->dev_data.cfg);
73-
icm42688_convert_gyro(&val[2], data->readings[6], &data->dev_data.cfg);
61+
icm42688_convert_gyro(&val[0], readings[4], cfg);
62+
icm42688_convert_gyro(&val[1], readings[5], cfg);
63+
icm42688_convert_gyro(&val[2], readings[6], cfg);
7464
break;
7565
case SENSOR_CHAN_GYRO_X:
76-
icm42688_convert_gyro(val, data->readings[4], &data->dev_data.cfg);
66+
icm42688_convert_gyro(val, readings[4], cfg);
7767
break;
7868
case SENSOR_CHAN_GYRO_Y:
79-
icm42688_convert_gyro(val, data->readings[5], &data->dev_data.cfg);
69+
icm42688_convert_gyro(val, readings[5], cfg);
8070
break;
8171
case SENSOR_CHAN_GYRO_Z:
82-
icm42688_convert_gyro(val, data->readings[6], &data->dev_data.cfg);
72+
icm42688_convert_gyro(val, readings[6], cfg);
8373
break;
8474
case SENSOR_CHAN_DIE_TEMP:
85-
icm42688_convert_temp(val, data->readings[0]);
75+
icm42688_convert_temp(val, readings[0]);
8676
break;
8777
default:
8878
return -ENOTSUP;
@@ -91,13 +81,21 @@ static int icm42688_channel_get(const struct device *dev, enum sensor_channel ch
9181
return 0;
9282
}
9383

84+
static int icm42688_channel_get(const struct device *dev, enum sensor_channel chan,
85+
struct sensor_value *val)
86+
{
87+
struct icm42688_dev_data *data = dev->data;
88+
89+
return icm42688_channel_parse_readings(chan, data->readings, &data->cfg, val);
90+
}
91+
9492
static int icm42688_sample_fetch(const struct device *dev, enum sensor_channel chan)
9593
{
9694
uint8_t status;
97-
struct icm42688_sensor_data *data = dev->data;
98-
const struct icm42688_sensor_config *cfg = dev->config;
95+
struct icm42688_dev_data *data = dev->data;
96+
const struct icm42688_dev_cfg *cfg = dev->config;
9997

100-
int res = icm42688_spi_read(&cfg->dev_cfg.spi, REG_INT_STATUS, &status, 1);
98+
int res = icm42688_spi_read(&cfg->spi, REG_INT_STATUS, &status, 1);
10199

102100
if (res) {
103101
return res;
@@ -125,8 +123,8 @@ static int icm42688_sample_fetch(const struct device *dev, enum sensor_channel c
125123
static int icm42688_attr_set(const struct device *dev, enum sensor_channel chan,
126124
enum sensor_attribute attr, const struct sensor_value *val)
127125
{
128-
const struct icm42688_sensor_data *data = dev->data;
129-
struct icm42688_cfg new_config = data->dev_data.cfg;
126+
const struct icm42688_dev_data *data = dev->data;
127+
struct icm42688_cfg new_config = data->cfg;
130128
int res = 0;
131129

132130
__ASSERT_NO_MSG(val != NULL);
@@ -173,8 +171,8 @@ static int icm42688_attr_set(const struct device *dev, enum sensor_channel chan,
173171
static int icm42688_attr_get(const struct device *dev, enum sensor_channel chan,
174172
enum sensor_attribute attr, struct sensor_value *val)
175173
{
176-
const struct icm42688_sensor_data *data = dev->data;
177-
const struct icm42688_cfg *cfg = &data->dev_data.cfg;
174+
const struct icm42688_dev_data *data = dev->data;
175+
const struct icm42688_cfg *cfg = &data->cfg;
178176
int res = 0;
179177

180178
__ASSERT_NO_MSG(val != NULL);
@@ -222,16 +220,20 @@ static const struct sensor_driver_api icm42688_driver_api = {
222220
.attr_get = icm42688_attr_get,
223221
#ifdef CONFIG_ICM42688_TRIGGER
224222
.trigger_set = icm42688_trigger_set,
223+
#endif
224+
.get_decoder = icm42688_get_decoder,
225+
#ifdef CONFIG_SENSOR_ASYNC_API
226+
.submit = icm42688_submit,
225227
#endif
226228
};
227229

228230
int icm42688_init(const struct device *dev)
229231
{
230-
struct icm42688_sensor_data *data = dev->data;
231-
const struct icm42688_sensor_config *cfg = dev->config;
232+
struct icm42688_dev_data *data = dev->data;
233+
const struct icm42688_dev_cfg *cfg = dev->config;
232234
int res;
233235

234-
if (!spi_is_ready_dt(&cfg->dev_cfg.spi)) {
236+
if (!spi_is_ready_dt(&cfg->spi)) {
235237
LOG_ERR("SPI bus is not ready");
236238
return -ENODEV;
237239
}
@@ -247,22 +249,18 @@ int icm42688_init(const struct device *dev)
247249
LOG_ERR("Failed to initialize triggers");
248250
return res;
249251
}
250-
251-
res = icm42688_trigger_enable_interrupt(dev);
252-
if (res != 0) {
253-
LOG_ERR("Failed to enable triggers");
254-
return res;
255-
}
256252
#endif
257253

258-
data->dev_data.cfg.accel_mode = ICM42688_ACCEL_LN;
259-
data->dev_data.cfg.gyro_mode = ICM42688_GYRO_LN;
260-
data->dev_data.cfg.accel_fs = ICM42688_ACCEL_FS_2G;
261-
data->dev_data.cfg.gyro_fs = ICM42688_GYRO_FS_125;
262-
data->dev_data.cfg.accel_odr = ICM42688_ACCEL_ODR_1000;
263-
data->dev_data.cfg.gyro_odr = ICM42688_GYRO_ODR_1000;
254+
memset(&data->cfg, 0, sizeof(struct icm42688_cfg));
255+
data->cfg.accel_mode = ICM42688_ACCEL_LN;
256+
data->cfg.gyro_mode = ICM42688_GYRO_LN;
257+
data->cfg.accel_fs = ICM42688_ACCEL_FS_2G;
258+
data->cfg.gyro_fs = ICM42688_GYRO_FS_125;
259+
data->cfg.accel_odr = ICM42688_ACCEL_ODR_1000;
260+
data->cfg.gyro_odr = ICM42688_GYRO_ODR_1000;
261+
data->cfg.fifo_en = false;
264262

265-
res = icm42688_configure(dev, &data->dev_data.cfg);
263+
res = icm42688_configure(dev, &data->cfg);
266264
if (res != 0) {
267265
LOG_ERR("Failed to configure");
268266
return res;
@@ -286,16 +284,15 @@ void icm42688_unlock(const struct device *dev)
286284
#define ICM42688_SPI_CFG \
287285
SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_CPHA | SPI_WORD_SET(8) | SPI_TRANSFER_MSB
288286

287+
#define ICM42688_DEFINE_DATA(inst) \
288+
static struct icm42688_dev_data icm42688_driver_##inst;
289289

290290
#define ICM42688_INIT(inst) \
291-
static struct icm42688_sensor_data icm42688_driver_##inst = { 0 }; \
291+
ICM42688_DEFINE_DATA(inst); \
292292
\
293-
static const struct icm42688_sensor_config icm42688_cfg_##inst = { \
294-
.dev_cfg = \
295-
{ \
296-
.spi = SPI_DT_SPEC_INST_GET(inst, ICM42688_SPI_CFG, 0U), \
297-
.gpio_int1 = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0}), \
298-
}, \
293+
static const struct icm42688_dev_cfg icm42688_cfg_##inst = { \
294+
.spi = SPI_DT_SPEC_INST_GET(inst, ICM42688_SPI_CFG, 0U), \
295+
.gpio_int1 = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0}), \
299296
}; \
300297
\
301298
SENSOR_DEVICE_DT_INST_DEFINE(inst, icm42688_init, NULL, &icm42688_driver_##inst, \

drivers/sensor/icm42688/icm42688.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,8 @@ struct icm42688_dev_data {
411411
const struct sensor_trigger *data_ready_trigger;
412412
struct k_mutex mutex;
413413
#endif /* CONFIG_ICM42688_TRIGGER */
414+
415+
int16_t readings[7];
414416
};
415417

416418
/**
@@ -515,7 +517,7 @@ static inline void icm42688_accel_g(struct icm42688_cfg *cfg, int32_t in, int32_
515517
* @param out_dps whole deg/s output in int32_t
516518
* @param out_udps micro (1/1000000) deg/s as uint32_t
517519
*/
518-
static inline void icm42688_gyro_dps(struct icm42688_cfg *cfg, int32_t in, int32_t *out_dps,
520+
static inline void icm42688_gyro_dps(const struct icm42688_cfg *cfg, int32_t in, int32_t *out_dps,
519521
uint32_t *out_udps)
520522
{
521523
int64_t sensitivity = 0; /* value equivalent for 10x gyro reading deg/s */
@@ -565,8 +567,8 @@ static inline void icm42688_gyro_dps(struct icm42688_cfg *cfg, int32_t in, int32
565567
* @param out_ms meters/s^2 (whole) output in int32_t
566568
* @param out_ums micrometers/s^2 output as uint32_t
567569
*/
568-
static inline void icm42688_accel_ms(struct icm42688_cfg *cfg, int32_t in, int32_t *out_ms,
569-
uint32_t *out_ums)
570+
static inline void icm42688_accel_ms(const struct icm42688_cfg *cfg, int32_t in, int32_t *out_ms,
571+
int32_t *out_ums)
570572
{
571573
int64_t sensitivity = 0; /* value equivalent for 1g */
572574

@@ -603,8 +605,8 @@ static inline void icm42688_accel_ms(struct icm42688_cfg *cfg, int32_t in, int32
603605
* @param out_rads whole rad/s output in int32_t
604606
* @param out_urads microrad/s as uint32_t
605607
*/
606-
static inline void icm42688_gyro_rads(struct icm42688_cfg *cfg, int32_t in, int32_t *out_rads,
607-
uint32_t *out_urads)
608+
static inline void icm42688_gyro_rads(const struct icm42688_cfg *cfg, int32_t in, int32_t *out_rads,
609+
int32_t *out_urads)
608610
{
609611
int64_t sensitivity = 0; /* value equivalent for 10x gyro reading deg/s */
610612

0 commit comments

Comments
 (0)