Skip to content

Commit

Permalink
drivers: imu: adis: Rework scale implementation
Browse files Browse the repository at this point in the history
Currently the scale implementation is not optimal: the arrays used
for scale which are defined in the chip specific drivers have a
bigger size than needed because device id is used.
This commit removes this problem by:
- adding chip specific API declaration to retrieve the scale,
instead of using scale arrays.
- implementing the chip specific APIs to retrieve the scale for
each existing adis driver
- using a device id with no offset in each chip specific driver
to define the scales for all supported devices.
All these changes lead to correct scale reading from adis driver
based on the device id, with driver-specific scale array size
equal to the number of supported devices.
Unit-tests are also updated to reflect this change.

Signed-off-by: Ramona Gradinariu <[email protected]>
  • Loading branch information
rbolboac authored and CiprianRegus committed Mar 7, 2024
1 parent 4916b27 commit fccff3a
Show file tree
Hide file tree
Showing 9 changed files with 370 additions and 217 deletions.
31 changes: 10 additions & 21 deletions drivers/imu/adis.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,6 @@ int adis_init(struct adis_dev **adis, const struct adis_chip_info *info)
if (ret)
goto error;

dev->anglvel_scale = info->anglvel_scale[dev->dev_id];
dev->accl_scale = info->accl_scale[dev->dev_id];
dev->deltaangl_scale = info->deltaangl_scale[dev->dev_id];
dev->deltavelocity_scale = info->deltavelocity_scale[dev->dev_id];
dev->temp_scale = info->temp_scale[dev->dev_id];

*adis = dev;

return ret;
Expand Down Expand Up @@ -2649,9 +2643,8 @@ int adis_get_anglvel_scale(struct adis_dev *adis,
if (!adis || !anglvel_scale)
return -EINVAL;

*anglvel_scale = adis->anglvel_scale;

return 0;
return adis->info->get_scale(adis, &anglvel_scale->dividend,
&anglvel_scale->divisor, ADIS_GYRO_CHAN);
}

/**
Expand All @@ -2666,9 +2659,8 @@ int adis_get_accl_scale(struct adis_dev *adis,
if (!adis || !accl_scale)
return -EINVAL;

*accl_scale = adis->accl_scale;

return 0;
return adis->info->get_scale(adis, &accl_scale->dividend, &accl_scale->divisor,
ADIS_ACCL_CHAN);
}

/**
Expand All @@ -2683,9 +2675,8 @@ int adis_get_deltaangl_scale(struct adis_dev *adis,
if (!adis || !deltaangl_scale)
return -EINVAL;

*deltaangl_scale = adis->deltaangl_scale;

return 0;
return adis->info->get_scale(adis, &deltaangl_scale->dividend,
&deltaangl_scale->power, ADIS_DELTAANGL_CHAN);
}

/**
Expand All @@ -2700,9 +2691,8 @@ int adis_get_deltavelocity_scale(struct adis_dev *adis,
if (!adis || !deltavelocity_scale)
return -EINVAL;

*deltavelocity_scale = adis->deltavelocity_scale;

return 0;
return adis->info->get_scale(adis, &deltavelocity_scale->dividend,
&deltavelocity_scale->power, ADIS_DELTAVEL_CHAN);
}

/**
Expand All @@ -2717,7 +2707,6 @@ int adis_get_temp_scale(struct adis_dev *adis,
if (!adis || !temp_scale)
return -EINVAL;

*temp_scale = adis->temp_scale;

return 0;
return adis->info->get_scale(adis, &temp_scale->dividend, &temp_scale->divisor,
ADIS_TEMP_CHAN);
}
43 changes: 23 additions & 20 deletions drivers/imu/adis.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,17 @@ enum adis_device_id {
ADIS16577_3,
};

/**
* @brief Supported channels
*/
enum adis_chan_type {
ADIS_ACCL_CHAN,
ADIS_GYRO_CHAN,
ADIS_TEMP_CHAN,
ADIS_DELTAANGL_CHAN,
ADIS_DELTAVEL_CHAN,
};

/** @struct adis_diag_flags
* @brief Bitfield struct which maps on the diagnosis register
*/
Expand Down Expand Up @@ -208,6 +219,14 @@ struct adis_clk_freq_limit {
uint32_t max_freq;
};

/** @struct adis_scale_members
* @brief ADIS generic scale members structure.
*/
struct adis_scale_members {
uint32_t scale_m1;
uint32_t scale_m2;
};

/** @struct adis_scale_fractional
* @brief ADIS fractional scale format structure; scale = dividend/divisor
*/
Expand Down Expand Up @@ -240,16 +259,6 @@ struct adis_dev {
const struct adis_chip_info *info;
/** Current diagnosis flags values. */
struct adis_diag_flags diag_flags;
/** Gyroscope fractional scale. */
struct adis_scale_fractional anglvel_scale;
/** Accelerometer fractional scale. */
struct adis_scale_fractional accl_scale;
/** Delta angle fractional log2 scale. */
struct adis_scale_fractional_log2 deltaangl_scale;
/** Delta velocity fractional log2 scale. */
struct adis_scale_fractional_log2 deltavelocity_scale;
/** Temperature fractional scale. */
struct adis_scale_fractional temp_scale;
/** Current device id, specified by the user */
enum adis_device_id dev_id;
/** Current page to be accessed in register map. */
Expand Down Expand Up @@ -507,16 +516,6 @@ struct adis_chip_info {
const struct adis_clk_freq_limit sampling_clk_limits;
/** Chip specific timeouts. */
const struct adis_timeout *timeouts;
/** Gyroscope fractional scale. */
const struct adis_scale_fractional *anglvel_scale;
/** Accelerometer fractional scale. */
const struct adis_scale_fractional *accl_scale;
/** Delta angle fractional log2 scale. */
const struct adis_scale_fractional_log2 *deltaangl_scale;
/** Delta velocity fractional log2 scale. */
const struct adis_scale_fractional_log2 *deltavelocity_scale;
/** Temperature fractional scale. */
const struct adis_scale_fractional *temp_scale;
/** Chip specific flags. */
const uint32_t flags;
/** Chip specific read delay for SPI transactions. */
Expand All @@ -543,6 +542,10 @@ struct adis_chip_info {
uint8_t bias_corr_tbc_max;
/** Chip specific internal clock frequency in Hertz. */
uint32_t int_clk;
/** Chip specific implementation to obtain the channel scale members. */
int (*get_scale)(struct adis_dev *adis,
uint32_t *scale_m1, uint32_t *scale_m2,
enum adis_chan_type chan_type);
};

/******************************************************************************/
Expand Down
158 changes: 98 additions & 60 deletions drivers/imu/adis1646x.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@
#include "adis1646x.h"
#include "no_os_units.h"

/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/

#define ADIS1646X_ID_NO_OFFSET(x) ((x) - ADIS16465_1)

/******************************************************************************/
/************************** Variable Definitions ******************************/
/******************************************************************************/
Expand Down Expand Up @@ -139,89 +145,121 @@ static const struct adis_clk_freq_limit adis1646x_sampling_clk_limits = {
};

/* Values from datasheet for 32-bit data */
static const struct adis_scale_fractional adis1646x_anglvel_scale[] = {
[ADIS16465_1] = {1, RAD_TO_DEGREE(160 << 16)},
[ADIS16465_2] = {1, RAD_TO_DEGREE(40 << 16)},
[ADIS16465_3] = {1, RAD_TO_DEGREE(10 << 16)},
[ADIS16467_1] = {1, RAD_TO_DEGREE(160 << 16)},
[ADIS16467_2] = {1, RAD_TO_DEGREE(40 << 16)},
[ADIS16467_3] = {1, RAD_TO_DEGREE(10 << 16)},
[ADIS16470] = {1, RAD_TO_DEGREE(10 << 16)},
[ADIS16475_1] = {1, RAD_TO_DEGREE(160 << 16)},
[ADIS16475_2] = {1, RAD_TO_DEGREE(40 << 16)},
[ADIS16475_3] = {1, RAD_TO_DEGREE(10 << 16)},
static const struct adis_scale_members adis1646x_anglvel_scale[] = {
[ADIS1646X_ID_NO_OFFSET(ADIS16465_1)] = {1, RAD_TO_DEGREE(160 << 16)},
[ADIS1646X_ID_NO_OFFSET(ADIS16465_2)] = {1, RAD_TO_DEGREE(40 << 16)},
[ADIS1646X_ID_NO_OFFSET(ADIS16465_3)] = {1, RAD_TO_DEGREE(10 << 16)},
[ADIS1646X_ID_NO_OFFSET(ADIS16467_1)] = {1, RAD_TO_DEGREE(160 << 16)},
[ADIS1646X_ID_NO_OFFSET(ADIS16467_2)] = {1, RAD_TO_DEGREE(40 << 16)},
[ADIS1646X_ID_NO_OFFSET(ADIS16467_3)] = {1, RAD_TO_DEGREE(10 << 16)},
[ADIS1646X_ID_NO_OFFSET(ADIS16470)] = {1, RAD_TO_DEGREE(10 << 16)},
[ADIS1646X_ID_NO_OFFSET(ADIS16475_1)] = {1, RAD_TO_DEGREE(160 << 16)},
[ADIS1646X_ID_NO_OFFSET(ADIS16475_2)] = {1, RAD_TO_DEGREE(40 << 16)},
[ADIS1646X_ID_NO_OFFSET(ADIS16475_3)] = {1, RAD_TO_DEGREE(10 << 16)},
};

static const struct adis_scale_fractional adis1646x_accl_scale[] = {
[ADIS16465_1] = {1, M_S_2_TO_G(4000 << 16)},
[ADIS16465_2] = {1, M_S_2_TO_G(4000 << 16)},
[ADIS16465_3] = {1, M_S_2_TO_G(4000 << 16)},
[ADIS16467_1] = {1, M_S_2_TO_G(800 << 16)},
[ADIS16467_2] = {1, M_S_2_TO_G(800 << 16)},
[ADIS16467_3] = {1, M_S_2_TO_G(800 << 16)},
[ADIS16470] = {1, M_S_2_TO_G(800 << 16)},
[ADIS16475_1] = {1, M_S_2_TO_G(4000 << 16)},
[ADIS16475_2] = {1, M_S_2_TO_G(4000 << 16)},
[ADIS16475_3] = {1, M_S_2_TO_G(4000 << 16)},
static const struct adis_scale_members adis1646x_accl_scale[] = {
[ADIS1646X_ID_NO_OFFSET(ADIS16465_1)] = {1, M_S_2_TO_G(4000 << 16)},
[ADIS1646X_ID_NO_OFFSET(ADIS16465_2)] = {1, M_S_2_TO_G(4000 << 16)},
[ADIS1646X_ID_NO_OFFSET(ADIS16465_3)] = {1, M_S_2_TO_G(4000 << 16)},
[ADIS1646X_ID_NO_OFFSET(ADIS16467_1)] = {1, M_S_2_TO_G(800 << 16)},
[ADIS1646X_ID_NO_OFFSET(ADIS16467_2)] = {1, M_S_2_TO_G(800 << 16)},
[ADIS1646X_ID_NO_OFFSET(ADIS16467_3)] = {1, M_S_2_TO_G(800 << 16)},
[ADIS1646X_ID_NO_OFFSET(ADIS16470)] = {1, M_S_2_TO_G(800 << 16)},
[ADIS1646X_ID_NO_OFFSET(ADIS16475_1)] = {1, M_S_2_TO_G(4000 << 16)},
[ADIS1646X_ID_NO_OFFSET(ADIS16475_2)] = {1, M_S_2_TO_G(4000 << 16)},
[ADIS1646X_ID_NO_OFFSET(ADIS16475_3)] = {1, M_S_2_TO_G(4000 << 16)},
};

static const struct adis_scale_fractional_log2 adis1646x_deltaangl_scale[] = {
[ADIS16465_1] = {DEGREE_TO_RAD(360), 31},
[ADIS16465_2] = {DEGREE_TO_RAD(720), 31},
[ADIS16465_3] = {DEGREE_TO_RAD(2160), 31},
[ADIS16467_1] = {DEGREE_TO_RAD(360), 31},
[ADIS16467_2] = {DEGREE_TO_RAD(720), 31},
[ADIS16467_3] = {DEGREE_TO_RAD(2160), 31},
[ADIS16470] = {DEGREE_TO_RAD(2160), 31},
[ADIS16475_1] = {DEGREE_TO_RAD(360), 31},
[ADIS16475_2] = {DEGREE_TO_RAD(720), 31},
[ADIS16475_3] = {DEGREE_TO_RAD(2160), 31},
static const struct adis_scale_members adis1646x_deltaangl_scale[] = {
[ADIS1646X_ID_NO_OFFSET(ADIS16465_1)] = {DEGREE_TO_RAD(360), 31},
[ADIS1646X_ID_NO_OFFSET(ADIS16465_2)] = {DEGREE_TO_RAD(720), 31},
[ADIS1646X_ID_NO_OFFSET(ADIS16465_3)] = {DEGREE_TO_RAD(2160), 31},
[ADIS1646X_ID_NO_OFFSET(ADIS16467_1)] = {DEGREE_TO_RAD(360), 31},
[ADIS1646X_ID_NO_OFFSET(ADIS16467_2)] = {DEGREE_TO_RAD(720), 31},
[ADIS1646X_ID_NO_OFFSET(ADIS16467_3)] = {DEGREE_TO_RAD(2160), 31},
[ADIS1646X_ID_NO_OFFSET(ADIS16470)] = {DEGREE_TO_RAD(2160), 31},
[ADIS1646X_ID_NO_OFFSET(ADIS16475_1)] = {DEGREE_TO_RAD(360), 31},
[ADIS1646X_ID_NO_OFFSET(ADIS16475_2)] = {DEGREE_TO_RAD(720), 31},
[ADIS1646X_ID_NO_OFFSET(ADIS16475_3)] = {DEGREE_TO_RAD(2160), 31},
};

static const struct adis_scale_fractional_log2 adis1646x_deltavelocity_scale[]
static const struct adis_scale_members adis1646x_deltavelocity_scale[]
= {
[ADIS16465_1] = {100, 31},
[ADIS16465_2] = {100, 31},
[ADIS16465_3] = {100, 31},
[ADIS16467_1] = {400, 31},
[ADIS16467_2] = {400, 31},
[ADIS16467_3] = {400, 31},
[ADIS16470] = {400, 31},
[ADIS16475_1] = {100, 31},
[ADIS16475_2] = {100, 31},
[ADIS16475_3] = {100, 31},
[ADIS1646X_ID_NO_OFFSET(ADIS16465_1)] = {100, 31},
[ADIS1646X_ID_NO_OFFSET(ADIS16465_2)] = {100, 31},
[ADIS1646X_ID_NO_OFFSET(ADIS16465_3)] = {100, 31},
[ADIS1646X_ID_NO_OFFSET(ADIS16467_1)] = {400, 31},
[ADIS1646X_ID_NO_OFFSET(ADIS16467_2)] = {400, 31},
[ADIS1646X_ID_NO_OFFSET(ADIS16467_3)] = {400, 31},
[ADIS1646X_ID_NO_OFFSET(ADIS16470)] = {400, 31},
[ADIS1646X_ID_NO_OFFSET(ADIS16475_1)] = {100, 31},
[ADIS1646X_ID_NO_OFFSET(ADIS16475_2)] = {100, 31},
[ADIS1646X_ID_NO_OFFSET(ADIS16475_3)] = {100, 31},
};

/* Milli-degrees Celsius for temperature */
static const struct adis_scale_fractional adis1646x_temp_scale[] = {
[ADIS16465_1] = {1 * MILLIDEGREE_PER_DEGREE, 10},
[ADIS16465_2] = {1 * MILLIDEGREE_PER_DEGREE, 10},
[ADIS16465_3] = {1 * MILLIDEGREE_PER_DEGREE, 10},
[ADIS16467_1] = {1 * MILLIDEGREE_PER_DEGREE, 10},
[ADIS16467_2] = {1 * MILLIDEGREE_PER_DEGREE, 10},
[ADIS16467_3] = {1 * MILLIDEGREE_PER_DEGREE, 10},
[ADIS16470] = {1 * MILLIDEGREE_PER_DEGREE, 10},
[ADIS16475_1] = {1 * MILLIDEGREE_PER_DEGREE, 10},
[ADIS16475_2] = {1 * MILLIDEGREE_PER_DEGREE, 10},
[ADIS16475_3] = {1 * MILLIDEGREE_PER_DEGREE, 10},
static const struct adis_scale_members adis1646x_temp_scale[] = {
[ADIS1646X_ID_NO_OFFSET(ADIS16465_1)] = {1 * MILLIDEGREE_PER_DEGREE, 10},
[ADIS1646X_ID_NO_OFFSET(ADIS16465_2)] = {1 * MILLIDEGREE_PER_DEGREE, 10},
[ADIS1646X_ID_NO_OFFSET(ADIS16465_3)] = {1 * MILLIDEGREE_PER_DEGREE, 10},
[ADIS1646X_ID_NO_OFFSET(ADIS16467_1)] = {1 * MILLIDEGREE_PER_DEGREE, 10},
[ADIS1646X_ID_NO_OFFSET(ADIS16467_2)] = {1 * MILLIDEGREE_PER_DEGREE, 10},
[ADIS1646X_ID_NO_OFFSET(ADIS16467_3)] = {1 * MILLIDEGREE_PER_DEGREE, 10},
[ADIS1646X_ID_NO_OFFSET(ADIS16470)] = {1 * MILLIDEGREE_PER_DEGREE, 10},
[ADIS1646X_ID_NO_OFFSET(ADIS16475_1)] = {1 * MILLIDEGREE_PER_DEGREE, 10},
[ADIS1646X_ID_NO_OFFSET(ADIS16475_2)] = {1 * MILLIDEGREE_PER_DEGREE, 10},
[ADIS1646X_ID_NO_OFFSET(ADIS16475_3)] = {1 * MILLIDEGREE_PER_DEGREE, 10},
};

static int adis1646x_get_scale(struct adis_dev *adis,
uint32_t *scale_m1, uint32_t *scale_m2,
enum adis_chan_type chan_type)
{
switch(chan_type) {
case ADIS_ACCL_CHAN:
*scale_m1 = adis1646x_accl_scale[ADIS1646X_ID_NO_OFFSET(adis->dev_id)].scale_m1;
*scale_m2 = adis1646x_accl_scale[ADIS1646X_ID_NO_OFFSET(adis->dev_id)].scale_m2;
return 0;
case ADIS_GYRO_CHAN:
*scale_m1 = adis1646x_anglvel_scale[ADIS1646X_ID_NO_OFFSET(
adis->dev_id)].scale_m1;
*scale_m2 = adis1646x_anglvel_scale[ADIS1646X_ID_NO_OFFSET(
adis->dev_id)].scale_m2;
return 0;
case ADIS_TEMP_CHAN:
*scale_m1 = adis1646x_temp_scale[ADIS1646X_ID_NO_OFFSET(adis->dev_id)].scale_m1;
*scale_m2 = adis1646x_temp_scale[ADIS1646X_ID_NO_OFFSET(adis->dev_id)].scale_m2;
return 0;
case ADIS_DELTAANGL_CHAN:
*scale_m1 = adis1646x_deltaangl_scale[ADIS1646X_ID_NO_OFFSET(
adis->dev_id)].scale_m1;
*scale_m2 = adis1646x_deltaangl_scale[ADIS1646X_ID_NO_OFFSET(
adis->dev_id)].scale_m2;
return 0;
case ADIS_DELTAVEL_CHAN:
*scale_m1 = adis1646x_deltavelocity_scale[ADIS1646X_ID_NO_OFFSET(
adis->dev_id)].scale_m1;
*scale_m2 = adis1646x_deltavelocity_scale[ADIS1646X_ID_NO_OFFSET(
adis->dev_id)].scale_m2;
return 0;
default:
return -EINVAL;
}
}

struct adis_chip_info adis1646x_chip_info = {
.cs_change_delay = 16,
.read_delay = 8,
.write_delay = 0,
.timeouts = &adis1646x_timeouts,
.field_map = &adis1646x_def,
.anglvel_scale = adis1646x_anglvel_scale,
.accl_scale = adis1646x_accl_scale,
.deltaangl_scale = adis1646x_deltaangl_scale,
.deltavelocity_scale = adis1646x_deltavelocity_scale,
.temp_scale = adis1646x_temp_scale,
.filt_size_var_b_max = 6,
.dec_rate_max = 1999,
.sync_mode_max = ADIS_SYNC_PULSE,
.fls_mem_wr_cntr_max = 10000,
.int_clk = 2000,
.sync_clk_freq_limits = adis1646x_sync_clk_freq_limits,
.sampling_clk_limits = adis1646x_sampling_clk_limits,
.get_scale = &adis1646x_get_scale,
};
Loading

0 comments on commit fccff3a

Please sign in to comment.