Skip to content

Commit

Permalink
drivers: sensor: adxl372: Updated driver with RTIO stream functionality
Browse files Browse the repository at this point in the history
Updated ADXL372 driver with RTIO stream functionality.
RTIO stream is using both FIFO threshold and FIFO full triggers.
Together with RTIO stream, RTIO async read is also implemented.

Signed-off-by: Vladislav Pejic <vladislav.pejic@orioninc.com>
  • Loading branch information
vladislav-pejic authored and nashif committed Oct 22, 2024
1 parent 9356999 commit cfe64f7
Show file tree
Hide file tree
Showing 8 changed files with 957 additions and 21 deletions.
2 changes: 2 additions & 0 deletions drivers/sensor/adi/adxl372/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ zephyr_library_sources(adxl372.c)
zephyr_library_sources(adxl372_spi.c)
zephyr_library_sources(adxl372_i2c.c)
zephyr_library_sources_ifdef(CONFIG_ADXL372_TRIGGER adxl372_trigger.c)
zephyr_library_sources_ifdef(CONFIG_SENSOR_ASYNC_API adxl372_rtio.c adxl372_decoder.c)
zephyr_library_sources_ifdef(CONFIG_ADXL372_STREAM adxl372_stream.c adxl372_decoder.c)
10 changes: 10 additions & 0 deletions drivers/sensor/adi/adxl372/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ menuconfig ADXL372
depends on DT_HAS_ADI_ADXL372_ENABLED
select I2C if $(dt_compat_on_bus,$(DT_COMPAT_ADI_ADXL372),i2c)
select SPI if $(dt_compat_on_bus,$(DT_COMPAT_ADI_ADXL372),spi)
select RTIO_WORKQ if SENSOR_ASYNC_API
help
Enable driver for ADXL372 Three-Axis Digital Accelerometers.

Expand Down Expand Up @@ -106,6 +107,15 @@ config ADXL372_TRIGGER_OWN_THREAD

endchoice

config ADXL372_STREAM
bool "Use FIFO to stream data"
select ADXL372_TRIGGER
default y
depends on SPI_RTIO
depends on SENSOR_ASYNC_API
help
Use this configuration option to enable streaming sensor data via RTIO.

config ADXL372_TRIGGER
bool

Expand Down
94 changes: 74 additions & 20 deletions drivers/sensor/adi/adxl372/adxl372.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,22 @@ static int adxl372_set_activity_threshold_xyz(const struct device *dev,
* ADXL372_FULL_BW_MEASUREMENT
* @return 0 in case of success, negative error code otherwise.
*/
static int adxl372_set_op_mode(const struct device *dev,
enum adxl372_op_mode op_mode)
int adxl372_set_op_mode(const struct device *dev, enum adxl372_op_mode op_mode)
{
struct adxl372_data *data = dev->data;

return data->hw_tf->write_reg_mask(dev, ADXL372_POWER_CTL,
int ret = data->hw_tf->write_reg_mask(dev, ADXL372_POWER_CTL,
ADXL372_POWER_CTL_MODE_MSK,
ADXL372_POWER_CTL_MODE(op_mode));

#ifdef CONFIG_ADXL372_STREAM
if (ret == 0) {
data->pwr_reg &= ~ADXL372_POWER_CTL_MODE_MSK;
data->pwr_reg |= ADXL372_POWER_CTL_MODE(op_mode);
}
#endif /* CONFIG_ADXL372_STREAM */

return ret;
}

/**
Expand Down Expand Up @@ -145,6 +153,11 @@ static int adxl372_set_bandwidth(const struct device *dev,
return ret;
}

#ifdef CONFIG_ADXL372_STREAM
data->pwr_reg &= ~ADXL372_POWER_CTL_LPF_DIS_MSK;
data->pwr_reg |= mask;
#endif /* CONFIG_ADXL372_STREAM */

return data->hw_tf->write_reg_mask(dev, ADXL372_MEASURE,
ADXL372_MEASURE_BANDWIDTH_MSK,
ADXL372_MEASURE_BANDWIDTH_MODE(bw));
Expand Down Expand Up @@ -181,6 +194,11 @@ static int adxl372_set_hpf_corner(const struct device *dev,
return ret;
}

#ifdef CONFIG_ADXL372_STREAM
data->pwr_reg &= ~ADXL372_POWER_CTL_HPF_DIS_MSK;
data->pwr_reg |= mask;
#endif /* CONFIG_ADXL372_STREAM */

return data->hw_tf->write_reg(dev, ADXL372_HPF, ADXL372_HPF_CORNER(c));
}

Expand Down Expand Up @@ -237,9 +255,18 @@ static int adxl372_set_instant_on_th(const struct device *dev,
{
struct adxl372_data *data = dev->data;

return data->hw_tf->write_reg_mask(dev, ADXL372_POWER_CTL,
int ret = data->hw_tf->write_reg_mask(dev, ADXL372_POWER_CTL,
ADXL372_POWER_CTL_INSTANT_ON_TH_MSK,
ADXL372_POWER_CTL_INSTANT_ON_TH_MODE(mode));

#ifdef CONFIG_ADXL372_STREAM
if (ret == 0) {
data->pwr_reg &= ~ADXL372_POWER_CTL_INSTANT_ON_TH_MSK;
data->pwr_reg |= ADXL372_POWER_CTL_INSTANT_ON_TH_MODE(mode);
}
#endif /* CONFIG_ADXL372_STREAM */

return ret;
}

/**
Expand Down Expand Up @@ -313,9 +340,18 @@ static int adxl372_set_filter_settle(const struct device *dev,
{
struct adxl372_data *data = dev->data;

return data->hw_tf->write_reg_mask(dev, ADXL372_POWER_CTL,
int ret = data->hw_tf->write_reg_mask(dev, ADXL372_POWER_CTL,
ADXL372_POWER_CTL_FIL_SETTLE_MSK,
ADXL372_POWER_CTL_FIL_SETTLE_MODE(mode));

#ifdef CONFIG_ADXL372_STREAM
if (ret == 0) {
data->pwr_reg &= ~ADXL372_POWER_CTL_FIL_SETTLE_MSK;
data->pwr_reg |= ADXL372_POWER_CTL_FIL_SETTLE_MODE(mode);
}
#endif /* CONFIG_ADXL372_STREAM */

return ret;
}

/**
Expand Down Expand Up @@ -432,13 +468,10 @@ static int adxl372_reset(const struct device *dev)
* @param fifo_samples - FIFO Samples. Watermark number of FIFO samples that
* triggers a FIFO_FULL condition when reached.
* Values range from 0 to 512.
* @return 0 in case of success, negative error code otherwise.
*/
static int adxl372_configure_fifo(const struct device *dev,
enum adxl372_fifo_mode mode,
enum adxl372_fifo_format format,
uint16_t fifo_samples)
int adxl372_configure_fifo(const struct device *dev, enum adxl372_fifo_mode mode,
enum adxl372_fifo_format format, uint16_t fifo_samples)
{
struct adxl372_data *data = dev->data;
uint8_t fifo_config;
Expand Down Expand Up @@ -485,8 +518,8 @@ static int adxl372_configure_fifo(const struct device *dev,
* where (x, y, z) acceleration data will be stored.
* @return 0 in case of success, negative error code otherwise.
*/
static int adxl372_get_accel_data(const struct device *dev, bool maxpeak,
struct adxl372_xyz_accel_data *accel_data)
int adxl372_get_accel_data(const struct device *dev, bool maxpeak,
struct adxl372_xyz_accel_data *accel_data)
{
struct adxl372_data *data = dev->data;
uint8_t buf[6];
Expand All @@ -501,7 +534,9 @@ static int adxl372_get_accel_data(const struct device *dev, bool maxpeak,

ret = data->hw_tf->read_reg_multiple(dev, maxpeak ? ADXL372_X_MAXPEAK_H :
ADXL372_X_DATA_H, buf, 6);

#ifdef CONFIG_ADXL372_STREAM
accel_data->is_fifo = 0;
#endif /* CONFIG_ADXL372_STREAM */
accel_data->x = (buf[0] << 8) | (buf[1] & 0xF0);
accel_data->y = (buf[2] << 8) | (buf[3] & 0xF0);
accel_data->z = (buf[4] << 8) | (buf[5] & 0xF0);
Expand All @@ -515,6 +550,7 @@ static int adxl372_attr_set_odr(const struct device *dev,
const struct sensor_value *val)
{
enum adxl372_odr odr;
struct adxl372_dev_config *cfg = (struct adxl372_dev_config *)dev->config;

switch (val->val1) {
case 400:
Expand All @@ -536,7 +572,13 @@ static int adxl372_attr_set_odr(const struct device *dev,
return -EINVAL;
}

return adxl372_set_odr(dev, odr);
int ret = adxl372_set_odr(dev, odr);

if (ret == 0) {
cfg->odr = odr;
}

return ret;
}

static int adxl372_attr_set_thresh(const struct device *dev,
Expand Down Expand Up @@ -610,7 +652,7 @@ static int adxl372_sample_fetch(const struct device *dev,
&data->sample);
}

static void adxl372_accel_convert(struct sensor_value *val, int16_t value)
void adxl372_accel_convert(struct sensor_value *val, int16_t value)
{
/*
* Sensor resolution is 100mg/LSB, 12-bit value needs to be right
Expand Down Expand Up @@ -651,12 +693,16 @@ static int adxl372_channel_get(const struct device *dev,
}

static const struct sensor_driver_api adxl372_api_funcs = {
.attr_set = adxl372_attr_set,
.attr_set = adxl372_attr_set,
.sample_fetch = adxl372_sample_fetch,
.channel_get = adxl372_channel_get,
.channel_get = adxl372_channel_get,
#ifdef CONFIG_ADXL372_TRIGGER
.trigger_set = adxl372_trigger_set,
#endif
#ifdef CONFIG_SENSOR_ASYNC_API
.submit = adxl372_submit,
.get_decoder = adxl372_get_decoder,
#endif /* CONFIG_SENSOR_ASYNC_API */

};

Expand Down Expand Up @@ -822,6 +868,11 @@ static int adxl372_init(const struct device *dev)
/*
* Instantiation macros used when a device is on a SPI bus.
*/
#define ADXL372_SPI_CFG SPI_WORD_SET(8) | SPI_TRANSFER_MSB

#define ADXL372_RTIO_DEFINE(inst) \
SPI_DT_IODEV_DEFINE(adxl372_iodev_##inst, DT_DRV_INST(inst), ADXL372_SPI_CFG, 0U); \
RTIO_DEFINE(adxl372_rtio_ctx_##inst, 16, 16);

#ifdef CONFIG_ADXL372_TRIGGER
#define ADXL372_CFG_IRQ(inst) \
Expand Down Expand Up @@ -857,15 +908,18 @@ static int adxl372_init(const struct device *dev)
#define ADXL372_CONFIG_SPI(inst) \
{ \
.bus_init = adxl372_spi_init, \
.spi = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8) | \
SPI_TRANSFER_MSB, 0), \
.spi = SPI_DT_SPEC_INST_GET(inst, ADXL372_SPI_CFG, 0), \
ADXL372_CONFIG(inst) \
COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, int1_gpios), \
(ADXL372_CFG_IRQ(inst)), ()) \
}

#define ADXL372_DEFINE_SPI(inst) \
static struct adxl372_data adxl372_data_##inst; \
IF_ENABLED(CONFIG_ADXL372_STREAM, (ADXL372_RTIO_DEFINE(inst))); \
static struct adxl372_data adxl372_data_##inst = { \
IF_ENABLED(CONFIG_ADXL372_STREAM, (.rtio_ctx = &adxl372_rtio_ctx_##inst, \
.iodev = &adxl372_iodev_##inst,)) \
}; \
static const struct adxl372_dev_config adxl372_config_##inst = \
ADXL372_CONFIG_SPI(inst); \
ADXL372_DEVICE_INIT(inst)
Expand Down
53 changes: 53 additions & 0 deletions drivers/sensor/adi/adxl372/adxl372.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
#include <zephyr/kernel.h>
#include <zephyr/sys/util.h>

#ifdef CONFIG_ADXL372_STREAM
#include <zephyr/rtio/rtio.h>
#endif /* CONFIG_ADXL372_STREAM */

#define DT_DRV_COMPAT adi_adxl372

#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
#include <zephyr/drivers/spi.h>
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */
Expand Down Expand Up @@ -281,6 +287,10 @@ struct adxl372_activity_threshold {
};

struct adxl372_xyz_accel_data {
#ifdef CONFIG_ADXL372_STREAM
uint8_t is_fifo: 1;
uint8_t res: 7;
#endif /* CONFIG_ADXL372_STREAM */
int16_t x;
int16_t y;
int16_t z;
Expand Down Expand Up @@ -319,6 +329,16 @@ struct adxl372_data {
struct k_work work;
#endif
#endif /* CONFIG_ADXL372_TRIGGER */
#ifdef CONFIG_ADXL372_STREAM
struct rtio_iodev_sqe *sqe;
struct rtio *rtio_ctx;
struct rtio_iodev *iodev;
uint8_t status1;
uint8_t fifo_ent[2];
uint64_t timestamp;
uint8_t fifo_full_irq;
uint8_t pwr_reg;
#endif /* CONFIG_ADXL372_STREAM */
};

struct adxl372_dev_config {
Expand Down Expand Up @@ -358,9 +378,27 @@ struct adxl372_dev_config {
uint8_t int2_config;
};

struct adxl372_fifo_data {
uint8_t is_fifo: 1;
uint8_t sample_set_size: 4;
uint8_t has_x: 1;
uint8_t has_y: 1;
uint8_t has_z: 1;
uint8_t int_status;
uint16_t accel_odr: 4;
uint16_t fifo_byte_count: 12;
uint64_t timestamp;
} __attribute__((__packed__));

BUILD_ASSERT(sizeof(struct adxl372_fifo_data) % 4 == 0,
"adxl372_fifo_data struct should be word aligned");

int adxl372_spi_init(const struct device *dev);
int adxl372_i2c_init(const struct device *dev);

void adxl372_submit_stream(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe);
void adxl372_stream_irq_handler(const struct device *dev);

#ifdef CONFIG_ADXL372_TRIGGER
int adxl372_get_status(const struct device *dev,
uint8_t *status1, uint8_t *status2, uint16_t *fifo_entries);
Expand All @@ -372,4 +410,19 @@ int adxl372_trigger_set(const struct device *dev,
int adxl372_init_interrupt(const struct device *dev);
#endif /* CONFIG_ADXL372_TRIGGER */

#ifdef CONFIG_SENSOR_ASYNC_API
int adxl372_get_accel_data(const struct device *dev, bool maxpeak,
struct adxl372_xyz_accel_data *accel_data);
void adxl372_submit(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe);
int adxl372_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder);
void adxl372_accel_convert(struct sensor_value *val, int16_t sample);
#endif /* CONFIG_SENSOR_ASYNC_API */

#ifdef CONFIG_ADXL372_STREAM
int adxl372_configure_fifo(const struct device *dev, enum adxl372_fifo_mode mode,
enum adxl372_fifo_format format, uint16_t fifo_samples);
size_t adxl372_get_packet_size(const struct adxl372_dev_config *cfg);
int adxl372_set_op_mode(const struct device *dev, enum adxl372_op_mode op_mode);
#endif /* CONFIG_ADXL372_STREAM */

#endif /* ZEPHYR_DRIVERS_SENSOR_ADXL372_ADXL372_H_ */
Loading

0 comments on commit cfe64f7

Please sign in to comment.