adc: provide API to help with conversions
Gain values are specified with enumeration values that can't be used to reverse the effects of scaling the input signal. Provide a function that reverses the effect of the gain by scaling a measured value. Also provide a function that converts a raw measurement captured with a reference voltage and specific gain and resolution to the corresponding voltage in millivolts. Signed-off-by: Peter A. Bigot <pab@pabigot.com>
This commit is contained in:
parent
6438195701
commit
4420c5ed40
3 changed files with 101 additions and 0 deletions
|
@ -2,6 +2,7 @@
|
|||
|
||||
zephyr_library()
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_ADC adc_common.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_ADC_SHELL adc_shell.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_ADC_MCUX_ADC12 adc_mcux_adc12.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_ADC_MCUX_ADC16 adc_mcux_adc16.c)
|
||||
|
|
44
drivers/adc/adc_common.c
Normal file
44
drivers/adc/adc_common.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Peter Bigot Consulting, LLC
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <drivers/adc.h>
|
||||
|
||||
int adc_gain_invert(enum adc_gain gain,
|
||||
s32_t *value)
|
||||
{
|
||||
struct gain_desc {
|
||||
u8_t mul;
|
||||
u8_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_1_3] = {.mul = 3, .div = 1},
|
||||
[ADC_GAIN_1_2] = {.mul = 2, .div = 1},
|
||||
[ADC_GAIN_2_3] = {.mul = 3, .div = 2},
|
||||
[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_8] = {.mul = 1, .div = 8},
|
||||
[ADC_GAIN_16] = {.mul = 1, .div = 16},
|
||||
[ADC_GAIN_32] = {.mul = 1, .div = 32},
|
||||
[ADC_GAIN_64] = {.mul = 1, .div = 64},
|
||||
};
|
||||
int rv = -EINVAL;
|
||||
|
||||
if ((u8_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;
|
||||
}
|
|
@ -45,6 +45,25 @@ enum adc_gain {
|
|||
ADC_GAIN_128, /**< x 128. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @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(enum adc_gain gain,
|
||||
s32_t *value);
|
||||
|
||||
/** @brief ADC references. */
|
||||
enum adc_reference {
|
||||
ADC_REF_VDD_1, /**< VDD. */
|
||||
|
@ -135,6 +154,43 @@ struct adc_channel_cfg {
|
|||
#endif /* CONFIG_ADC_CONFIGURABLE_INPUTS */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Convert a raw ADC value to millivolts.
|
||||
*
|
||||
* This function performs the necessary conversion to transform a raw
|
||||
* ADC measurement to a voltage in millivolts.
|
||||
*
|
||||
* @param ref_mv the reference voltage used for the measurement, in
|
||||
* millivolts. This may be from adc_ref_internal() or a known
|
||||
* external reference.
|
||||
*
|
||||
* @param gain the ADC gain configuration used to sample the input
|
||||
*
|
||||
* @param resolution the number of bits in the absolute value of the
|
||||
* sample. For differential sampling this may be one less than the
|
||||
* resolution in struct adc_sequence.
|
||||
*
|
||||
* @param valp pointer to the raw measurement value on input, and the
|
||||
* corresponding millivolt value on successful conversion. If
|
||||
* conversion fails the stored value is left unchanged.
|
||||
*
|
||||
* @retval 0 on successful conversion
|
||||
* @retval -EINVAL if the gain is not reversible
|
||||
*/
|
||||
static inline int adc_raw_to_millivolts(s32_t ref_mv,
|
||||
enum adc_gain gain,
|
||||
u8_t resolution,
|
||||
s32_t *valp)
|
||||
{
|
||||
s32_t adc_mv = *valp * ref_mv;
|
||||
int ret = adc_gain_invert(gain, &adc_mv);
|
||||
|
||||
if (ret == 0) {
|
||||
*valp = (adc_mv >> resolution);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Forward declaration of the adc_sequence structure. */
|
||||
struct adc_sequence;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue