Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
182bc8f
sensor: adxl345: DTS: add binding for FIFO interrupts
Rubusch Jun 26, 2025
655870d
sensor: adxl345: DTS: set minimum watermark to 2
Rubusch Oct 6, 2025
e4ce8f5
sensor: adxl345: DTS: adjust comment for interrupt binding
Rubusch Oct 8, 2025
eaf2b48
sensor: adxl345: set minimum watermark to 2
Rubusch Oct 8, 2025
f2400ba
sensor: adxl345: rename ADXL345_INT_ENABLE to ADXL345_INT_ENABLE_REG
Rubusch Jul 22, 2025
baf2957
sensor: adxl345: rename ADXL345_INT_MAP to ADXL345_INT_MAP_REG
Rubusch Jul 22, 2025
05ef6ae
sensor: adxl345: rename ADXL345_INT_SOURCE to ADXL345_INT_SOURCE_REG
Rubusch Jul 22, 2025
8901286
sensor: adxl345: rename SAMPLE_SIZE to ADXL345_FIFO_SAMPLE_SIZE
Rubusch Jul 23, 2025
d120c48
sensor: adxl345: rename SAMPLE_MASK to ADXL345_FIFO_SAMPLE_MSK
Rubusch Jul 23, 2025
d075536
sensor: adxl345: rename SAMPLE_NUM to ADXL345_FIFO_CTL_SAMPLES_MSK
Rubusch Jul 22, 2025
6928939
sensor: adxl345: change type of member is_full_res
Rubusch Jul 21, 2025
b634780
sensor: adxl345: change type of member fifo_samples
Rubusch Jul 22, 2025
c742a13
sensor: adxl345: fix function adxl345_write_mask()
Rubusch Jul 21, 2025
013925b
sensor: adxl345: remove unused adxl345_set_op_mode()
Rubusch Jul 21, 2025
d8a9f58
sensor: adxl345: remove unused field op_mode
Rubusch Jul 22, 2025
c177965
sensor: adxl345: control measurement by a dedicated function
Rubusch Jul 22, 2025
adcbc72
sensor: adxl345: split function get_status()
Rubusch Jul 22, 2025
e6718a8
sensor: adxl345: refactor both interrupt lines configurable in device…
Rubusch Jul 22, 2025
da74339
sensor: adxl345: rename local status1 to status
Rubusch Oct 10, 2025
012004e
sensor: adxl345: refactor ODR initialization
Rubusch Jul 22, 2025
a5248fb
sensor: adxl345: init the ADXL345_DATA_FORMAT_REG register
Rubusch Jul 22, 2025
917e51e
sensor: adxl345: fix FIFO default configuration
Rubusch Jul 25, 2025
4b6e074
sensor: adxl345: introduce ADXL345_REG_DATA_XYZ_REGS
Rubusch Jul 27, 2025
8014790
sensor: adxl345: rework FIFO mode and interrupt initialization
Rubusch Jul 22, 2025
6ccabb0
sensor: adxl345: remove unused field fifo_config from the const config
Rubusch Jul 22, 2025
4f3204a
sensor: adxl345: remove unnecessary loop check
Rubusch Jul 22, 2025
a64c486
sensor: adxl345: simplify INT register field defines
Rubusch Jul 26, 2025
2c2df72
sensor: adxl345: simplify event handler registration
Rubusch Jul 22, 2025
ccea5a0
sensor: adxl345: fix fetch and get to correctly read the FIFO samples
Rubusch Jul 27, 2025
23189cd
sensor: adxl345: reorganize stream code
Rubusch Sep 22, 2025
334077b
sensor: adxl345: remove pointless variable fifo_total_bytes
Rubusch Sep 22, 2025
4f92ab8
sensor: adxl345: use a concise naming for fifo related variables
Rubusch Sep 22, 2025
7730503
sensor: adxl345: add watermark configuration through app attribute
Rubusch Jul 21, 2025
6a4d044
sensor: adxl345: rename status1 to reg_int_source
Rubusch Sep 23, 2025
e3e53db
sensor: adxl345: streamline error handling
Rubusch Sep 23, 2025
00a8fe7
sensor: adxl345: provide generic bus access API
Rubusch Sep 23, 2025
98ec77b
sensor: adxl345: factor out initialization of the stream header
Rubusch Sep 23, 2025
d45b662
sensor: adxl345: factor out consumption of CQEs
Rubusch Sep 23, 2025
d0cd81f
sensor: adxl345: move streaming checks to separate function
Rubusch Sep 23, 2025
a2b8770
sensor: adxl345: rework flushing the fifo
Rubusch Sep 23, 2025
f6b7a52
sensor: adxl345: cover watermark and overrun as sensor events
Rubusch Sep 23, 2025
29365ff
sensor: adxl345: distinguish the stream handler from trigger
Rubusch Sep 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 83 additions & 32 deletions drivers/sensor/adi/adxl345/adxl345.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,11 +279,9 @@ static int adxl345_attr_set(const struct device *dev,
}

int adxl345_read_sample(const struct device *dev,
struct adxl345_sample *sample)
struct adxl345_sample *sample)
{
int16_t raw_x, raw_y, raw_z;
struct adxl345_dev_data *data = dev->data;
uint8_t axis_data[6];
uint8_t axis_data[ADXL345_FIFO_SAMPLE_SIZE];
int rc;

rc = adxl345_reg_read(dev, ADXL345_REG_DATA_XYZ_REGS,
Expand All @@ -293,74 +291,127 @@ int adxl345_read_sample(const struct device *dev,
return rc;
}

raw_x = axis_data[0] | (axis_data[1] << 8);
raw_y = axis_data[2] | (axis_data[3] << 8);
raw_z = axis_data[4] | (axis_data[5] << 8);
sample->x = axis_data[0] | axis_data[1] << 8;
sample->y = axis_data[2] | axis_data[3] << 8;
sample->z = axis_data[4] | axis_data[5] << 8;

sample->x = raw_x;
sample->y = raw_y;
sample->z = raw_z;
#ifdef CONFIG_ADXL345_TRIGGER
struct adxl345_dev_data *data = dev->data;

sample->is_full_res = data->is_full_res; /* needed for decoder */
sample->selected_range = data->selected_range;
sample->is_full_res = data->is_full_res;
#endif

return 0;
return rc;
}

void adxl345_accel_convert(struct sensor_value *val, int16_t sample)
/**
* adxl345_accel_convert - The fallback conversion of raw measurements.
* @out: Converted value for output, containing the initialized fractional.
* @sample: Input raw measurement.
* When working without decoder, neither TRIGGER, nor STREAM is enabled,
* this small converter is used. It assumes full scale resolution and 8g.
*/
void adxl345_accel_convert(struct sensor_value *out, int16_t sample)
{
if (sample & BIT(9)) {
sample |= ADXL345_COMPLEMENT;
/* full resolution enabled w/ 8g */
if (sample & BIT(11)) {
sample |= ADXL345_COMPLEMENT_MASK(12);
}

val->val1 = ((sample * SENSOR_G) / 32) / 1000000;
val->val2 = ((sample * SENSOR_G) / 32) % 1000000;
out->val1 = ((sample * SENSOR_G) / 32) / 1000000;
out->val2 = ((sample * SENSOR_G) / 32) % 1000000;
}

static int adxl345_sample_fetch(const struct device *dev,
enum sensor_channel chan)
{
struct adxl345_dev_data *data = dev->data;
struct adxl345_sample sample;
uint8_t count;
int rc;

rc = adxl345_read_sample(dev, &sample);
if (rc < 0) {
LOG_ERR("Failed to fetch sample rc=%d\n", rc);
return rc;
count = 1;

/* FIFO BYPASSED is the only mode not using a FIFO buffer */
if (data->fifo_config.fifo_mode != ADXL345_FIFO_BYPASSED) {
count = adxl345_get_fifo_entries(dev);
if (count < 0) {
return -EIO;
}
}

__ASSERT_NO_MSG(count <= ARRAY_SIZE(data->sample));

for (uint8_t s = 0; s < count; s++) {
rc = adxl345_read_sample(dev, &data->sample[s]);
Comment on lines +490 to +491
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sensor: adxl345: fix fetch and get to correctly read the FIFO samples
In Analog Devices' FIFO modes (e.g. STREAM), samples are stored in the
sensor's internal buffer, and a watermark interrupt signals when enough
samples are ready. The driver should then fetch all available samples in a
burst read.

Currently, the driver handles interrupts but reads only a single sample
each time, regardless of FIFO mode. This effectively reduces all modes
(FIFO, TRIGGER, STREAM) to BYPASS behavior. Additionally, fetch operations
only returned the last sample repeatedly instead of the full FIFO contents.

This commit restores proper FIFO operation by converting sample storage
back to an array, but fixing the fetch logic to read and return all
configured FIFO entries.

Two things:

  1. I don't see the described burst-read change. All I see is code formatted, additional checks and asserts and then the same for-loop performed.
  2. Please confirm whether your proposition is even possible: AFAIK - The datasheet specifies the sensor only places the new sample once the previous sample is read. This is the reason why this comment is captured in the driver:
    /** RTIO SQE/CQE pool size depends on the fifo-watermark because we
    * can't just burst-read all the fifo data at once. Datasheet specifies
    * we need to get one frame at a time (through the Data registers),
    * therefore, we set all the sequence at once to properly pull each
    * frame, and then end up calling the completion event so the
    * application receives it).
    */
    #define ADXL345_RTIO_DEFINE(inst) \

RETRIEVING DATA FROM FIFO
The FIFO data is read through the DATAX, DATAY, and DATAZ
registers (Address 0x32 to Address 0x37). When the FIFO is in
FIFO, stream, or trigger mode, reads to the DATAX, DATAY, and
DATAZ registers read data stored in the FIFO. Each time data is
read from the FIFO, the oldest x-, y-, and z-axes data are placed
into the DATAX, DATAY, and DATAZ registers.

if (rc < 0) {
LOG_ERR("Failed to fetch sample rc=%d\n", rc);
return rc;
}

#ifdef CONFIG_ADXL345_STREAM
data->sample[s].is_fifo = 0;
#endif
}
data->samples.x = sample.x;
data->samples.y = sample.y;
data->samples.z = sample.z;

/* new sample available, reset book-keeping */
data->sample_idx = 0;
data->sample_number = count;

return 0;
}

/**
* adxl345_channel_get - Read a single element of one or three axis.
* @dev: The sensor device.
* @chan: The axis channel, can be x, y, z or xyz.
* @val: The resulting value after conversion of the raw axis data. Val can be
* a single value or an array of three values, where the index correspondes to
* x, y, z axis entries.
*/
static int adxl345_channel_get(const struct device *dev,
enum sensor_channel chan,
struct sensor_value *val)
{
struct adxl345_dev_data *data = dev->data;
int idx;

if (data->sample_number <= 0) { /* empty */
val->val1 = 0;
val->val2 = 0;
if (chan == SENSOR_CHAN_ACCEL_XYZ) {
val[1].val1 = 0;
val[1].val2 = 0;
val[2].val1 = 0;
val[2].val2 = 0;
}
return -ENOTSUP;
}

data->sample_idx = data->sample_idx % data->sample_number;
idx = data->sample_idx;

switch (chan) {
case SENSOR_CHAN_ACCEL_X:
adxl345_accel_convert(val, data->samples.x);
adxl345_accel_convert(val, data->sample[idx].x);
break;
case SENSOR_CHAN_ACCEL_Y:
adxl345_accel_convert(val, data->samples.y);
adxl345_accel_convert(val, data->sample[idx].y);
break;
case SENSOR_CHAN_ACCEL_Z:
adxl345_accel_convert(val, data->samples.z);
adxl345_accel_convert(val, data->sample[idx].z);
break;
case SENSOR_CHAN_ACCEL_XYZ:
adxl345_accel_convert(val++, data->samples.x);
adxl345_accel_convert(val++, data->samples.y);
adxl345_accel_convert(val, data->samples.z);
adxl345_accel_convert(val++, data->sample[idx].x);
adxl345_accel_convert(val++, data->sample[idx].y);
adxl345_accel_convert(val, data->sample[idx].z);

break;
default:
return -ENOTSUP;
}

data->sample_idx++;

return 0;
}

Expand Down
32 changes: 15 additions & 17 deletions drivers/sensor/adi/adxl345/adxl345.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,22 @@ struct adxl345_fifo_config {
uint8_t fifo_samples;
};

struct adxl345_sample {
#ifdef CONFIG_ADXL345_STREAM
uint8_t is_fifo: 1;
uint8_t res: 7;
#endif /* CONFIG_ADXL345_STREAM */
enum adxl345_range selected_range;
bool is_full_res;
int16_t x;
int16_t y;
int16_t z;
} __attribute__((__packed__));

struct adxl345_dev_data {
struct {
int16_t x;
int16_t y;
int16_t z;
} samples;
struct adxl345_sample sample[ADXL345_MAX_FIFO_SIZE];
uint8_t sample_number; /* number of samples to read from sensor */
uint8_t sample_idx; /* index counting up sample_number entries */
struct adxl345_fifo_config fifo_config;
bool is_full_res;
enum adxl345_range selected_range;
Expand Down Expand Up @@ -228,18 +238,6 @@ struct adxl345_fifo_data {
uint64_t timestamp;
} __attribute__((__packed__));

struct adxl345_sample {
#ifdef CONFIG_ADXL345_STREAM
uint8_t is_fifo: 1;
uint8_t res: 7;
#endif /* CONFIG_ADXL345_STREAM */
uint8_t selected_range;
bool is_full_res;
int16_t x;
int16_t y;
int16_t z;
};

union adxl345_bus {
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
struct i2c_dt_spec i2c;
Expand Down