Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 0 additions & 1 deletion drivers/sensor/adi/adxl345/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ endchoice
config ADXL345_STREAM
bool "Use FIFO to stream data"
select ADXL345_TRIGGER
default y
depends on (SPI_RTIO || I2C_RTIO)
depends on SENSOR_ASYNC_API
help
Expand Down
6 changes: 6 additions & 0 deletions drivers/sensor/adi/adxl345/adxl345.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ int adxl345_read_sample(const struct device *dev,
{
int16_t raw_x, raw_y, raw_z;
uint8_t axis_data[6], status1;
struct adxl345_dev_data *data = dev->data;

if (!IS_ENABLED(CONFIG_ADXL345_TRIGGER)) {
do {
Expand All @@ -303,6 +304,9 @@ int adxl345_read_sample(const struct device *dev,
sample->y = raw_y;
sample->z = raw_z;

sample->selected_range = data->selected_range;
sample->is_full_res = data->is_full_res;

return 0;
}

Expand Down Expand Up @@ -453,11 +457,13 @@ static int adxl345_init(const struct device *dev)
return -ENODEV;
}

#if CONFIG_ADXL345_STREAM
rc = adxl345_reg_write_byte(dev, ADXL345_FIFO_CTL_REG, ADXL345_FIFO_STREAM_MODE);
if (rc < 0) {
LOG_ERR("FIFO enable failed\n");
return -EIO;
}
#endif

rc = adxl345_reg_write_byte(dev, ADXL345_DATA_FORMAT_REG, ADXL345_RANGE_8G);
if (rc < 0) {
Expand Down
1 change: 1 addition & 0 deletions drivers/sensor/adi/adxl345/adxl345.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ struct adxl345_sample {
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;
Expand Down
125 changes: 85 additions & 40 deletions drivers/sensor/adi/adxl345/adxl345_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,42 @@

#include "adxl345.h"

#ifdef CONFIG_ADXL345_STREAM
/** The q-scale factor will always be the same, as the nominal LSB/g
* changes at the same rate the selected shift parameter per range:
*
* - At 2G: 256 LSB/g, 10-bits resolution.
* - At 4g: 128 LSB/g, 10-bits resolution.
* - At 8g: 64 LSB/g, 10-bits resolution.
* - At 16g 32 LSB/g, 10-bits resolution.
*/
static const uint32_t qscale_factor_no_full_res[] = {
/* (1.0 / Resolution-LSB-per-g * (2^31 / 2^5) * SENSOR_G / 1000000 */
[ADXL345_RANGE_2G] = UINT32_C(2570754),
/* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^6) * SENSOR_G / 1000000 */
[ADXL345_RANGE_4G] = UINT32_C(2570754),
/* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^7) ) * SENSOR_G / 1000000 */
[ADXL345_RANGE_8G] = UINT32_C(2570754),
/* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^8) ) * SENSOR_G / 1000000 */
[ADXL345_RANGE_16G] = UINT32_C(2570754),
};

#define SENSOR_SCALING_FACTOR (SENSOR_G / (16 * 1000 / 100))

static const uint32_t accel_period_ns[] = {
[ADXL345_ODR_12HZ] = UINT32_C(1000000000) / 12,
[ADXL345_ODR_25HZ] = UINT32_C(1000000000) / 25,
[ADXL345_ODR_50HZ] = UINT32_C(1000000000) / 50,
[ADXL345_ODR_100HZ] = UINT32_C(1000000000) / 100,
[ADXL345_ODR_200HZ] = UINT32_C(1000000000) / 200,
[ADXL345_ODR_400HZ] = UINT32_C(1000000000) / 400,
/** Sensitivities based on Range:
*
* - At 2G: 256 LSB/g, 10-bits resolution.
* - At 4g: 256 LSB/g, 11-bits resolution.
* - At 8g: 256 LSB/g, 12-bits resolution.
* - At 16g 256 LSB/g, 13-bits resolution.
*/
static const uint32_t qscale_factor_full_res[] = {
/* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^5) * SENSOR_G / 1000000 */
[ADXL345_RANGE_2G] = UINT32_C(2570754),
/* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^6) * SENSOR_G / 1000000 */
[ADXL345_RANGE_4G] = UINT32_C(1285377),
/* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^7) ) * SENSOR_G / 1000000 */
[ADXL345_RANGE_8G] = UINT32_C(642688),
/* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^8) ) * SENSOR_G / 1000000 */
[ADXL345_RANGE_16G] = UINT32_C(321344),
};

static const uint32_t range_to_shift[] = {
Expand All @@ -26,30 +51,6 @@ static const uint32_t range_to_shift[] = {
[ADXL345_RANGE_16G] = 8,
};

/* (1 / sensitivity) * (pow(2,31) / pow(2,shift)) * (unit_scaler) */
static const uint32_t qscale_factor_no_full_res[] = {
/* (1.0 / ADXL362_ACCEL_2G_LSB_PER_G) * (2^31 / 2^5) * SENSOR_G / 1000000 */
[ADXL345_RANGE_2G] = UINT32_C(2569011),
/* (1.0 / ADXL362_ACCEL_4G_LSB_PER_G) * (2^31 / 2^6) * SENSOR_G / 1000000 */
[ADXL345_RANGE_4G] = UINT32_C(642253),
/* (1.0 / ADXL362_ACCEL_8G_LSB_PER_G) * (2^31 / 2^7) ) * SENSOR_G / 1000000 */
[ADXL345_RANGE_8G] = UINT32_C(160563),
/* (1.0 / ADXL362_ACCEL_8G_LSB_PER_G) * (2^31 / 2^8) ) * SENSOR_G / 1000000 */
[ADXL345_RANGE_16G] = UINT32_C(40141),
};

/* (1 / sensitivity) * (pow(2,31) / pow(2,shift)) * (unit_scaler) */
static const uint32_t qscale_factor_full_res[] = {
/* (1.0 / ADXL362_ACCEL_2G_LSB_PER_G) * (2^31 / 2^5) * SENSOR_G / 1000000 */
[ADXL345_RANGE_2G] = UINT32_C(2569011),
/* (1.0 / ADXL362_ACCEL_4G_LSB_PER_G) * (2^31 / 2^6) * SENSOR_G / 1000000 */
[ADXL345_RANGE_4G] = UINT32_C(1284506),
/* (1.0 / ADXL362_ACCEL_8G_LSB_PER_G) * (2^31 / 2^7) ) * SENSOR_G / 1000000 */
[ADXL345_RANGE_8G] = UINT32_C(642253),
/* (1.0 / ADXL362_ACCEL_8G_LSB_PER_G) * (2^31 / 2^8) ) * SENSOR_G / 1000000 */
[ADXL345_RANGE_16G] = UINT32_C(321126),
};

static inline void adxl345_accel_convert_q31(q31_t *out, int16_t sample, int32_t range,
uint8_t is_full_res)
{
Expand All @@ -76,15 +77,28 @@ static inline void adxl345_accel_convert_q31(q31_t *out, int16_t sample, int32_t
}
break;
}
*out = sample * qscale_factor_full_res[range];
} else {
if (sample & BIT(9)) {
sample |= ADXL345_COMPLEMENT;
}
*out = sample * qscale_factor_no_full_res[range];
}

*out = sample * qscale_factor_no_full_res[range];
}

#ifdef CONFIG_ADXL345_STREAM

#define SENSOR_SCALING_FACTOR (SENSOR_G / (16 * 1000 / 100))

static const uint32_t accel_period_ns[] = {
[ADXL345_ODR_12HZ] = UINT32_C(1000000000) / 12,
[ADXL345_ODR_25HZ] = UINT32_C(1000000000) / 25,
[ADXL345_ODR_50HZ] = UINT32_C(1000000000) / 50,
[ADXL345_ODR_100HZ] = UINT32_C(1000000000) / 100,
[ADXL345_ODR_200HZ] = UINT32_C(1000000000) / 200,
[ADXL345_ODR_400HZ] = UINT32_C(1000000000) / 400,
};

static int adxl345_decode_stream(const uint8_t *buffer, struct sensor_chan_spec chan_spec,
uint32_t *fit, uint16_t max_count, void *data_out)
{
Expand Down Expand Up @@ -208,25 +222,33 @@ static int adxl345_decode_sample(const struct adxl345_sample *data,
struct sensor_chan_spec chan_spec, uint32_t *fit,
uint16_t max_count, void *data_out)
{
struct sensor_value *out = (struct sensor_value *)data_out;
struct sensor_three_axis_data *out = (struct sensor_three_axis_data *)data_out;

memset(out, 0, sizeof(struct sensor_three_axis_data));
out->header.base_timestamp_ns = k_ticks_to_ns_floor64(k_uptime_ticks());
out->header.reading_count = 1;
out->shift = range_to_shift[data->selected_range];

if (*fit > 0) {
return -ENOTSUP;
}

switch (chan_spec.chan_type) {
case SENSOR_CHAN_ACCEL_XYZ:
adxl345_accel_convert(out++, data->x);
adxl345_accel_convert(out++, data->y);
adxl345_accel_convert(out, data->z);
adxl345_accel_convert_q31(&out->readings->x, data->x, data->selected_range,
data->is_full_res);
adxl345_accel_convert_q31(&out->readings->y, data->y, data->selected_range,
data->is_full_res);
adxl345_accel_convert_q31(&out->readings->z, data->z, data->selected_range,
data->is_full_res);
break;
default:
return -ENOTSUP;
}

*fit = 1;

return 0;
return 1;
}

static int adxl345_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec,
Expand Down Expand Up @@ -259,10 +281,33 @@ static bool adxl345_decoder_has_trigger(const uint8_t *buffer, enum sensor_trigg
}
}

static int adxl345_get_size_info(struct sensor_chan_spec channel, size_t *base_size,
size_t *frame_size)
{
__ASSERT_NO_MSG(base_size != NULL);
__ASSERT_NO_MSG(frame_size != NULL);

if (channel.chan_type >= SENSOR_CHAN_ALL) {
return -ENOTSUP;
}

switch (channel.chan_type) {
case SENSOR_CHAN_ACCEL_XYZ:
*base_size = sizeof(struct sensor_three_axis_data);
*frame_size = sizeof(struct sensor_three_axis_sample_data);
return 0;
default:
break;
}

return -ENOTSUP;
}

SENSOR_DECODER_API_DT_DEFINE() = {
.get_frame_count = adxl345_decoder_get_frame_count,
.decode = adxl345_decoder_decode,
.has_trigger = adxl345_decoder_has_trigger,
.get_size_info = adxl345_get_size_info,
};

int adxl345_get_decoder(const struct device *dev, const struct sensor_decoder_api **decoder)
Expand Down
Loading