Skip to content

Commit 283b519

Browse files
ubiedakartben
authored andcommitted
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 <[email protected]>
1 parent 2dba777 commit 283b519

File tree

3 files changed

+67
-40
lines changed

3 files changed

+67
-40
lines changed

drivers/sensor/adi/adxl345/adxl345.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ int adxl345_read_sample(const struct device *dev,
281281
{
282282
int16_t raw_x, raw_y, raw_z;
283283
uint8_t axis_data[6], status1;
284+
struct adxl345_dev_data *data = dev->data;
284285

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

307+
sample->selected_range = data->selected_range;
308+
sample->is_full_res = data->is_full_res;
309+
306310
return 0;
307311
}
308312

drivers/sensor/adi/adxl345/adxl345.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ struct adxl345_sample {
205205
uint8_t res: 7;
206206
#endif /* CONFIG_ADXL345_STREAM */
207207
uint8_t selected_range;
208+
bool is_full_res;
208209
int16_t x;
209210
int16_t y;
210211
int16_t z;

drivers/sensor/adi/adxl345/adxl345_decoder.c

Lines changed: 62 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,42 @@
66

77
#include "adxl345.h"
88

9-
#ifdef CONFIG_ADXL345_STREAM
9+
/** The q-scale factor will always be the same, as the nominal LSB/g
10+
* changes at the same rate the selected shift parameter per range:
11+
*
12+
* - At 2G: 256 LSB/g, 10-bits resolution.
13+
* - At 4g: 128 LSB/g, 10-bits resolution.
14+
* - At 8g: 64 LSB/g, 10-bits resolution.
15+
* - At 16g 32 LSB/g, 10-bits resolution.
16+
*/
17+
static const uint32_t qscale_factor_no_full_res[] = {
18+
/* (1.0 / Resolution-LSB-per-g * (2^31 / 2^5) * SENSOR_G / 1000000 */
19+
[ADXL345_RANGE_2G] = UINT32_C(2570754),
20+
/* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^6) * SENSOR_G / 1000000 */
21+
[ADXL345_RANGE_4G] = UINT32_C(2570754),
22+
/* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^7) ) * SENSOR_G / 1000000 */
23+
[ADXL345_RANGE_8G] = UINT32_C(2570754),
24+
/* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^8) ) * SENSOR_G / 1000000 */
25+
[ADXL345_RANGE_16G] = UINT32_C(2570754),
26+
};
1027

11-
#define SENSOR_SCALING_FACTOR (SENSOR_G / (16 * 1000 / 100))
1228

13-
static const uint32_t accel_period_ns[] = {
14-
[ADXL345_ODR_12HZ] = UINT32_C(1000000000) / 12,
15-
[ADXL345_ODR_25HZ] = UINT32_C(1000000000) / 25,
16-
[ADXL345_ODR_50HZ] = UINT32_C(1000000000) / 50,
17-
[ADXL345_ODR_100HZ] = UINT32_C(1000000000) / 100,
18-
[ADXL345_ODR_200HZ] = UINT32_C(1000000000) / 200,
19-
[ADXL345_ODR_400HZ] = UINT32_C(1000000000) / 400,
29+
/** Sensitivities based on Range:
30+
*
31+
* - At 2G: 256 LSB/g, 10-bits resolution.
32+
* - At 4g: 256 LSB/g, 11-bits resolution.
33+
* - At 8g: 256 LSB/g, 12-bits resolution.
34+
* - At 16g 256 LSB/g, 13-bits resolution.
35+
*/
36+
static const uint32_t qscale_factor_full_res[] = {
37+
/* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^5) * SENSOR_G / 1000000 */
38+
[ADXL345_RANGE_2G] = UINT32_C(2570754),
39+
/* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^6) * SENSOR_G / 1000000 */
40+
[ADXL345_RANGE_4G] = UINT32_C(1285377),
41+
/* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^7) ) * SENSOR_G / 1000000 */
42+
[ADXL345_RANGE_8G] = UINT32_C(642688),
43+
/* (1.0 / Resolution-LSB-per-g) * (2^31 / 2^8) ) * SENSOR_G / 1000000 */
44+
[ADXL345_RANGE_16G] = UINT32_C(321344),
2045
};
2146

2247
static const uint32_t range_to_shift[] = {
@@ -26,30 +51,6 @@ static const uint32_t range_to_shift[] = {
2651
[ADXL345_RANGE_16G] = 8,
2752
};
2853

29-
/* (1 / sensitivity) * (pow(2,31) / pow(2,shift)) * (unit_scaler) */
30-
static const uint32_t qscale_factor_no_full_res[] = {
31-
/* (1.0 / ADXL362_ACCEL_2G_LSB_PER_G) * (2^31 / 2^5) * SENSOR_G / 1000000 */
32-
[ADXL345_RANGE_2G] = UINT32_C(2569011),
33-
/* (1.0 / ADXL362_ACCEL_4G_LSB_PER_G) * (2^31 / 2^6) * SENSOR_G / 1000000 */
34-
[ADXL345_RANGE_4G] = UINT32_C(642253),
35-
/* (1.0 / ADXL362_ACCEL_8G_LSB_PER_G) * (2^31 / 2^7) ) * SENSOR_G / 1000000 */
36-
[ADXL345_RANGE_8G] = UINT32_C(160563),
37-
/* (1.0 / ADXL362_ACCEL_8G_LSB_PER_G) * (2^31 / 2^8) ) * SENSOR_G / 1000000 */
38-
[ADXL345_RANGE_16G] = UINT32_C(40141),
39-
};
40-
41-
/* (1 / sensitivity) * (pow(2,31) / pow(2,shift)) * (unit_scaler) */
42-
static const uint32_t qscale_factor_full_res[] = {
43-
/* (1.0 / ADXL362_ACCEL_2G_LSB_PER_G) * (2^31 / 2^5) * SENSOR_G / 1000000 */
44-
[ADXL345_RANGE_2G] = UINT32_C(2569011),
45-
/* (1.0 / ADXL362_ACCEL_4G_LSB_PER_G) * (2^31 / 2^6) * SENSOR_G / 1000000 */
46-
[ADXL345_RANGE_4G] = UINT32_C(1284506),
47-
/* (1.0 / ADXL362_ACCEL_8G_LSB_PER_G) * (2^31 / 2^7) ) * SENSOR_G / 1000000 */
48-
[ADXL345_RANGE_8G] = UINT32_C(642253),
49-
/* (1.0 / ADXL362_ACCEL_8G_LSB_PER_G) * (2^31 / 2^8) ) * SENSOR_G / 1000000 */
50-
[ADXL345_RANGE_16G] = UINT32_C(321126),
51-
};
52-
5354
static inline void adxl345_accel_convert_q31(q31_t *out, int16_t sample, int32_t range,
5455
uint8_t is_full_res)
5556
{
@@ -76,15 +77,28 @@ static inline void adxl345_accel_convert_q31(q31_t *out, int16_t sample, int32_t
7677
}
7778
break;
7879
}
80+
*out = sample * qscale_factor_full_res[range];
7981
} else {
8082
if (sample & BIT(9)) {
8183
sample |= ADXL345_COMPLEMENT;
8284
}
85+
*out = sample * qscale_factor_no_full_res[range];
8386
}
84-
85-
*out = sample * qscale_factor_no_full_res[range];
8687
}
8788

89+
#ifdef CONFIG_ADXL345_STREAM
90+
91+
#define SENSOR_SCALING_FACTOR (SENSOR_G / (16 * 1000 / 100))
92+
93+
static const uint32_t accel_period_ns[] = {
94+
[ADXL345_ODR_12HZ] = UINT32_C(1000000000) / 12,
95+
[ADXL345_ODR_25HZ] = UINT32_C(1000000000) / 25,
96+
[ADXL345_ODR_50HZ] = UINT32_C(1000000000) / 50,
97+
[ADXL345_ODR_100HZ] = UINT32_C(1000000000) / 100,
98+
[ADXL345_ODR_200HZ] = UINT32_C(1000000000) / 200,
99+
[ADXL345_ODR_400HZ] = UINT32_C(1000000000) / 400,
100+
};
101+
88102
static int adxl345_decode_stream(const uint8_t *buffer, struct sensor_chan_spec chan_spec,
89103
uint32_t *fit, uint16_t max_count, void *data_out)
90104
{
@@ -208,25 +222,33 @@ static int adxl345_decode_sample(const struct adxl345_sample *data,
208222
struct sensor_chan_spec chan_spec, uint32_t *fit,
209223
uint16_t max_count, void *data_out)
210224
{
211-
struct sensor_value *out = (struct sensor_value *)data_out;
225+
struct sensor_three_axis_data *out = (struct sensor_three_axis_data *)data_out;
226+
227+
memset(out, 0, sizeof(struct sensor_three_axis_data));
228+
out->header.base_timestamp_ns = k_ticks_to_ns_floor64(k_uptime_ticks());
229+
out->header.reading_count = 1;
230+
out->shift = range_to_shift[data->selected_range];
212231

213232
if (*fit > 0) {
214233
return -ENOTSUP;
215234
}
216235

217236
switch (chan_spec.chan_type) {
218237
case SENSOR_CHAN_ACCEL_XYZ:
219-
adxl345_accel_convert(out++, data->x);
220-
adxl345_accel_convert(out++, data->y);
221-
adxl345_accel_convert(out, data->z);
238+
adxl345_accel_convert_q31(&out->readings->x, data->x, data->selected_range,
239+
data->is_full_res);
240+
adxl345_accel_convert_q31(&out->readings->y, data->y, data->selected_range,
241+
data->is_full_res);
242+
adxl345_accel_convert_q31(&out->readings->z, data->z, data->selected_range,
243+
data->is_full_res);
222244
break;
223245
default:
224246
return -ENOTSUP;
225247
}
226248

227249
*fit = 1;
228250

229-
return 0;
251+
return 1;
230252
}
231253

232254
static int adxl345_decoder_decode(const uint8_t *buffer, struct sensor_chan_spec chan_spec,

0 commit comments

Comments
 (0)