diff --git a/drivers/sensor/adi/adxl345/adxl345.c b/drivers/sensor/adi/adxl345/adxl345.c index adeaae828b26..2ad60d42c9b8 100644 --- a/drivers/sensor/adi/adxl345/adxl345.c +++ b/drivers/sensor/adi/adxl345/adxl345.c @@ -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 { @@ -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; } diff --git a/drivers/sensor/adi/adxl345/adxl345.h b/drivers/sensor/adi/adxl345/adxl345.h index 1a3f1eed58ba..8bc25f503402 100644 --- a/drivers/sensor/adi/adxl345/adxl345.h +++ b/drivers/sensor/adi/adxl345/adxl345.h @@ -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; diff --git a/drivers/sensor/adi/adxl345/adxl345_decoder.c b/drivers/sensor/adi/adxl345/adxl345_decoder.c index b6a661a68184..1f39fb9d1d14 100644 --- a/drivers/sensor/adi/adxl345/adxl345_decoder.c +++ b/drivers/sensor/adi/adxl345/adxl345_decoder.c @@ -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[] = { @@ -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) { @@ -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) { @@ -208,7 +222,12 @@ 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; @@ -216,9 +235,12 @@ static int adxl345_decode_sample(const struct adxl345_sample *data, 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; @@ -226,7 +248,7 @@ static int adxl345_decode_sample(const struct adxl345_sample *data, *fit = 1; - return 0; + return 1; } static int adxl345_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec,