drivers: sensor: ina237: add high-precision mode
The current-shunt calibration requires a factor of 4x if high-precision mode is selected. Signed-off-by: Eric Holmberg <eric.holmberg@northriversystems.co.nz>
This commit is contained in:
parent
2d3a391191
commit
a70d056513
6 changed files with 112 additions and 7 deletions
|
@ -22,8 +22,8 @@ LOG_MODULE_REGISTER(INA237, CONFIG_SENSOR_LOG_LEVEL);
|
|||
/** @brief The LSB value for the bus voltage register, in microvolts/LSB. */
|
||||
#define INA237_BUS_VOLTAGE_TO_uV(x) ((x) * 3125U)
|
||||
|
||||
/** @brief Power scaling (scaled by 10) */
|
||||
#define INA237_POWER_SCALING 2
|
||||
/** @brief Power scaling (need factor of 0.2) */
|
||||
#define INA237_POWER_TO_uW(x) ((x) / 5ULL)
|
||||
|
||||
/**
|
||||
* @brief Scale die temperture from 0.125 degC/bit to micro-degrees C
|
||||
|
@ -37,6 +37,12 @@ static void micro_s32_to_sensor_value(struct sensor_value *val, int32_t value_mi
|
|||
val->val2 = value_microX % 1000000L;
|
||||
}
|
||||
|
||||
static void micro_u64_to_sensor_value(struct sensor_value *val, uint64_t value_microX)
|
||||
{
|
||||
val->val1 = value_microX / 1000000U;
|
||||
val->val2 = value_microX % 1000000U;
|
||||
}
|
||||
|
||||
static int ina237_channel_get(const struct device *dev, enum sensor_channel chan,
|
||||
struct sensor_value *val)
|
||||
{
|
||||
|
@ -54,9 +60,9 @@ static int ina237_channel_get(const struct device *dev, enum sensor_channel chan
|
|||
break;
|
||||
|
||||
case SENSOR_CHAN_POWER:
|
||||
/* see datasheet "Current and Power calculations" section */
|
||||
micro_s32_to_sensor_value(val,
|
||||
(data->power * INA237_POWER_SCALING * config->current_lsb) / 10000U);
|
||||
/* power in uW is power_reg * current_lsb * 0.2 */
|
||||
micro_u64_to_sensor_value(val,
|
||||
INA237_POWER_TO_uW((uint64_t)data->power * config->current_lsb));
|
||||
break;
|
||||
|
||||
case SENSOR_CHAN_DIE_TEMP:
|
||||
|
@ -364,6 +370,10 @@ static const struct sensor_driver_api ina237_driver_api = {
|
|||
.channel_get = ina237_channel_get,
|
||||
};
|
||||
|
||||
/* Shunt calibration must be muliplied by 4 if high-prevision mode is selected */
|
||||
#define CAL_PRECISION_MULTIPLIER(config) \
|
||||
(((config & INA237_CFG_HIGH_PRECISION) >> 4) * 3 + 1)
|
||||
|
||||
#define INA237_DRIVER_INIT(inst) \
|
||||
static struct ina237_data ina237_data_##inst; \
|
||||
static const struct ina237_config ina237_config_##inst = { \
|
||||
|
@ -376,8 +386,9 @@ static const struct sensor_driver_api ina237_driver_api = {
|
|||
(DT_INST_ENUM_IDX(inst, temp_conversion_time_us) << 3) | \
|
||||
DT_INST_ENUM_IDX(inst, avg_count), \
|
||||
.current_lsb = DT_INST_PROP(inst, current_lsb_microamps), \
|
||||
.cal = INA237_CAL_SCALING * DT_INST_PROP(inst, current_lsb_microamps) * \
|
||||
DT_INST_PROP(inst, rshunt_micro_ohms) / 10000000000ULL, \
|
||||
.cal = CAL_PRECISION_MULTIPLIER(DT_INST_PROP(inst, config)) * \
|
||||
INA237_CAL_SCALING * DT_INST_PROP(inst, current_lsb_microamps) * \
|
||||
DT_INST_PROP(inst, rshunt_micro_ohms) / 10000000ULL, \
|
||||
.alert_config = DT_INST_PROP_OR(inst, alert_config, 0x01), \
|
||||
.alert_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, alert_gpios, {0}), \
|
||||
}; \
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#include <zephyr/drivers/sensor.h>
|
||||
|
||||
#define INA237_REG_CONFIG 0x00
|
||||
#define INA237_CFG_HIGH_PRECISION BIT(4)
|
||||
|
||||
#define INA237_REG_ADC_CONFIG 0x01
|
||||
#define INA237_REG_CALIB 0x02
|
||||
#define INA237_REG_SHUNT_VOLT 0x04
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue