adc: 64bit gain inversion function

Add a variant of `adc_gain_invert` that operates on an `int64_t` instead
of `int32_t`.

Signed-off-by: Jordan Yates <jordan@embeint.com>
This commit is contained in:
Jordan Yates 2025-02-20 13:19:29 +10:00 committed by Fabio Baltieri
commit 8ab300d63e
2 changed files with 64 additions and 31 deletions

View file

@ -6,36 +6,52 @@
#include <zephyr/drivers/adc.h>
int adc_gain_invert(enum adc_gain gain,
int32_t *value)
struct gain_desc {
uint8_t mul;
uint8_t div;
};
static const struct gain_desc gains[] = {
[ADC_GAIN_1_6] = {.mul = 6, .div = 1},
[ADC_GAIN_1_5] = {.mul = 5, .div = 1},
[ADC_GAIN_1_4] = {.mul = 4, .div = 1},
[ADC_GAIN_2_7] = {.mul = 7, .div = 2},
[ADC_GAIN_1_3] = {.mul = 3, .div = 1},
[ADC_GAIN_2_5] = {.mul = 5, .div = 2},
[ADC_GAIN_1_2] = {.mul = 2, .div = 1},
[ADC_GAIN_2_3] = {.mul = 3, .div = 2},
[ADC_GAIN_4_5] = {.mul = 5, .div = 4},
[ADC_GAIN_1] = {.mul = 1, .div = 1},
[ADC_GAIN_2] = {.mul = 1, .div = 2},
[ADC_GAIN_3] = {.mul = 1, .div = 3},
[ADC_GAIN_4] = {.mul = 1, .div = 4},
[ADC_GAIN_6] = {.mul = 1, .div = 6},
[ADC_GAIN_8] = {.mul = 1, .div = 8},
[ADC_GAIN_12] = {.mul = 1, .div = 12},
[ADC_GAIN_16] = {.mul = 1, .div = 16},
[ADC_GAIN_24] = {.mul = 1, .div = 24},
[ADC_GAIN_32] = {.mul = 1, .div = 32},
[ADC_GAIN_64] = {.mul = 1, .div = 64},
[ADC_GAIN_128] = {.mul = 1, .div = 128},
};
int adc_gain_invert(enum adc_gain gain, int32_t *value)
{
int rv = -EINVAL;
if ((uint8_t)gain < ARRAY_SIZE(gains)) {
const struct gain_desc *gdp = &gains[gain];
if ((gdp->mul != 0) && (gdp->div != 0)) {
*value = (gdp->mul * *value) / gdp->div;
rv = 0;
}
}
return rv;
}
int adc_gain_invert_64(enum adc_gain gain, int64_t *value)
{
struct gain_desc {
uint8_t mul;
uint8_t div;
};
static const struct gain_desc gains[] = {
[ADC_GAIN_1_6] = {.mul = 6, .div = 1},
[ADC_GAIN_1_5] = {.mul = 5, .div = 1},
[ADC_GAIN_1_4] = {.mul = 4, .div = 1},
[ADC_GAIN_2_7] = {.mul = 7, .div = 2},
[ADC_GAIN_1_3] = {.mul = 3, .div = 1},
[ADC_GAIN_2_5] = {.mul = 5, .div = 2},
[ADC_GAIN_1_2] = {.mul = 2, .div = 1},
[ADC_GAIN_2_3] = {.mul = 3, .div = 2},
[ADC_GAIN_4_5] = {.mul = 5, .div = 4},
[ADC_GAIN_1] = {.mul = 1, .div = 1},
[ADC_GAIN_2] = {.mul = 1, .div = 2},
[ADC_GAIN_3] = {.mul = 1, .div = 3},
[ADC_GAIN_4] = {.mul = 1, .div = 4},
[ADC_GAIN_6] = {.mul = 1, .div = 6},
[ADC_GAIN_8] = {.mul = 1, .div = 8},
[ADC_GAIN_12] = {.mul = 1, .div = 12},
[ADC_GAIN_16] = {.mul = 1, .div = 16},
[ADC_GAIN_24] = {.mul = 1, .div = 24},
[ADC_GAIN_32] = {.mul = 1, .div = 32},
[ADC_GAIN_64] = {.mul = 1, .div = 64},
[ADC_GAIN_128] = {.mul = 1, .div = 128},
};
int rv = -EINVAL;
if ((uint8_t)gain < ARRAY_SIZE(gains)) {

View file

@ -71,8 +71,25 @@ enum adc_gain {
* @retval 0 if the gain was successfully reversed
* @retval -EINVAL if the gain could not be interpreted
*/
int adc_gain_invert(enum adc_gain gain,
int32_t *value);
int adc_gain_invert(enum adc_gain gain, int32_t *value);
/**
* @brief Invert the application of gain to a measurement value.
*
* For example, if the gain passed in is ADC_GAIN_1_6 and the
* referenced value is 10, the value after the function returns is 60.
*
* @param gain the gain used to amplify the input signal.
*
* @param value a pointer to a value that initially has the effect of
* the applied gain but has that effect removed when this function
* successfully returns. If the gain cannot be reversed the value
* remains unchanged.
*
* @retval 0 if the gain was successfully reversed
* @retval -EINVAL if the gain could not be interpreted
*/
int adc_gain_invert_64(enum adc_gain gain, int64_t *value);
/** @brief ADC references. */
enum adc_reference {