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: Luis Ubieda <luisf@croxel.com>
This commit is contained in:
parent
2dba777432
commit
283b5197e6
3 changed files with 67 additions and 40 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue