Commit 80b607dd authored by Luis Ubieda's avatar Luis Ubieda Committed by Dan Kalowsky
Browse files

sensor: adxl345: Fix decoder for non-streaming mode

The following fixes have been applied to this decoder:
- The Q-scale factor was fixed, both for full-scale and non
full-scale modes.
- The data-type decoded is struct sensor_three_axis_data, as
it should for read/decode API.

Signed-off-by: default avatarLuis Ubieda <luisf@croxel.com>
parent e465e616
Loading
Loading
Loading
Loading
+4 −0
Changes for drivers/sensor/adi/adxl345/adxl345.c: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -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;
}

+1 −0
Changes for drivers/sensor/adi/adxl345/adxl345.h: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
@@ -202,6 +202,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;
+62 −40
Changes for drivers/sensor/adi/adxl345/adxl345_decoder.c: 62 added lines, 40 removed lines.
Original line number Diff line number Diff line
@@ -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,14 +77,27 @@ 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];
	}
}

#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,