From c50149e4889c7267bf93a47bf94d723a7309e835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20H=C3=BC=C3=9Fler?= Date: Tue, 2 Feb 2021 11:15:12 +0100 Subject: [PATCH] drivers/ina3221: refactor --- drivers/ina3221/alerts.c | 12 +- drivers/ina3221/ina3221.c | 535 +++++------- drivers/include/ina3221.h | 971 ++++++++++----------- drivers/saul/init_devs/auto_init_ina3221.c | 2 +- 4 files changed, 695 insertions(+), 825 deletions(-) diff --git a/drivers/ina3221/alerts.c b/drivers/ina3221/alerts.c index 5149424510..fb1406a0df 100644 --- a/drivers/ina3221/alerts.c +++ b/drivers/ina3221/alerts.c @@ -23,8 +23,8 @@ #include "periph/gpio.h" #include "ina3221.h" -int _ina3221_enable_alert(ina3221_t *dev, ina3221_alert_t alert, - ina3221_alert_cb_t cb, void *arg) +int ina3221_enable_alert(ina3221_t *dev, ina3221_alert_t alert, + ina3221_alert_cb_t cb, void *arg) { if (alert >= INA3221_NUM_ALERTS) { return -ERANGE; @@ -36,15 +36,15 @@ int _ina3221_enable_alert(ina3221_t *dev, ina3221_alert_t alert, dev->alert_callback_arguments[alert] = arg; int check = gpio_init_int( dev->params.upins.apins.alert_pins[alert], - (dev->params.gpio_config & (1 << alert)) ? GPIO_IN_PU : GPIO_IN, + (dev->params.gpio_config & (1U << alert)) ? GPIO_IN_PU : GPIO_IN, GPIO_FALLING, cb, arg ); - return check ? check : INA3221_OK; + return check ? check : 0; } -int _ina3221_disable_alert(ina3221_t *dev, ina3221_alert_t alert) +int ina3221_disable_alert(ina3221_t *dev, ina3221_alert_t alert) { if (alert >= INA3221_NUM_ALERTS) { return -ERANGE; @@ -53,5 +53,5 @@ int _ina3221_disable_alert(ina3221_t *dev, ina3221_alert_t alert) return -ENOTSUP; } gpio_irq_disable(dev->params.upins.apins.alert_pins[alert]); - return INA3221_OK; + return 0; } diff --git a/drivers/ina3221/ina3221.c b/drivers/ina3221/ina3221.c index 3789a29e2b..38725e7289 100644 --- a/drivers/ina3221/ina3221.c +++ b/drivers/ina3221/ina3221.c @@ -24,39 +24,24 @@ #include #include "byteorder.h" #include "ina3221_internal.h" -#include "ina3221_params.h" #include "ina3221_regs.h" #include "ina3221.h" + #define ENABLE_DEBUG 0 #include "debug.h" -typedef struct { - uint8_t chi_reg_shunt; - uint8_t chi_reg_bus; - uint8_t chi_reg_crit_alert_limit; - uint8_t chi_reg_warn_alert_limit; -} ina3221_channel_info_t; +/* register addresses differ by 2 */ +#define INA3221_REG_CH_SHUNT_VOLTAGE(i) \ + (INA3221_REG_CH1_SHUNT_VOLTAGE + (i * 2)) -static ina3221_channel_info_t _chi[INA3221_NUM_CH] = { - { - .chi_reg_shunt = INA3221_REG_CH1_SHUNT_VOLTAGE, - .chi_reg_bus = INA3221_REG_CH1_BUS_VOLTAGE, - .chi_reg_crit_alert_limit = INA3221_REG_CH1_CRIT_ALERT_LIMIT, - .chi_reg_warn_alert_limit = INA3221_REG_CH1_WARN_ALERT_LIMIT - }, - { - .chi_reg_shunt = INA3221_REG_CH2_SHUNT_VOLTAGE, - .chi_reg_bus = INA3221_REG_CH2_BUS_VOLTAGE, - .chi_reg_crit_alert_limit = INA3221_REG_CH2_CRIT_ALERT_LIMIT, - .chi_reg_warn_alert_limit = INA3221_REG_CH2_WARN_ALERT_LIMIT - }, - { - .chi_reg_shunt = INA3221_REG_CH3_SHUNT_VOLTAGE, - .chi_reg_bus = INA3221_REG_CH3_BUS_VOLTAGE, - .chi_reg_crit_alert_limit = INA3221_REG_CH3_CRIT_ALERT_LIMIT, - .chi_reg_warn_alert_limit = INA3221_REG_CH3_WARN_ALERT_LIMIT - } -}; +#define INA3221_REG_CH_BUS_VOLTAGE(i) \ + (INA3221_REG_CH1_BUS_VOLTAGE + (i * 2)) + +#define INA3221_REG_CH_CRIT_ALERT_LIMIT(i) \ + (INA3221_REG_CH1_CRIT_ALERT_LIMIT + (i * 2)) + +#define INA3221_REG_CH_WARN_ALERT_LIMIT(i) \ + (INA3221_REG_CH1_WARN_ALERT_LIMIT + (i * 2)) /** * @brief Read register value @@ -68,13 +53,13 @@ static ina3221_channel_info_t _chi[INA3221_NUM_CH] = { * @post @p out is in host byte order * * @return 0, on success - * @return -INA3221_I2C_ERROR, if i2c bus acquirement failed + * @return -EIO, if i2c bus acquirement failed * @return @see i2c_read_regs */ static int _read_reg(const ina3221_t *dev, uint8_t reg, uint16_t *out) { if (i2c_acquire(dev->params.i2c)) { - return -INA3221_I2C_ERROR; + return -EIO; } int status = i2c_read_regs(dev->params.i2c, dev->params.addr, reg, out, INA3221_REG_LEN, 0); @@ -96,14 +81,14 @@ static int _read_reg(const ina3221_t *dev, uint8_t reg, uint16_t *out) * @pre @p in must be in host byte order * * @return 0, on success - * @return -INA3221_I2C_ERROR, if i2c bus acquirement failed + * @return -EIO, if i2c bus acquirement failed * @return @see i2c_write_regs */ static int _write_reg(const ina3221_t *dev, uint8_t reg, uint16_t in) { in = htons(in); if (i2c_acquire(dev->params.i2c)) { - return -INA3221_I2C_ERROR; + return -EIO; } int status = i2c_write_regs(dev->params.i2c, dev->params.addr, reg, &in, INA3221_REG_LEN, 0); @@ -118,7 +103,6 @@ int ina3221_reset(ina3221_t *dev) { uint16_t config; int status = _write_reg(dev, INA3221_REG_CONFIGURATION, INA3221_RESET); - if (status < 0) { return status; } @@ -128,18 +112,17 @@ int ina3221_reset(ina3221_t *dev) return status; } if (config != INA3221_DEFCONFIG) { - return -INA3221_RESET_FAILED; + return -ENODEV; } dev->params.config = INA3221_DEFCONFIG; - return INA3221_OK; + return 0; } int ina3221_init(ina3221_t *dev, const ina3221_params_t *params) { int status; - if (!dev || !params) { - return -EINVAL; + return -EFAULT; } dev->params = *params; uint16_t id; @@ -148,34 +131,32 @@ int ina3221_init(ina3221_t *dev, const ina3221_params_t *params) return status; } if (id != INA3221_MANUFACTURER_ID) { - return -INA3221_BAD_MANUF_ID; + return -ENXIO; } status = _read_reg(dev, INA3221_REG_DIE_ID, &id); if (status < 0) { return status; } if (id != INA3221_DIE_ID) { - return -INA3221_BAD_DIE_ID; + return -ENXIO; } - if (ina3221_reset(dev) != INA3221_OK) { - return -INA3221_RESET_FAILED; - } - if (_ina3221_set_config(dev, params->config) != INA3221_OK) { - return -INA3221_CONFIG_FAILED; + if (ina3221_reset(dev) != 0) { + return -ENODEV; } uint16_t cfg; - if (_ina3221_get_config(dev, &cfg) != INA3221_OK || cfg != params->config) { - return -INA3221_CONFIG_FAILED; + if ((ina3221_set_config(dev, params->config) != 0) || + (ina3221_get_config(dev, &cfg) != 0)) { + return -EINVAL; } -#if defined(MODULE_INA3221_ALERTS) || defined(DOXYGEN) +#if IS_USED(MODULE_INA3221_ALERTS) || defined(DOXYGEN) memset(dev->alert_callbacks, 0, sizeof(dev->alert_callbacks)); memset(dev->alert_callback_arguments, 0, sizeof(dev->alert_callback_arguments)); #endif - return INA3221_OK; + return 0; } -int _ina3221_set_config(ina3221_t *dev, uint16_t cfg) +int ina3221_set_config(ina3221_t *dev, uint16_t cfg) { cfg &= ~INA3221_RESET; /* prevent accidental reset */ int status = _write_reg(dev, INA3221_REG_CONFIGURATION, cfg); @@ -183,282 +164,219 @@ int _ina3221_set_config(ina3221_t *dev, uint16_t cfg) return status; } dev->params.config = cfg; - return INA3221_OK; + return 0; } -int _ina3221_get_config(const ina3221_t *dev, uint16_t *cfg) +int ina3221_get_config(const ina3221_t *dev, uint16_t *cfg) { - *cfg = dev->params.config; + int status = _read_reg(dev, INA3221_REG_CONFIGURATION, cfg); + if (status < 0) { + return status; + } *cfg &= ~INA3221_RESET; /* clear reset flag */ - return INA3221_OK; + return 0; } -int _ina3221_set_enable_channel(ina3221_t *dev, uint16_t ech) +int ina3221_set_enable_channel(ina3221_t *dev, ina3221_ch_t ch) { uint16_t cfg; - int status = _read_reg(dev, INA3221_REG_CONFIGURATION, &cfg); - - if (status < 0) { + int status; + if ((status = ina3221_get_config(dev, &cfg)) < 0) { return status; } - cfg &= ~INA3221_ENABLE_CH_MASK; - cfg |= (ech & INA3221_ENABLE_CH_MASK); - status = _write_reg(dev, INA3221_REG_CONFIGURATION, cfg); - if (status < 0) { + ina3221_config_set_enabled_channels(&cfg, ch); + if ((status = ina3221_set_config(dev, cfg)) < 0) { return status; } - dev->params.config = cfg; - return INA3221_OK; -} - -int _ina3221_get_enable_channel(const ina3221_t *dev, uint16_t *ech) -{ - *ech = dev->params.config & INA3221_ENABLE_CH_MASK; - return ((*ech & INA3221_ENABLE_CH1) ? 1 : 0) + - ((*ech & INA3221_ENABLE_CH2) ? 1 : 0) + - ((*ech & INA3221_ENABLE_CH3) ? 1 : 0); + return 0; } int ina3221_set_num_samples(ina3221_t *dev, ina3221_num_samples_t ns) { uint16_t cfg; - int status = _read_reg(dev, INA3221_REG_CONFIGURATION, &cfg); - - if (status < 0) { + int status; + if ((status = ina3221_get_config(dev, &cfg)) < 0) { return status; } - cfg &= ~INA3221_NUM_SAMPLES_MASK; - cfg |= (ns & INA3221_NUM_SAMPLES_MASK); - status = _write_reg(dev, INA3221_REG_CONFIGURATION, cfg); - if (status < 0) { + ina3221_config_set_num_samples(&cfg, ns); + if ((status = ina3221_set_config(dev, cfg)) < 0) { return status; } - dev->params.config = cfg; - return INA3221_OK; -} - -int ina3221_get_num_samples(const ina3221_t *dev, ina3221_num_samples_t *ns) -{ - *ns = dev->params.config & INA3221_NUM_SAMPLES_MASK; - return INA3221_OK; + return 0; } int ina3221_set_conv_time_bus_adc(ina3221_t *dev, ina3221_conv_time_bus_adc_t ctb) { uint16_t cfg; - int status = _read_reg(dev, INA3221_REG_CONFIGURATION, &cfg); - - if (status < 0) { + int status; + if ((status = ina3221_get_config(dev, &cfg)) < 0) { return status; } - cfg &= ~INA3221_CONV_TIME_BADC_MASK; - cfg |= (ctb & INA3221_CONV_TIME_BADC_MASK); - status = _write_reg(dev, INA3221_REG_CONFIGURATION, cfg); - if (status < 0) { + ina3221_config_set_conv_time_bus(&cfg, ctb); + if ((status = ina3221_set_config(dev, cfg)) < 0) { return status; } - dev->params.config = cfg; - return INA3221_OK; -} - -int ina3221_get_conv_time_bus_adc(const ina3221_t *dev, - ina3221_conv_time_bus_adc_t *ctb) -{ - *ctb = dev->params.config & INA3221_CONV_TIME_BADC_MASK; - return INA3221_OK; + return 0; } int ina3221_set_conv_time_shunt_adc(ina3221_t *dev, - ina3221_conv_time_shunt_adc_t ctb) + ina3221_conv_time_shunt_adc_t cts) { uint16_t cfg; - int status = _read_reg(dev, INA3221_REG_CONFIGURATION, &cfg); - - if (status < 0) { + int status; + if ((status = ina3221_get_config(dev, &cfg)) < 0) { return status; } - cfg &= ~INA3221_CONV_TIME_SADC_MASK; - cfg |= (ctb & INA3221_CONV_TIME_SADC_MASK); - status = _write_reg(dev, INA3221_REG_CONFIGURATION, cfg); - if (status < 0) { + ina3221_config_set_conv_time_shunt(&cfg, cts); + if ((status = ina3221_set_config(dev, cfg)) < 0) { return status; } - dev->params.config = cfg; - return INA3221_OK; -} - -int ina3221_get_conv_time_shunt_adc(const ina3221_t *dev, - ina3221_conv_time_shunt_adc_t *ctb) -{ - *ctb = dev->params.config & INA3221_CONV_TIME_SADC_MASK; - return INA3221_OK; + return 0; } int ina3221_set_mode(ina3221_t *dev, ina3221_mode_t mode) { uint16_t cfg; - int status = _read_reg(dev, INA3221_REG_CONFIGURATION, &cfg); - - if (status < 0) { + int status; + if ((status = ina3221_get_config(dev, &cfg)) < 0) { return status; } - cfg &= ~INA3221_MODE_MASK; - cfg |= (mode & INA3221_MODE_MASK); - status = _write_reg(dev, INA3221_REG_CONFIGURATION, cfg); - if (status < 0) { + ina3221_config_set_mode(&cfg, mode); + if ((status = ina3221_set_config(dev, cfg)) < 0) { return status; } - dev->params.config = cfg; - return INA3221_OK; + return 0; } -int ina3221_get_mode(const ina3221_t *dev, ina3221_mode_t *mode) -{ - *mode = dev->params.config & INA3221_MODE_MASK; - return INA3221_OK; -} - -int _ina3221_set_enable_sum_channel(const ina3221_t *dev, - uint16_t esch) +int ina3221_set_enable_sum_channel(const ina3221_t *dev, ina3221_ch_t ch) { uint16_t mask_en; int status = _read_reg(dev, INA3221_REG_MASK_ENABLE, &mask_en); - if (status < 0) { return status; } mask_en &= ~INA3221_ENABLE_SUM_CH_MASK; - mask_en |= (esch & INA3221_ENABLE_SUM_CH_MASK); + mask_en |= ((ch & INA3221_CH1) ? INA3221_ENABLE_SUM_CH1 : 0) | + ((ch & INA3221_CH2) ? INA3221_ENABLE_SUM_CH2 : 0) | + ((ch & INA3221_CH3) ? INA3221_ENABLE_SUM_CH3 : 0); status = _write_reg(dev, INA3221_REG_MASK_ENABLE, mask_en); if (status < 0) { return status; } - return INA3221_OK; + return 0; } -int _ina3221_get_enable_sum_channel(const ina3221_t *dev, - uint16_t *esch) +int ina3221_get_enable_sum_channel(const ina3221_t *dev, ina3221_ch_t *ch) { uint16_t mask_en; int status = _read_reg(dev, INA3221_REG_MASK_ENABLE, &mask_en); - if (status < 0) { return status; } - *esch = mask_en & (INA3221_ENABLE_SUM_CH_MASK); - return ((*esch & INA3221_ENABLE_SUM_CH1) ? 1 : 0) + - ((*esch & INA3221_ENABLE_SUM_CH2) ? 1 : 0) + - ((*esch & INA3221_ENABLE_SUM_CH3) ? 1 : 0); + *ch = ((mask_en & INA3221_ENABLE_SUM_CH1) ? INA3221_CH1 : 0) | + ((mask_en & INA3221_ENABLE_SUM_CH2) ? INA3221_CH2 : 0) | + ((mask_en & INA3221_ENABLE_SUM_CH3) ? INA3221_CH3 : 0); + return 0; } -int ina3221_set_latch(const ina3221_t *dev, ina3221_enable_latch_t latch) +int ina3221_set_latch(const ina3221_t *dev, bool warn, bool crit) { uint16_t mask_en; int status = _read_reg(dev, INA3221_REG_MASK_ENABLE, &mask_en); - if (status < 0) { return status; } mask_en &= ~INA3221_ENABLE_LATCH_MASK; - mask_en |= (latch & INA3221_ENABLE_LATCH_MASK); + mask_en |= (warn ? INA3221_ENABLE_WARN_LATCH : 0); + mask_en |= (crit ? INA3221_ENABLE_CRIT_LATCH : 0); status = _write_reg(dev, INA3221_REG_MASK_ENABLE, mask_en); if (status < 0) { return status; } - return INA3221_OK; + return 0; } -int ina3221_get_latch(const ina3221_t *dev, ina3221_enable_latch_t *latch) +int ina3221_get_latch(const ina3221_t *dev, bool *warn, bool *crit) { uint16_t mask_en; int status = _read_reg(dev, INA3221_REG_MASK_ENABLE, &mask_en); - if (status < 0) { return status; } - *latch = mask_en & INA3221_ENABLE_LATCH_MASK; - return INA3221_OK; + *warn = !!(mask_en & INA3221_ENABLE_WARN_LATCH); + *crit = !!(mask_en & INA3221_ENABLE_CRIT_LATCH); + return 0; } -int ina3221_set_crit_alert_limit(const ina3221_t *dev, ina3221_channel_t ch, - int32_t in_uv) +ina3221_ch_t ina3221_set_crit_alert_limit(const ina3221_t *dev, + ina3221_ch_t ch, int32_t in_uv) { if (in_uv < INA3221_MIN_SHUNT_UV || in_uv > INA3221_MAX_SHUNT_UV) { - return -ERANGE; + return 0; } int16_t reg_val = shunt_voltage_uv_to_reg_val(in_uv); - int status = INA3221_OK; - int i, j; - for (i = 0, j = 0; i < INA3221_NUM_CH; i++) { - if (ch & (1 << i)) { - status = _write_reg(dev, _chi[i].chi_reg_crit_alert_limit, reg_val); - if (status < 0) { - break; + for (int i = 0; i < INA3221_NUM_CH; i++) { + if (ch & (1U << i)) { + if (_write_reg(dev, INA3221_REG_CH_CRIT_ALERT_LIMIT(i), reg_val)) { + ch &= ~(1U << i); } - j++; } } - return j ? j : status; + return ch; } -int ina3221_get_crit_alert_limit(const ina3221_t *dev, ina3221_channel_t ch, - int32_t *out_uv) +ina3221_ch_t ina3221_get_crit_alert_limit(const ina3221_t *dev, ina3221_ch_t ch, + int32_t out_uv[INA3221_NUM_CH]) { uint16_t reg_val; - int status = INA3221_OK; - int i, j; - - for (i = 0, j = 0; i < INA3221_NUM_CH; i++) { - if (ch & (1 << i)) { - status = _read_reg(dev, _chi[i].chi_reg_crit_alert_limit, ®_val); - if (status < 0) { - break; + for (int i = 0; i < INA3221_NUM_CH; i++) { + out_uv[i] = 0; + if (ch & (1U << i)) { + if (_read_reg(dev, INA3221_REG_CH_CRIT_ALERT_LIMIT(i), ®_val)) { + ch &= ~(1U << i); + } + else { + out_uv[i] = reg_val_to_shunt_voltage_uv(reg_val); } - out_uv[j++] = reg_val_to_shunt_voltage_uv(reg_val); } } - return j ? j : status; + return ch; } -int ina3221_set_warn_alert_limit(const ina3221_t *dev, ina3221_channel_t ch, - int32_t in_uv) +ina3221_ch_t ina3221_set_warn_alert_limit(const ina3221_t *dev, + ina3221_ch_t ch, int32_t in_uv) { if (in_uv < INA3221_MIN_SHUNT_UV || in_uv > INA3221_MAX_SHUNT_UV) { - return -ERANGE; + return 0; } int16_t reg_val = shunt_voltage_uv_to_reg_val(in_uv); - int status = INA3221_OK; - int i, j; - for (i = 0, j = 0; i < INA3221_NUM_CH; i++) { - if (ch & (1 << i)) { - status = _write_reg(dev, _chi[i].chi_reg_warn_alert_limit, reg_val); - if (status < 0) { - break; + for (int i = 0; i < INA3221_NUM_CH; i++) { + if (ch & (1U << i)) { + if (_write_reg(dev, INA3221_REG_CH_WARN_ALERT_LIMIT(i), reg_val)) { + ch &= ~(1U << i); } - j++; } } - return j ? j : status; + return ch; } -int ina3221_get_warn_alert_limit(const ina3221_t *dev, ina3221_channel_t ch, - int32_t *out_uv) +ina3221_ch_t ina3221_get_warn_alert_limit(const ina3221_t *dev, ina3221_ch_t ch, + int32_t out_uv[INA3221_NUM_CH]) { uint16_t reg_val; - int status = INA3221_OK; - int i, j; - - for (i = 0, j = 0; i < INA3221_NUM_CH; i++) { - if (ch & (1 << i)) { - status = _read_reg(dev, _chi[i].chi_reg_warn_alert_limit, ®_val); - if (status < 0) { - break; + for (int i = 0; i < INA3221_NUM_CH; i++) { + out_uv[i] = 0; + if (ch & (1U << i)) { + if (_read_reg(dev, INA3221_REG_CH_WARN_ALERT_LIMIT(i), ®_val)) { + ch &= ~(1U << i); + } + else { + out_uv[i] = reg_val_to_shunt_voltage_uv(reg_val); } - out_uv[j++] = reg_val_to_shunt_voltage_uv(reg_val); } } - return j ? j : status; + return ch; } int ina3221_set_shunt_voltage_sum_alert_limit(const ina3221_t *dev, @@ -472,7 +390,7 @@ int ina3221_set_shunt_voltage_sum_alert_limit(const ina3221_t *dev, if (status < 0) { return status; } - return INA3221_OK; + return 0; } int ina3221_get_shunt_voltage_sum_alert_limit(const ina3221_t *dev, @@ -480,12 +398,11 @@ int ina3221_get_shunt_voltage_sum_alert_limit(const ina3221_t *dev, { uint16_t reg_val; int status = _read_reg(dev, INA3221_REG_SHUNT_VOLTAGE_SUM_LIMIT, ®_val); - if (status < 0) { return status; } *out_uv = sum_reg_val_to_shunt_voltage_uv(reg_val); - return INA3221_OK; + return 0; } int ina3221_set_power_valid_upper_limit(const ina3221_t *dev, int32_t in_mv) @@ -498,19 +415,18 @@ int ina3221_set_power_valid_upper_limit(const ina3221_t *dev, int32_t in_mv) if (status < 0) { return status; } - return INA3221_OK; + return 0; } int ina3221_get_power_valid_upper_limit(const ina3221_t *dev, int32_t *out_mv) { uint16_t reg_val; int status = _read_reg(dev, INA3221_REG_PV_UPPER_LIMIT, ®_val); - if (status < 0) { return status; } *out_mv = reg_val_to_bus_voltage_mv(reg_val); - return INA3221_OK; + return 0; } int ina3221_set_power_valid_lower_limit(const ina3221_t *dev, int32_t in_mv) @@ -523,31 +439,29 @@ int ina3221_set_power_valid_lower_limit(const ina3221_t *dev, int32_t in_mv) if (status < 0) { return status; } - return INA3221_OK; + return 0; } int ina3221_get_power_valid_lower_limit(const ina3221_t *dev, int32_t *out_mv) { uint16_t reg_val; int status = _read_reg(dev, INA3221_REG_PV_LOWER_LIMIT, ®_val); - if (status < 0) { return status; } *out_mv = reg_val_to_bus_voltage_mv(reg_val); - return INA3221_OK; + return 0; } int ina3221_read_flags(const ina3221_t *dev, uint16_t *flags) { uint16_t reg_val; int status = _read_reg(dev, INA3221_REG_MASK_ENABLE, ®_val); - if (status < 0) { return status; } *flags = reg_val & INA3221_FLAGS_MASK; - return INA3221_OK; + return 0; } int ina3221_read_shunt_sum_uv(const ina3221_t *dev, int32_t *out_uv, @@ -555,132 +469,99 @@ int ina3221_read_shunt_sum_uv(const ina3221_t *dev, int32_t *out_uv, { uint16_t reg_val; int status = _read_reg(dev, INA3221_REG_SHUNT_VOLTAGE_SUM, ®_val); - if (status < 0) { return status; } *out_uv = sum_reg_val_to_shunt_voltage_uv(reg_val); if (flags) { - status = _read_reg(dev, INA3221_REG_MASK_ENABLE, flags); - if (status < 0) { - *flags = 0; - DEBUG("ina3221_read_shunt_sum_uv: Reading flags failed\n"); - } - else { - *flags &= INA3221_FLAGS_MASK; - } + *flags = 0; + _read_reg(dev, INA3221_REG_MASK_ENABLE, flags); } - return INA3221_OK; + return 0; } -int ina3221_read_shunt_uv(const ina3221_t *dev, ina3221_channel_t ch, - int32_t *out_uv, uint16_t *flags) +ina3221_ch_t ina3221_read_shunt_uv(const ina3221_t *dev, + int32_t out_uv[INA3221_NUM_CH], + uint16_t *flags) { uint16_t reg_val; - int status = INA3221_OK; - int i, j; - - for (i = 0, j = 0; i < INA3221_NUM_CH; i++) { - if (ch & (1 << i)) { - status = _read_reg(dev, _chi[i].chi_reg_shunt, ®_val); - if (status < 0) { - break; - } - out_uv[j++] = reg_val_to_shunt_voltage_uv(reg_val); - } - } - if (j && flags) { - status = _read_reg(dev, INA3221_REG_MASK_ENABLE, flags); - if (status < 0) { - *flags = 0; - DEBUG("ina3221_read_shunt_uv: Reading flags failed\n"); - } - else { - *flags &= INA3221_FLAGS_MASK; - } - } - return j ? j : status; -} - -int ina3221_read_bus_mv(const ina3221_t *dev, ina3221_channel_t ch, - int16_t *out_mv, uint16_t *flags) -{ - uint16_t reg_val; - int status = INA3221_OK; - int i, j = 0; - - for (i = 0; i < INA3221_NUM_CH; i++) { - if (ch & (1 << i)) { - status = _read_reg(dev, _chi[i].chi_reg_bus, ®_val); - if (status < 0) { - break; - } - out_mv[j++] = reg_val_to_bus_voltage_mv(reg_val); - } - } - if (j && flags) { - status = _read_reg(dev, INA3221_REG_MASK_ENABLE, flags); - if (status < 0) { - *flags = 0; - DEBUG("ina3221_read_bus_mv: Reading flags failed\n"); - } - else { - *flags &= INA3221_FLAGS_MASK; - } - } - return j ? j : status; -} - -int ina3221_calculate_current_ua(const ina3221_t *dev, ina3221_channel_t ch, - int32_t *in_uv, int32_t *out_ua) -{ - int i, j = 0; - - for (i = 0; i < INA3221_NUM_CH; i++) { - if (ch & (1 << i)) { - out_ua[j] = in_uv[j] * 1000 / dev->params.rshunt_mohm[i]; - j++; - } - } - return j; -} - -int ina3221_calculate_power_uw(int16_t *in_mv, int32_t *in_ua, uint8_t num, - int32_t *out_uw) -{ - if (num > INA3221_NUM_CH) { - return -ERANGE; - } - int i; - for (i = 0; i < num; i++) { - /* max 26V bus voltage */ - /* (2^31)-1 resolution; 2.147483647 Watt in Nanowatt resolutiona */ - /* 2.147483647 / 26000 = 82595.525 */ - if (in_ua[i] < (82596 - 500)) { - out_uw[i] = (in_ua[i] * in_mv[i] + 500) / 1000; - } - else { - out_uw[i] = (in_ua[i] + 500) / 1000 * in_mv[i]; - } - } - return i; -} - -void ina3221_ch_align(ina3221_channel_t ch, const void *in_res, void *out_res, - size_t res_val_size) -{ - uint8_t *in = (uint8_t *)in_res; - uint8_t tmp_out[INA3221_NUM_CH][res_val_size]; - int j = 0; - + ina3221_ch_t ch = ina3221_config_get_enabled_channels(dev->params.config); for (int i = 0; i < INA3221_NUM_CH; i++) { - if (ch & (1 << i)) { - memcpy(&tmp_out[i][0], in + j * res_val_size, res_val_size); - j++; - } - else { - memset(&tmp_out[i][0], 0, res_val_size); + out_uv[i] = 0; + if (ch & (1U << i)) { + if (_read_reg(dev, INA3221_REG_CH_SHUNT_VOLTAGE(i), ®_val)) { + ch &= ~(1U << i); + } + else { + out_uv[i] = reg_val_to_shunt_voltage_uv(reg_val); + } + } + } + if (flags) { + *flags = 0; + _read_reg(dev, INA3221_REG_MASK_ENABLE, flags); + } + return ch; +} + +ina3221_ch_t ina3221_read_bus_mv(const ina3221_t *dev, + int16_t out_mv[INA3221_NUM_CH], + uint16_t *flags) +{ + uint16_t reg_val; + ina3221_ch_t ch = ina3221_config_get_enabled_channels(dev->params.config); + for (int i = 0; i < INA3221_NUM_CH; i++) { + out_mv[i] = 0; + if (ch & (1U << i)) { + if (_read_reg(dev, INA3221_REG_CH_BUS_VOLTAGE(i), ®_val)) { + ch &= ~(1U << i); + } + else { + out_mv[i] = reg_val_to_bus_voltage_mv(reg_val); + } + } + } + if (flags) { + *flags = 0; + _read_reg(dev, INA3221_REG_MASK_ENABLE, flags); + } + return ch; +} + +void ina3221_calculate_current_ua(ina3221_ch_t ch, + const uint16_t in_mohm[INA3221_NUM_CH], + const int32_t in_uv[INA3221_NUM_CH], + int32_t out_ua[INA3221_NUM_CH]) +{ + for (int i = 0; i < INA3221_NUM_CH; i++) { + if (ch & (1U << i)) { + out_ua[i] = in_uv[i] * 1000 / in_mohm[i]; + } + else { + out_ua[i] = 0; + } + } +} + +void ina3221_calculate_power_uw(ina3221_ch_t ch, + const int16_t in_mv[INA3221_NUM_CH], + const int32_t in_ua[INA3221_NUM_CH], + int32_t out_uw[INA3221_NUM_CH]) +{ + for (int i = 0; i < INA3221_NUM_CH; i++) { + if (ch & (1U << i)) { + /* max 26V bus voltage */ + /* (2^31)-1 resolution; 2.147483647 Watt in Nanowatt resolution */ + /* 2.147483647 / 26000 = 82595.525 */ + if (in_ua[i] < (82596 - 500)) { + out_uw[i] = (in_ua[i] * in_mv[i] + 500) / 1000; + } + else { + out_uw[i] = (in_ua[i] + 500) / 1000 * in_mv[i]; + } + } + else { + out_uw[i] = 0; } } - memcpy(out_res, tmp_out, sizeof(tmp_out)); } diff --git a/drivers/include/ina3221.h b/drivers/include/ina3221.h index 8ae2e1cf40..f1b1026eb8 100644 --- a/drivers/include/ina3221.h +++ b/drivers/include/ina3221.h @@ -11,13 +11,13 @@ * @ingroup drivers_sensors * @ingroup drivers_saul * @brief Device driver for Texas Instruments INA3221 - * three-channel ,high-side current and bus voltage + * three-channel, high-side current and bus voltage * monitor * @{ * * @file * @brief Device driver interface for Texas Instruments INA3221 - * three-channel ,high-side current and bus voltage + * three-channel, high-side current and bus voltage * monitor. * * The alert pins WRN, CRT, TC, PV are open drain @@ -25,9 +25,9 @@ * internal or external pull-ups. They pull low, if * the alert condition becomes true. If they become * pulled low, the configured input pins in - * @see ina3221_params_t will read a low flank and + * @ref ina3221_params_t will read a low flank and * the related interrupt callback will be executed, - * if configured with @see ina3221_enable_alert. + * if configured with @ref ina3221_enable_alert. * WRN condition: * Any channel´s measured shunt * voltage drop was higher than the configured value in @@ -43,20 +43,26 @@ * channels are using the same shunt resistance value! * TC condition: * After a 1.2-V level is detected on channel 1, if the - * INA3221 does not detecta 1.2-V value or greater on + * INA3221 does not detect a 1.2-V value or greater on * the bus voltage measurement following four complete * cycles of all three channels, the timing control - * (TC)alert pin pulls low. + * TC alert pin pulls low. * PV condition: * If any channel´s measured bus voltage was not within * the configured values in INA3221_REG_PV_LOWER_LIMIT * and INA3221_REG_PV_UPPER_LIMIT, the PV pin is pulled * low. * - * For all enabled channels (1 <= i <= INA3221_NUM_CH), - * the time to complete a full measurement cycle is: + * For the number of enabled channels @f$NCH@f$, + * number of samples @f$NS@f$, + * bus voltage conversion time @f$BCT@f$, and + * shunt voltage conversion time @f$SCT@f$, + * the time to complete a full measurement cycle + * can be calculated with: + * @f$ NCH \times NS \times (BCT + SCT) @f$. * - * num_samples * (shunt_conv_time_ch_i + bus_voltage_conv_time_ch_i) + * @see Datasheet: + * https://www.ti.com/lit/ds/symlink/ina3221.pdf * * @author Fabian Hüßler */ @@ -64,8 +70,12 @@ #ifndef INA3221_H #define INA3221_H +#include +#include #include +#include +#include "kernel_defines.h" #include "periph/gpio.h" #include "periph/i2c.h" @@ -73,9 +83,14 @@ extern "C" { #endif -#define INA3221_NUM_CH (3) /**< Number of channels */ - -#define INA3221_NUM_ALERTS (4) /**< Number of alerts */ +/** + * @brief Number of channels + */ +#define INA3221_NUM_CH (3) +/** + * @brief Number of alerts + */ +#define INA3221_NUM_ALERTS (4) /** * @brief INA3221 alert callback for alert pins @@ -83,18 +98,6 @@ extern "C" { */ typedef void (*ina3221_alert_cb_t)(void *arg); -/** - * @brief Return codes - */ -typedef enum ina3221_ret_val { - INA3221_OK, /**< Everything is fine */ - INA3221_I2C_ERROR, /**< I2C bus acquirenment failed */ - INA3221_BAD_MANUF_ID, /**< Read device manufacturer ID failed */ - INA3221_BAD_DIE_ID, /**< Read device DIE ID failed */ - INA3221_RESET_FAILED, /**< Device reset failed */ - INA3221_CONFIG_FAILED /**< Device configuration failed */ -} ina3221_ret_val_t; - /** * @brief I2C device addresses */ @@ -103,15 +106,15 @@ typedef enum ina3221_dev_addr { INA3221_ADDR_01 = 0x41, /**< A0 connected to VS */ INA3221_ADDR_10 = 0x42, /**< A0 connected to SDA */ INA3221_ADDR_11 = 0x43, /**< A0 connected to SCL */ -} ina3221_dav_addr_t; +} ina3221_dev_addr_t; /** * @brief Channel flags */ typedef enum ina3221_channel { - INA3221_CH1 = (1 << 0), /**< Channel 1 */ - INA3221_CH2 = (1 << 1), /**< Channel 2 */ - INA3221_CH3 = (1 << 2) /**< Channel 3 */ + INA3221_CH1 = (1U << 0), /**< Channel 1 */ + INA3221_CH2 = (1U << 1), /**< Channel 2 */ + INA3221_CH3 = (1U << 2) /**< Channel 3 */ } ina3221_channel_t; /** @@ -132,12 +135,15 @@ typedef enum ina3221_mode { INA3221_MODE_TRIGGER_SHUNT_ONLY = 0x0001, /**< Trigger shunt voltage measurement only */ INA3221_MODE_TRIGGER_BUS_ONLY = 0x0002, /**< Trigger bus voltage measurement only */ INA3221_MODE_TRIGGER_SHUNT_BUS = 0x0003, /**< Trigger shunt and bus voltage measurement */ - INA3221_MODE_POWER_DOWN_ = 0x0004, /**< Also power down (see datasheet)*/ - INA3221_MODE_CONTINUOUS_SHUNT_ONLY = 0x0005, /**< Continuous shunt voltage measurement only*/ - INA3221_MODE_CONTINUOUS_BUS_ONLY = 0x0006, /**< Continuous bus voltage measurement only*/ + INA3221_MODE_POWER_DOWN_ = 0x0004, /**< Also power down (see datasheet) */ + INA3221_MODE_CONTINUOUS_SHUNT_ONLY = 0x0005, /**< Continuous shunt voltage measurement only */ + INA3221_MODE_CONTINUOUS_BUS_ONLY = 0x0006, /**< Continuous bus voltage measurement only */ INA3221_MODE_CONTINUOUS_SHUNT_BUS = 0x0007 /**< Continuous shunt and bus voltage measurement */ } ina3221_mode_t; -#define INA3221_MODE_MASK (0x0007) /**< Device operation mode bit mask */ +/** + * @brief Device operation mode bit mask + */ +#define INA3221_MODE_MASK (0x0007) /** * @brief ADC shunt voltage conversion times @@ -152,7 +158,10 @@ typedef enum ina3221_conv_time_shunt_adc { INA3221_CONV_TIME_SADC_4156US = 0x0030, /**< 4156 us */ INA3221_CONV_TIME_SADC_8244US = 0x0038 /**< 8244 us */ } ina3221_conv_time_shunt_adc_t; -#define INA3221_CONV_TIME_SADC_MASK (0x0038) /**< ADC shunt voltage conversion times bit mask*/ +/** + * @brief ADC shunt voltage conversion times bit mask + */ +#define INA3221_CONV_TIME_SADC_MASK (0x0038) /** * @brief ADC bus voltage conversion times @@ -167,7 +176,10 @@ typedef enum ina3221_conv_time_bus_adc { INA3221_CONV_TIME_BADC_4156US = 0x0180, /**< 4156 us */ INA3221_CONV_TIME_BADC_8244US = 0x01C0 /**< 8244 us */ } ina3221_conv_time_bus_adc_t; -#define INA3221_CONV_TIME_BADC_MASK (0x01C0) /**< ADC bus voltage conversion times bit mask*/ +/** + * @brief ADC bus voltage conversion times bit mask + */ +#define INA3221_CONV_TIME_BADC_MASK (0x01C0) /** * @brief Number of samples to calculate average shunt/bus voltage value @@ -182,7 +194,10 @@ typedef enum ina3221_num_samples { INA3221_NUM_SAMPLES_512 = 0x0C00, /**< 512 */ INA3221_NUM_SAMPLES_1024 = 0x0E00 /**< 1024 */ } ina3221_num_samples_t; -#define INA3221_NUM_SAMPLES_MASK (0x0E00) /**< Number of samples to calculate average shunt/bus voltage value bit mask */ +/** + * @brief Number of samples to calculate average shunt/bus voltage value bit mask + */ +#define INA3221_NUM_SAMPLES_MASK (0x0E00) /** * @brief Enable channel flags @@ -192,17 +207,12 @@ typedef enum ina3221_enable_ch { INA3221_ENABLE_CH2 = 0x2000, /**< Enable channel 2 */ INA3221_ENABLE_CH3 = 0x1000 /**< Enable channel 3 */ } ina3221_enable_ch_t; +/** + * @brief Enable channel bit mask + */ #define INA3221_ENABLE_CH_MASK (INA3221_ENABLE_CH1 \ | INA3221_ENABLE_CH2 \ - | INA3221_ENABLE_CH3) /**< Enable channel bit mask */ - -/** - * @brief Channel state enabled/disabled - */ -typedef enum ina3221_channel_state { - INA3221_CH_DISABLE, /**< Channel disabled */ - INA3221_CH_ENABLE /**< Channel enabled */ -} ina3221_channel_state_t; + | INA3221_ENABLE_CH3) /** * @brief Enable shunt voltage sum calculation channel flags @@ -212,9 +222,12 @@ typedef enum ina3221_enable_sum_ch { INA3221_ENABLE_SUM_CH2 = 0x2000, /**< Enable sum channel 2 */ INA3221_ENABLE_SUM_CH3 = 0x1000 /**< Enable sum channel 3 */ } ina3221_enable_sum_ch_t; +/** + * @brief Enable shunt voltage sum calculation channel bit mask + */ #define INA3221_ENABLE_SUM_CH_MASK (INA3221_ENABLE_SUM_CH1 \ | INA3221_ENABLE_SUM_CH2 \ - | INA3221_ENABLE_SUM_CH3) /**< Enable shunt voltage sum calculation channel bit mask */ + | INA3221_ENABLE_SUM_CH3) /** * @brief Enable latch flags @@ -223,8 +236,17 @@ typedef enum ina3221_enable_latch { INA3221_ENABLE_WARN_LATCH = 0x0800, /**< Enable warning alert latch */ INA3221_ENABLE_CRIT_LATCH = 0x0400 /**< Enable critical alert latch */ } ina3221_enable_latch_t; +/** + * @brief Enable latch bit mask + */ #define INA3221_ENABLE_LATCH_MASK (INA3221_ENABLE_WARN_LATCH \ - | INA3221_ENABLE_CRIT_LATCH) /**< Enable latch bit mask */ + | INA3221_ENABLE_CRIT_LATCH) + +/** + * @brief Flags @ref ina3221_channel_t + */ +typedef unsigned ina3221_ch_t; + /** * @brief INA3221 device parameters */ @@ -233,10 +255,10 @@ typedef struct { uint8_t addr; /**< I2C address */ union { struct { - gpio_t pin_warn; /**< Warning alert pin, becomes configured as input*/ - gpio_t pin_crit; /**< Critical alert pin, becomes configured as input*/ - gpio_t pin_tc; /**< Timing control alert pin, becomes configured as input*/ - gpio_t pin_pv; /**< Power valid alert pin, becomes configured as input*/ + gpio_t pin_warn; /**< Warning alert pin, becomes configured as input */ + gpio_t pin_crit; /**< Critical alert pin, becomes configured as input */ + gpio_t pin_tc; /**< Timing control alert pin, becomes configured as input */ + gpio_t pin_pv; /**< Power valid alert pin, becomes configured as input */ } pins; /**< Struct of alert pins */ struct { gpio_t alert_pins[INA3221_NUM_ALERTS]; /**< Array to access alert pins via an index */ @@ -249,7 +271,7 @@ typedef struct { */ uint8_t gpio_config; /**< Configure pull up resistors for gpio pins */ uint16_t config; /**< Configuration */ - uint16_t rshunt_mohm[INA3221_NUM_CH]; /**< Shunt resistances im mOhm for each channel */ + uint16_t rshunt_mohm[INA3221_NUM_CH]; /**< Shunt resistances in mOhm for each channel */ } ina3221_params_t; /* ( INA3221_ENABLE_CH_1 @@ -261,7 +283,7 @@ typedef struct { | INA3221_MODE_CONTINUOUS_SHUNT_BUS ) */ #define INA3221_DEFCONFIG (0x7127) /**< Default configuration register value */ -#define INA3221_RESET (0x8000) /**< Reset configuration register value*/ +#define INA3221_RESET (0x8000) /**< Reset configuration register value */ #define INA3221_FLAG_CRIT_ALERT_CH1 (0x0200) /**< Critical alert channel 1 flag */ #define INA3221_FLAG_CRIT_ALERT_CH2 (0x0100) /**< Critical alert channel 2 flag */ @@ -279,6 +301,9 @@ typedef struct { #define INA3221_FLAG_CONV_READY (0x0001) /**< Conversion ready flag */ +/** + * @brief Flags bit mask + */ #define INA3221_FLAGS_MASK (INA3221_FLAG_CRIT_ALERT_CH1 \ | INA3221_FLAG_CRIT_ALERT_CH2 \ | INA3221_FLAG_CRIT_ALERT_CH3 \ @@ -288,20 +313,20 @@ typedef struct { | INA3221_FLAG_WARN_ALERT_CH3 \ | INA3221_FLAG_POWER_VALID \ | INA3221_FLAG_TIMING_CONTROL \ - | INA3221_FLAG_CONV_READY) /**< Flags bit mask*/ + | INA3221_FLAG_CONV_READY) /** * @brief INA3221 device handle struct */ typedef struct { - ina3221_params_t params; /**< Device parameters */ -#if defined(MODULE_INA3221_ALERTS) || defined(DOXYGEN) + ina3221_params_t params; /**< Device parameters */ +#if IS_USED(MODULE_INA3221_ALERTS) || defined(DOXYGEN) union { struct { ina3221_alert_cb_t warn_cb; /**< Warning alert callback: executed when WRN is pulled low */ ina3221_alert_cb_t crit_cb; /**< Critical alert callback: executed when CRT is pulled low */ ina3221_alert_cb_t tc_cb; /**< Timing control alert callback: executed when TC is pulled low */ - ina3221_alert_cb_t pv_cb; /**< Power Valid alert callback: executed when PV is pulled low */ + ina3221_alert_cb_t pv_cb; /**< Power Valid alert callback: executed when PV is pulled low */ }; struct { ina3221_alert_cb_t alert_callbacks[INA3221_NUM_ALERTS]; /**< Array to access alert callbacks via an index */ @@ -324,11 +349,11 @@ typedef struct { /** * @brief Reset device, i.e. apply default configuration * - * @param[in,out] dev Device handle + * @param[in,out] dev Device handle * - * @return INA3221_OK, on success - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed - * @return -INA3221_RESET_FAILED, if device could not be reset + * @return 0, on success + * @return -EIO, if I2C bus acquirement failed + * @return -ENODEV, if device could not be reset * @return @see i2c_read_regs * @return @see i2c_write_regs */ @@ -337,320 +362,365 @@ int ina3221_reset(ina3221_t *dev); /** * @brief Initialize device * - * @param[out] dev Device handle - * @param[in] params Device parameters + * @param[out] dev Device handle + * @param[in] params Device parameters * - * @return INA3221_OK, on success - * @return -EINVAL, if NULL pointer was passed - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed - * @return -INA3221_BAD_MANUF_ID, if manufacturer ID does not match - * @return -INA3221_DIE_ID, if DIE ID does not match - * @return -INA3221_RESET_FAILED, if reset failed - * @return -INA3221_CONFIG_FAILED, if configuration could not be applied + * @return 0, on success + * @return -EFAULT, if NULL pointer was passed + * @return -EIO, if I2C bus acquirement failed + * @return -ENXIO, if manufacturer ID or DIE ID does not match + * @return -ENODEV, if reset failed + * @return -EINVAL, if configuration could not be applied * @return @see i2c_read_regs * @return @see i2c_write_regs */ int ina3221_init(ina3221_t *dev, const ina3221_params_t *params); -#if defined(MODULE_INA3221_ALERTS) || defined(DOXYGEN) +#if IS_USED(MODULE_INA3221_ALERTS) || defined(DOXYGEN) /** - * @brief Enable alert callback and argument for alert @p alert + * @brief Enable alert and set callback and argument for alert @p alert * - * @param[in,out] dev Device handle - * @param[in] alert Alert index - * @param[in] cb Alert callback - * @param[in] arg Alert callback argument + * @param[in,out] dev Device handle + * @param[in] alert Alert index + * @param[in] cb Alert callback + * @param[in] arg Alert callback argument * - * @return INA3221_OK, on success - * @return -ERANGE, if @p alert was out of bounds - * @return -ENUTSUP, if alert pin was initialized with GPIO_UNDEF + * @return 0, on success + * @return -ERANGE, if @p alert was out of bounds + * @return -ENUTSUP, if alert pin was initialized with GPIO_UNDEF */ -int _ina3221_enable_alert(ina3221_t *dev, ina3221_alert_t alert, - ina3221_alert_cb_t cb, void *arg); +int ina3221_enable_alert(ina3221_t *dev, ina3221_alert_t alert, + ina3221_alert_cb_t cb, void *arg); /** - * @brief Wrapper around @see _ina3221_enable_alert, to - * enable warning alert + * @brief Wrapper around @ref ina3221_enable_alert, + * to enable warning alert * - * @param[in,out] dev Device handle - * @param[in] cb Alert callback - * @param[in] arg Alert callback argument + * @param[in,out] dev Device handle + * @param[in] cb Alert callback + * @param[in] arg Alert callback argument * - * @return @see _ina3221_enable_alert + * @return @see ina3221_enable_alert */ static inline int ina3221_enable_warning_alert(ina3221_t *dev, - ina3221_alert_cb_t cb, void *arg) + ina3221_alert_cb_t cb, + void *arg) { - return _ina3221_enable_alert(dev, INA3221_ALERT_WRN, cb, arg); + return ina3221_enable_alert(dev, INA3221_ALERT_WRN, cb, arg); } /** - * @brief Wrapper around @see _ina3221_enable_alert, to - * enable critical alert + * @brief Wrapper around @ref ina3221_enable_alert, + * to enable critical alert * - * @param[in,out] dev Device handle - * @param[in] cb Alert callback - * @param[in] arg Alert callback argument + * @param[in,out] dev Device handle + * @param[in] cb Alert callback + * @param[in] arg Alert callback argument * - * @return @see _ina3221_enable_alert + * @return @see ina3221_enable_alert */ static inline int ina3221_enable_critical_alert(ina3221_t *dev, ina3221_alert_cb_t cb, void *arg) { - return _ina3221_enable_alert(dev, INA3221_ALERT_CRT, cb, arg); + return ina3221_enable_alert(dev, INA3221_ALERT_CRT, cb, arg); } /** - * @brief Wrapper around @see _ina3221_enable_alert, to - * enable timing control alert + * @brief Wrapper around @ref ina3221_enable_alert, + * to enable timing control alert * - * @param[in,out] dev Device handle - * @param[in] cb Alert callback - * @param[in] arg Alert callback argument + * @param[in,out] dev Device handle + * @param[in] cb Alert callback + * @param[in] arg Alert callback argument * - * @return @see _ina3221_enable_alert + * @return @see ina3221_enable_alert */ static inline int ina3221_enable_timing_control_alert(ina3221_t *dev, ina3221_alert_cb_t cb, void *arg) { - return _ina3221_enable_alert(dev, INA3221_ALERT_TC, cb, arg); + return ina3221_enable_alert(dev, INA3221_ALERT_TC, cb, arg); } /** - * @brief Wrapper around @see _ina3221_enable_alert, to - * enable power valid alert + * @brief Wrapper around @ref ina3221_enable_alert, + * to enable power valid alert * - * @param[in,out] dev Device handle - * @param[in] cb Alert callback - * @param[in] arg Alert callback argument + * @param[in,out] dev Device handle + * @param[in] cb Alert callback + * @param[in] arg Alert callback argument * - * @return @see _ina3221_enable_alert + * @return @see ina3221_enable_alert */ static inline int ina3221_enable_power_valid_alert(ina3221_t *dev, ina3221_alert_cb_t cb, void *arg) { - return _ina3221_enable_alert(dev, INA3221_ALERT_PV, cb, arg); + return ina3221_enable_alert(dev, INA3221_ALERT_PV, cb, arg); } /** - * @brief Disable alert callback and argument for alert @p alert + * @brief Disable alert @p alert * - * @param[in,out] dev Device handle - * @param[in] alert Alert index + * @param[in,out] dev Device handle + * @param[in] alert Alert index * - * @return INA3221_OK, on success - * @return -ERANGE, if @p alert was out of bounds - * @return -ENUTSUP, if alert pin was initialized with GPIO_UNDEF + * @return 0, on success + * @return -ERANGE, if @p alert was out of bounds + * @return -ENUTSUP, if alert pin was initialized with GPIO_UNDEF */ -int _ina3221_disable_alert(ina3221_t *dev, ina3221_alert_t alert); +int ina3221_disable_alert(ina3221_t *dev, ina3221_alert_t alert); /** - * @brief Wrapper around @see _ina3221_disable_alert, to - * disable warning alert + * @brief Wrapper around @ref ina3221_disable_alert, + * to disable warning alert * - * @param[in,out] dev Device handle + * @param[in,out] dev Device handle * - * @return @see _ina3221_disable_alert + * @return @see ina3221_disable_alert */ static inline int ina3221_disable_warning_alert(ina3221_t *dev) { - return _ina3221_disable_alert(dev, INA3221_ALERT_WRN); + return ina3221_disable_alert(dev, INA3221_ALERT_WRN); } /** - * @brief Wrapper around @see _ina3221_disable_alert, to - * disable critical alert + * @brief Wrapper around @ref ina3221_disable_alert, + * to disable critical alert * - * @param[in,out] dev Device handle + * @param[in,out] dev Device handle * - * @return @see _ina3221_disable_alert + * @return @see ina3221_disable_alert */ static inline int ina3221_disable_critical_alert(ina3221_t *dev) { - return _ina3221_disable_alert(dev, INA3221_ALERT_CRT); + return ina3221_disable_alert(dev, INA3221_ALERT_CRT); } /** - * @brief Wrapper around @see _ina3221_disable_alert, to - * disable timing control alert + * @brief Wrapper around @ref ina3221_disable_alert, + * to disable timing control alert * - * @param[in,out] dev Device handle + * @param[in,out] dev Device handle * - * @return @see _ina3221_disable_alert + * @return @see ina3221_disable_alert */ static inline int ina3221_disable_timing_control_alert(ina3221_t *dev) { - return _ina3221_disable_alert(dev, INA3221_ALERT_TC); + return ina3221_disable_alert(dev, INA3221_ALERT_TC); } /** - * @brief Wrapper around @see _ina3221_disable_alert, to - * disable power valid alert + * @brief Wrapper around @ref ina3221_disable_alert, + * to disable power valid alert * - * @param[in,out] dev Device handle + * @param[in,out] dev Device handle * - * @return @see _ina3221_disable_alert + * @return @see ina3221_disable_alert */ static inline int ina3221_disable_power_valid_alert(ina3221_t *dev) { - return _ina3221_disable_alert(dev, INA3221_ALERT_PV); + return ina3221_disable_alert(dev, INA3221_ALERT_PV); } #endif /* MODULE_INA3221_ALERTS */ /** - * @brief Write configuration register value to configuration register + * @brief Get enabled measurement channels from configuration value * - * @param[in,out] dev Device handle - * @param[in] cfg Configuration register value in host byte order + * @param[in] cfg Configuration value * - * @return INA3221_OK, on success - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed - * @return @see i2c_write_regs + * @return Channel flags @ref ina3221_channel_t */ -int _ina3221_set_config(ina3221_t *dev, uint16_t cfg); +static inline ina3221_ch_t ina3221_config_get_enabled_channels(uint16_t cfg) +{ + return ((cfg & INA3221_ENABLE_CH1) ? INA3221_CH1 : 0) | + ((cfg & INA3221_ENABLE_CH2) ? INA3221_CH2 : 0) | + ((cfg & INA3221_ENABLE_CH3) ? INA3221_CH3 : 0); +} /** - * @brief Wrapper around @see _ina3221_set_config + * @brief Enable measurement channels in configuration value * - * @param[in, out] dev Device handle - * @param[in] chs Channel enable flags @see ina3221_enable_ch_t - * @param[in] ns Number of samples - * @param[in] ctbadc Conversion time for bus voltage ADC - * @param[in] ctsadc Conversion time for shunt voltage ADC - * @param[in] mode Device operation mode - * - * @return @see _ina3221_set_config + * @param[out] cfg Configuration value + * @param[in] ch Channel flags @ref ina3221_channel_t */ -static inline int ina3221_set_config(ina3221_t *dev, - uint16_t chs, - ina3221_num_samples_t ns, - ina3221_conv_time_bus_adc_t ctbadc, - ina3221_conv_time_shunt_adc_t ctsadc, - ina3221_mode_t mode) +static inline void ina3221_config_set_enabled_channels(uint16_t *cfg, ina3221_ch_t ch) { - return _ina3221_set_config(dev, chs | ns | ctbadc | ctsadc | mode); + assert(cfg); + uint16_t u16 = ((ch & INA3221_CH1) ? INA3221_ENABLE_CH1 : 0) | + ((ch & INA3221_CH2) ? INA3221_ENABLE_CH2 : 0) | + ((ch & INA3221_CH3) ? INA3221_ENABLE_CH3 : 0); + *cfg &= ~INA3221_ENABLE_CH_MASK; + *cfg |= (u16 & INA3221_ENABLE_CH_MASK); } +/** + * @brief Get number of samples from configuration value + * + * @param[in] cfg Configuration value + * + * @return Number of samples + */ +static inline ina3221_num_samples_t ina3221_config_get_num_samples(uint16_t cfg) +{ + return (ina3221_num_samples_t)(cfg & INA3221_NUM_SAMPLES_MASK); +} + +/** + * @brief Set number of samples in configuration value + * + * @param[out] cfg Configuration value + * @param[in] ns Number of samples + */ +static inline void ina3221_config_set_num_samples(uint16_t *cfg, + ina3221_num_samples_t ns) +{ + assert(cfg); + uint16_t u16 = (uint16_t)ns; + *cfg &= ~INA3221_NUM_SAMPLES_MASK; + *cfg |= (u16 & INA3221_NUM_SAMPLES_MASK); +} + +/** + * @brief Get bus voltage conversion time from configuration value + * + * @param[in] cfg Configuration value + * + * @return Bus conversion time + */ +static inline ina3221_conv_time_bus_adc_t ina3221_config_get_conv_time_bus(uint16_t cfg) +{ + return (ina3221_conv_time_bus_adc_t)(cfg & INA3221_CONV_TIME_BADC_MASK); +} + +/** + * @brief Set bus voltage conversion time in configuration value + * + * @param[out] cfg Configuration value + * @param[in] bus Bus conversion time + */ +static inline void ina3221_config_set_conv_time_bus(uint16_t *cfg, + ina3221_conv_time_bus_adc_t bus) +{ + assert(cfg); + uint16_t u16 = (uint16_t)bus; + *cfg &= ~INA3221_CONV_TIME_BADC_MASK; + *cfg |= (u16 & INA3221_CONV_TIME_BADC_MASK); +} + +/** + * @brief Get shunt voltage conversion time from configuration value + * + * @param[in] cfg Configuration value + * + * @return Shunt conversion time + */ +static inline ina3221_conv_time_shunt_adc_t ina3221_config_get_conv_time_shunt(uint16_t cfg) +{ + return (ina3221_conv_time_shunt_adc_t)(cfg & INA3221_CONV_TIME_SADC_MASK); +} + +/** + * @brief Set shunt voltage conversion time in configuration value + * + * @param[out] cfg Configuration value + * @param[in] shunt Shunt conversion time + */ +static inline void ina3221_config_set_conv_time_shunt(uint16_t *cfg, + ina3221_conv_time_shunt_adc_t shunt) +{ + assert(cfg); + uint16_t u16 = (uint16_t)shunt; + *cfg &= ~INA3221_CONV_TIME_SADC_MASK; + *cfg |= (u16 & INA3221_CONV_TIME_SADC_MASK); +} + +/** + * @brief Get operation mode from configuration value + * + * @param[in] cfg Configuration value + * + * @return Operation mode + */ +static inline ina3221_mode_t ina3221_config_get_mode(uint16_t cfg) +{ + return (ina3221_mode_t)(cfg & INA3221_MODE_MASK); +} + +/** + * @brief Set operation mode in configuration value + * + * @param[out] cfg Configuration value + * @param[in] mode Operation mode + */ +static inline void ina3221_config_set_mode(uint16_t *cfg, + ina3221_mode_t mode) +{ + assert(cfg); + uint16_t u16 = (uint16_t)mode; + *cfg &= ~INA3221_MODE_MASK; + *cfg |= (u16 & INA3221_MODE_MASK); +} + +/** + * @brief Write configuration register value to configuration register + * + * @param[in,out] dev Device handle + * @param[in] cfg Configuration register value + * + * @return 0, on success + * @return -EIO, if I2C bus acquirement failed + * @return @see i2c_write_regs + */ +int ina3221_set_config(ina3221_t *dev, uint16_t cfg); + /** * @brief Read currently saved configuration register value * - * @param[in] dev Device handle - * @param[out] cfg Pointer to configuration register output value in host byte order + * @param[in] dev Device handle + * @param[out] cfg Pointer to configuration register output value * - * @return INA3221_OK + * @return 0, on success + * @return -EIO, if I2C bus acquirement failed + * @return @see i2c_read_regs */ -int _ina3221_get_config(const ina3221_t *dev, uint16_t *cfg); - -/** - * @brief Wrapper around @see _ina3221_get_config - * - * @param[in] dev Device handle - * @param[out] chs Pointer to enabled channels variable @see ina3221_enable_ch_t - * @param[out] ns Pointer to number of samples variable - * @param[out] ctbadc Pointer to conversion time bus adc variable - * @param[out] ctsadc Pointer to conversion time shunt adc variable - * @param[out] mode Pointer to measurement mode variable - * - * @return @see _ina3221_get_config - */ -static inline int ina3221_get_config(const ina3221_t *dev, - uint16_t *chs, - ina3221_num_samples_t *ns, - ina3221_conv_time_bus_adc_t *ctbadc, - ina3221_conv_time_shunt_adc_t *ctsadc, - ina3221_mode_t *mode) -{ - uint16_t cfg = 0; - int ret = _ina3221_get_config(dev, &cfg); - - *chs = cfg & INA3221_ENABLE_CH_MASK; - *ns = (ina3221_num_samples_t)(cfg & INA3221_NUM_SAMPLES_MASK); - *ctbadc = (ina3221_conv_time_bus_adc_t)(cfg & INA3221_CONV_TIME_BADC_MASK); - *ctsadc = (ina3221_conv_time_shunt_adc_t)(cfg & INA3221_CONV_TIME_SADC_MASK); - *mode = (ina3221_mode_t)(cfg & INA3221_MODE_MASK); - return ret; -} +int ina3221_get_config(const ina3221_t *dev, uint16_t *cfg); /** * @brief Enable channels * - * @param[in,out] dev Device handle - * @param[in] ech Channel enable flags @see ina3221_enable_ch_t + * @param[in,out] dev Device handle + * @param[in] ch Channel flags @ref ina3221_channel_t * - * @return INA3221_OK, on success - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed + * @return 0, on success + * @return -EIO, if I2C bus acquirement failed * @return @see i2c_read_regs * @return @see i2c_write_regs */ -int _ina3221_set_enable_channel(ina3221_t *dev, uint16_t ech); - -/** - * @brief Wrapper around @see _ina3221_set_enable_channel - * - * @param[in, out] dev Device handle - * @param[in] ch1 Channel 1 state - * @param[in] ch2 Channel 2 state - * @param[in] ch3 Channel 3 state - * - * @return @see _ina3221_set_enable_channel - */ -static inline int ina3221_set_channel_state(ina3221_t *dev, - ina3221_channel_state_t ch1, - ina3221_channel_state_t ch2, - ina3221_channel_state_t ch3) -{ - return _ina3221_set_enable_channel(dev, - (ch1 ? INA3221_ENABLE_CH1 : 0) | - (ch2 ? INA3221_ENABLE_CH2 : 0) | - (ch3 ? INA3221_ENABLE_CH3 : 0)); -} +int ina3221_set_enable_channel(ina3221_t *dev, ina3221_ch_t ch); /** * @brief Read which channels are currently enabled * - * @param[in] dev Device handle - * @param[out] ech Pointer to enabled channels output variable @see ina3221_enable_ch_t - * - * @return Number of enabled channels + * @param[in] dev Device handle + * @param[out] ch Channel flags @ref ina3221_channel_t */ -int _ina3221_get_enable_channel(const ina3221_t *dev, uint16_t *ech); - -/** - * @brief Wrapper around _ina3221_get_enable_channel - * - * @param[in] dev Device handle - * @param[out] ch1 Pointer to channel 1 state variable - * @param[out] ch2 Pointer to channel 2 state variable - * @param[out] ch3 Pointer to channel 3 state variable - * - * @return @see _ina3221_get_enable_channel - */ -static inline int ina3221_get_channel_state(const ina3221_t *dev, - ina3221_channel_state_t *ch1, - ina3221_channel_state_t *ch2, - ina3221_channel_state_t *ch3) +static inline void ina3221_get_enable_channel(const ina3221_t *dev, + ina3221_ch_t *ch) { - uint16_t ech = 0; - int ret = _ina3221_get_enable_channel(dev, &ech); - - *ch1 = (ech & INA3221_ENABLE_CH1) ? INA3221_CH_ENABLE : INA3221_CH_DISABLE; - *ch2 = (ech & INA3221_ENABLE_CH2) ? INA3221_CH_ENABLE : INA3221_CH_DISABLE; - *ch3 = (ech & INA3221_ENABLE_CH3) ? INA3221_CH_ENABLE : INA3221_CH_DISABLE; - return ret; + *ch = ina3221_config_get_enabled_channels(dev->params.config); } /** * @brief Update number of samples and write to configuration register * - * @param[in, out] dev Device handle - * @param[in] ns Number of samples + * @param[in, out] dev Device handle + * @param[in] ns Number of samples * - * @return INA3221_OK, on success - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed + * @return 0, on success + * @return -EIO, if I2C bus acquirement failed * @return @see i2c_read_regs * @return @see i2c_write_regs */ @@ -659,21 +729,23 @@ int ina3221_set_num_samples(ina3221_t *dev, ina3221_num_samples_t ns); /** * @brief Read currently applied number of samples * - * @param[in] dev Device handle - * @param[out] ns Pointer to number of samples output variable - * - * @return INA3221_OK + * @param[in] dev Device handle + * @param[out] ns Pointer to number of samples output variable */ -int ina3221_get_num_samples(const ina3221_t *dev, ina3221_num_samples_t *ns); +static inline void ina3221_get_num_samples(const ina3221_t *dev, + ina3221_num_samples_t *ns) +{ + *ns = ina3221_config_get_num_samples(dev->params.config); +} /** * @brief Update conversion time of bus voltage ADC and write to configuration register * - * @param[in,out] dev Device handle - * @param[in] ctb Bus voltage conversion time + * @param[in,out] dev Device handle + * @param[in] ctb Bus voltage conversion time * - * @return INA3221_OK, on success - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed + * @return 0, on success + * @return -EIO, if I2C bus acquirement failed * @return @see i2c_read_regs * @return @see i2c_write_regs */ @@ -683,22 +755,23 @@ int ina3221_set_conv_time_bus_adc(ina3221_t *dev, /** * @brief Read currently applied bus voltage ADC conversion time * - * @param[in] dev Device handle - * @param[out] ctb Pointer to bus voltage ADC conversion time output variable - * - * @return INA3221_OK + * @param[in] dev Device handle + * @param[out] ctb Pointer to bus voltage ADC conversion time output variable */ -int ina3221_get_conv_time_bus_adc(const ina3221_t *dev, - ina3221_conv_time_bus_adc_t *ctb); +static inline void ina3221_get_conv_time_bus_adc(const ina3221_t *dev, + ina3221_conv_time_bus_adc_t *ctb) +{ + *ctb = ina3221_config_get_conv_time_bus(dev->params.config); +} /** * @brief Update conversion time of shunt voltage ADC and write to configuration register * - * @param[in,out] dev Device handle - * @param[in] cts Shunt voltage conversion time value + * @param[in,out] dev Device handle + * @param[in] cts Shunt voltage conversion time value * - * @return INA3221_OK, on success - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed + * @return 0, on success + * @return -EIO, if I2C bus acquirement failed * @return @see i2c_read_regs * @return @see i2c_write_regs */ @@ -708,22 +781,23 @@ int ina3221_set_conv_time_shunt_adc(ina3221_t *dev, /** * @brief Read currently applied shunt voltage ADC conversion time * - * @param[in] dev Device handle - * @param[out] cts Pointer to shunt voltage ADC conversion time output variable - * - * @return INA3221_OK + * @param[in] dev Device handle + * @param[out] cts Pointer to shunt voltage ADC conversion time output variable */ -int ina3221_get_conv_time_shunt_adc(const ina3221_t *dev, - ina3221_conv_time_shunt_adc_t *cts); +static inline void ina3221_get_conv_time_shunt_adc(const ina3221_t *dev, + ina3221_conv_time_shunt_adc_t *cts) +{ + *cts = ina3221_config_get_conv_time_shunt(dev->params.config); +} /** * @brief Update device operation mode * - * @param[in,out] dev Device handle - * @param[in] mode Operation mode value in host byte order + * @param[in,out] dev Device handle + * @param[in] mode Operation mode value * - * @return INA3221_OK, on success - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed + * @return 0, on success + * @return -EIO, if I2C bus acquirement failed * @return @see i2c_read_regs * @return @see i2c_write_regs */ @@ -732,191 +806,126 @@ int ina3221_set_mode(ina3221_t *dev, ina3221_mode_t mode); /** * @brief Read currently applied device operation mode * - * @param[in] dev Device handle - * @param[out] mode Pointer to device operation mode output variable - * - * @return INA3221_OK + * @param[in] dev Device handle + * @param[out] mode Pointer to device operation mode output variable */ -int ina3221_get_mode(const ina3221_t *dev, ina3221_mode_t *mode); +static inline void ina3221_get_mode(const ina3221_t *dev, ina3221_mode_t *mode) +{ + *mode = ina3221_config_get_mode(dev->params.config); +} /** * @brief Enable channels for shunt voltage sum calculation * - * @param[in] dev Device handle - * @param[in] esch Enable channel shunt voltage sum flags in host byte order @see ina3221_enable_sum_ch_t + * @param[in] dev Device handle + * @param[in] ch Channel flags @ref ina3221_channel_t * - * @return INA3221_OK, on success - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed + * @note The channel must also have been enabled with + * @ref ina3221_set_enable_channel + * + * @return 0, on success + * @return -EIO, if I2C bus acquirement failed * @return @see i2c_read_regs * @return @see i2c_write_regs */ -int _ina3221_set_enable_sum_channel(const ina3221_t *dev, - uint16_t esch); - -/** - * @brief Wrapper around @see _ina3221_set_enable_sum_channel - * - * @param[in] dev Device handle - * @param[in] ch1 Channel 1 state for sum voltage drop calculation - * @param[in] ch2 Channel 2 state for sum voltage drop calculation - * @param[in] ch3 Channel 3 state for sum voltage drop calculation - * - * @return @see _ina3221_set_enable_sum_channel - */ -static inline int ina3221_set_enable_sum_channel(const ina3221_t *dev, - ina3221_channel_state_t ch1, - ina3221_channel_state_t ch2, - ina3221_channel_state_t ch3) -{ - return _ina3221_set_enable_sum_channel(dev, - (ch1 ? INA3221_ENABLE_SUM_CH1 : 0) | - (ch2 ? INA3221_ENABLE_SUM_CH2 : 0) | - (ch3 ? INA3221_ENABLE_SUM_CH3 : 0)); -} +int ina3221_set_enable_sum_channel(const ina3221_t *dev, ina3221_ch_t ch); /** * @brief Read enabled channels for shunt voltage sum calculation * - * @param[in] dev Device handle - * @param[out] esch Pointer to enabled channels for shunt voltage sum calculation output variable @see ina3221_enable_sum_ch_t + * @param[in] dev Device handle + * @param[out] ch Channel flags @ref ina3221_channel_t * - * @return Number of enabled channels for shunt voltage sum calculation, on success - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed + * @return 0, on success + * @return -EIO, if I2C bus acquirement failed * @return @see i2c_read_regs */ -int _ina3221_get_enable_sum_channel(const ina3221_t *dev, - uint16_t *esch); - -/** - * @brief Wrapper for @see _ina3221_get_enable_sum_channel - * - * @param[in] dev Device handle - * @param[out] ch1 Pointer to channel 1 state variable for sum voltage drop calculation - * @param[out] ch2 Pointer to channel 2 state variable for sum voltage drop calculation - * @param[out] ch3 Pointer to channel 3 state variable for sum voltage drop calculation - * - * @return @see _ina3221_get_enable_sum_channel - */ -static inline int ina3221_get_enable_sum_channel(const ina3221_t *dev, - ina3221_channel_state_t *ch1, - ina3221_channel_state_t *ch2, - ina3221_channel_state_t *ch3) -{ - uint16_t esch = 0; - int ret = _ina3221_get_enable_sum_channel(dev, &esch); - - *ch1 = - (esch & - INA3221_ENABLE_SUM_CH1) ? INA3221_CH_ENABLE : INA3221_CH_DISABLE; - *ch2 = - (esch & - INA3221_ENABLE_SUM_CH2) ? INA3221_CH_ENABLE : INA3221_CH_DISABLE; - *ch3 = - (esch & - INA3221_ENABLE_SUM_CH3) ? INA3221_CH_ENABLE : INA3221_CH_DISABLE; - return ret; -} +int ina3221_get_enable_sum_channel(const ina3221_t *dev, ina3221_ch_t *ch); /** * @brief Enable latches for critical/warning alert pins * - * @param[in] dev Device handle - * @param[in] latch Enable latch flags + * @param[in] dev Device handle + * @param[in] warn Enable warning alert latch + * @param[in] crit Enable critical alert latch * - * @return INA3221_OK, on success - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed + * @return 0, on success + * @return -EIO, if I2C bus acquirement failed * @return @see i2c_read_regs * @return @see i2c_write_regs */ -int ina3221_set_latch(const ina3221_t *dev, ina3221_enable_latch_t latch); +int ina3221_set_latch(const ina3221_t *dev, bool warn, bool crit); /** * @brief Read enabled latches for critical/warning alert pins * - * @param[in] dev Device handle - * @param[in] latch Pointer to latch flags output variable + * @param[in] dev Device handle + * @param[in] warn Will be true if warning alert is latched + * @param[in] crit Will be true if critical alert is latched * - * @return INA3221_OK, on success - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed + * @return 0, on success + * @return -EIO, if I2C bus acquirement failed * @return @see i2c_read_regs */ -int ina3221_get_latch(const ina3221_t *dev, ina3221_enable_latch_t *latch); +int ina3221_get_latch(const ina3221_t *dev, bool *warn, bool *crit); /** * @brief Set critical shunt voltage alert limit to @p in_uv for each channel in @p ch * - * The function exits on the first channel that could not be updated. + * @param[in] dev Device handle + * @param[in] ch Channel flags @ref ina3221_channel_t + * @param[in] in_uv Critical shunt voltage limit in uV * - * @param[in] dev Device handle - * @param[in] ch Channel flags - * @param[in] in_uv Critical shunt voltage limit in uv - * - * @return Number of channels whose critical shunt voltage alert limit could be set, if any - * @return -ERANGE, if @p in_uv was not in [INA3221_MIN_SHUNT_UV; INA3221_MAX_SHUNT_UV] - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed - * @return @see i2c_write_regs + * @return Flags of which channel´s limits could be updated */ -int ina3221_set_crit_alert_limit(const ina3221_t *dev, ina3221_channel_t ch, - int32_t in_uv); +ina3221_ch_t ina3221_set_crit_alert_limit(const ina3221_t *dev, + ina3221_ch_t ch, int32_t in_uv); /** * @brief Read critical shunt voltage alert limit for each channel in @p ch * - * The function exits on the first channel whose critical alert limit could not be read. + * @param[in] dev Device handle + * @param[in] ch Channel flags @ref ina3221_channel_t + * @param[out] out_uv Output array of shunt voltage alert limits in uV * - * @param[in] dev Device handle - * @param[in] ch Channel flags - * @param[out] out_uv Output array of shunt voltage alert limits in uV - * - * @return Number of channels whose critical shunt voltage alert limits could be read, if any - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed - * @return @see i2c_read_regs + * @return Flags of which channel´s values were written to @p out_uv */ -int ina3221_get_crit_alert_limit(const ina3221_t *dev, ina3221_channel_t ch, - int32_t *out_uv); +ina3221_ch_t ina3221_get_crit_alert_limit(const ina3221_t *dev, ina3221_ch_t ch, + int32_t out_uv[INA3221_NUM_CH]); /** * @brief Set warning shunt voltage alert limit to @p in_uv for each channel in @p ch * - * The function exits on the first channel that could not be updated. + * @param[in] dev Device handle + * @param[in] ch Channel flags @ref ina3221_channel_t + * @param[in] in_uv Warning shunt voltage limit in uV * - * @param[in] dev Device handle - * @param[in] ch Channel flags - * @param[in] in_uv Warning shunt voltage limit in uV in host byte order - * - * @return Number of channels whose warning shunt voltage alert limit could be set, if any - * @return -ERANGE, if @p in_uv was not in [INA3221_MIN_SHUNT_UV; INA3221_MAX_SHUNT_UV] - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed - * @return @see i2c_write_regs + * @return Flags of which channel´s limits could be updated */ -int ina3221_set_warn_alert_limit(const ina3221_t *dev, ina3221_channel_t ch, - int32_t in_uv); +ina3221_ch_t ina3221_set_warn_alert_limit(const ina3221_t *dev, + ina3221_ch_t ch, int32_t in_uv); /** * @brief Read warning shunt voltage alert limit for each channel in @p ch * - * The function exits on the first channel whose warning alert limit could not be read. + * @param[in] dev Device handle + * @param[in] ch Channel flags @ref ina3221_channel_t + * @param[out] out_uv Output array of shunt voltage alert limits in uV * - * @param[in] dev Device handle - * @param[in] ch Channel flags - * @param[out] out_uv Output array of shunt voltage alert limits in uV - * - * @return Number of channels whose warning shunt voltage alert limits could be read, on success - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed - * @return @see i2c_read_regs + * @return Flags of which channel´s values could be read */ -int ina3221_get_warn_alert_limit(const ina3221_t *dev, ina3221_channel_t ch, - int32_t *out_uv); +ina3221_ch_t ina3221_get_warn_alert_limit(const ina3221_t *dev, ina3221_ch_t ch, + int32_t out_uv[INA3221_NUM_CH]); /** * @brief Set shunt voltage sum alert limit to @p in_uv * - * @param[in] dev Device handle - * @param[in] in_uv shunt voltage sum limit in uv + * @param[in] dev Device handle + * @param[in] in_uv Shunt voltage sum limit in uV * - * @return INA3221_OK, on success + * @return 0, on success * @return -ERANGE, if @p in_uv was not in [INA3221_MIN_SHUNT_SUM_UV; INA3221_MAX_SHUNT_SUM_UV] - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed + * @return -EIO, if I2C bus acquirement failed * @return @see i2c_write_regs */ int ina3221_set_shunt_voltage_sum_alert_limit(const ina3221_t *dev, @@ -925,11 +934,11 @@ int ina3221_set_shunt_voltage_sum_alert_limit(const ina3221_t *dev, /** * @brief Read shunt voltage sum alert limit * - * @param[in] dev Device handle - * @param[out] out_uv Pointer to sum voltage sum alert limit output variable + * @param[in] dev Device handle + * @param[out] out_uv Pointer to sum voltage sum alert limit output variable * - * @return INA3221_OK, on success - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed + * @return 0, on success + * @return -EIO, if I2C bus acquirement failed * @return @see i2c_read_regs */ int ina3221_get_shunt_voltage_sum_alert_limit(const ina3221_t *dev, @@ -938,12 +947,12 @@ int ina3221_get_shunt_voltage_sum_alert_limit(const ina3221_t *dev, /** * @brief Set bus voltage power valid upper limit to @p in_mv * - * @param[in] dev Device handle - * @param[in] in_mv bus voltage power valid upper limit in mv + * @param[in] dev Device handle + * @param[in] in_mv Bus voltage power valid upper limit in mV * - * @return INA3221_OK, on success + * @return 0, on success * @return -ERANGE, if @p in_mv was not in [INA3221_MIN_BUS_MV; INA3221_MAX_BUS_MV] - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed + * @return -EIO, if I2C bus acquirement failed * @return @see i2c_write_regs */ int ina3221_set_power_valid_upper_limit(const ina3221_t *dev, int32_t in_mv); @@ -951,11 +960,11 @@ int ina3221_set_power_valid_upper_limit(const ina3221_t *dev, int32_t in_mv); /** * @brief Read bus voltage power valid upper limit * - * @param[in] dev Device handle - * @param[out] out_mv Pointer to bus voltage power valid upper limit output variable + * @param[in] dev Device handle + * @param[out] out_mv Pointer to bus voltage power valid upper limit output variable * - * @return INA3221_OK, on success - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed + * @return 0, on success + * @return -EIO, if I2C bus acquirement failed * @return @see i2c_read_regs */ int ina3221_get_power_valid_upper_limit(const ina3221_t *dev, int32_t *out_mv); @@ -963,12 +972,12 @@ int ina3221_get_power_valid_upper_limit(const ina3221_t *dev, int32_t *out_mv); /** * @brief Set bus voltage power valid lower limit to @p in_mv * - * @param[in] dev Device handle - * @param[in] in_mv bus voltage power valid lower limit in mV + * @param[in] dev Device handle + * @param[in] in_mv Bus voltage power valid lower limit in mV * - * @return INA3221_OK, on success + * @return 0, on success * @return -ERANGE, if @p in_mv was not in [INA3221_MIN_BUS_MV; INA3221_MAX_BUS_MV] - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed + * @return -EIO, if I2C bus acquirement failed * @return @see i2c_write_regs */ int ina3221_set_power_valid_lower_limit(const ina3221_t *dev, int32_t in_mv); @@ -976,11 +985,11 @@ int ina3221_set_power_valid_lower_limit(const ina3221_t *dev, int32_t in_mv); /** * @brief Read bus voltage power valid lower limit * - * @param[in] dev Device handle - * @param[out] out_mv Pointer to bus voltage power valid lower limit output variable + * @param[in] dev Device handle + * @param[out] out_mv Pointer to bus voltage power valid lower limit output variable * - * @return INA3221_OK, on success - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed + * @return 0, on success + * @return -EIO, if I2C bus acquirement failed * @return @see i2c_read_regs */ int ina3221_get_power_valid_lower_limit(const ina3221_t *dev, int32_t *out_mv); @@ -988,11 +997,11 @@ int ina3221_get_power_valid_lower_limit(const ina3221_t *dev, int32_t *out_mv); /** * @brief Read status flags * - * @param[in] dev Device handle - * @param[out] flags Pointer to flags output variable + * @param[in] dev Device handle + * @param[out] flags Pointer to flags output variable * - * @return INA3221_OK, on success - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed + * @return 0, on success + * @return -EIO, if I2C bus acquirement failed * @return @see i2c_read_regs */ int ina3221_read_flags(const ina3221_t *dev, uint16_t *flags); @@ -1000,12 +1009,12 @@ int ina3221_read_flags(const ina3221_t *dev, uint16_t *flags); /** * @brief Read sum of shunt voltages * - * @param[in] dev Device handle - * @param[out] out_uv Pointer to shunt voltage sum output variable - * @param[out] flags Pointer to flags output variable, may be NULL + * @param[in] dev Device handle + * @param[out] out_uv Pointer to shunt voltage sum output variable + * @param[out] flags Pointer to flags output variable, may be NULL * - * @return INA3221_OK, on success - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed + * @return 0, on success + * @return -EIO, if I2C bus acquirement failed * @return @see i2c_read_regs */ int ina3221_read_shunt_sum_uv(const ina3221_t *dev, int32_t *out_uv, @@ -1014,98 +1023,78 @@ int ina3221_read_shunt_sum_uv(const ina3221_t *dev, int32_t *out_uv, /** * @brief Read shunt voltages for each channel in @p ch * - * The function exits on the first channel whose shunt voltage could not be read + * @param[in] dev Device handle + * @param[out] out_uv Array of output shunt voltage values in uV + * @param[out] flags Pointer to flags output variable, may be NULL * - * @param[in] dev Device handle - * @param[in] ch Channel flags - * @param[out] out_uv Array of output shunt voltage values in uV - * @param[out] flags Pointer to flags output variable, may be NULL - * - * @return Number of channels whose shunt voltages could be read, if any - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed - * @return @see i2c_read_regs + * @return Flags of which channel´s shunt voltage drops could be read */ -int ina3221_read_shunt_uv(const ina3221_t *dev, ina3221_channel_t ch, - int32_t *out_uv, uint16_t *flags); +ina3221_ch_t ina3221_read_shunt_uv(const ina3221_t *dev, + int32_t out_uv[INA3221_NUM_CH], + uint16_t *flags); /** * @brief Read bus voltages for each channel in @p ch * - * The function exits on the first channel whose bus voltage could not be read + * @param[in] dev Device handle + * @param[out] out_mv Array of output bus voltage values in mV + * @param[out] flags Pointer to flags output variable, may be NULL * - * @param[in] dev Device handle - * @param[in] ch Channel flags - * @param[out] out_mv Array of output bus voltage values in mV - * @param[out] flags Pointer to flags output variable, may be NULL - * - * @return Number of channels whose bus voltages could be read, if any - * @return -INA3221_I2C_ERROR, if I2C bus acquirement failed - * @return @see i2c_read_regs + * @return Flags of which channel´s bus voltage values could be read */ -int ina3221_read_bus_mv(const ina3221_t *dev, ina3221_channel_t ch, - int16_t *out_mv, uint16_t *flags); +ina3221_ch_t ina3221_read_bus_mv(const ina3221_t *dev, + int16_t out_mv[INA3221_NUM_CH], + uint16_t *flags); /** * @brief Calculate current for each channel in @p ch * - * @param[in] dev Device handle - * @param[in] ch Channel flags - * @param[in] in_uv Array of input shunt voltage values - * @param[out] out_ma Array of output current values - * - * @return Number of clculated current values + * @param[in] ch Flags of which values in @p in_mohm and @p in_uv are valid + * @param[in] in_mohm Array of input shunt resistors in mOhm + * @param[in] in_uv Array of input shunt voltage values in uV + * @param[out] out_ua Array of output current values in uA */ -int ina3221_calculate_current_ua(const ina3221_t *dev, ina3221_channel_t ch, - int32_t *in_uv, int32_t *out_ma); +void ina3221_calculate_current_ua(ina3221_ch_t ch, + const uint16_t in_mohm[INA3221_NUM_CH], + const int32_t in_uv[INA3221_NUM_CH], + int32_t out_ua[INA3221_NUM_CH]); /** * @brief Calculate power from bus voltage and current values * - * @param[in] in_mv Array of input bus voltage values in mV - * @param[in] in_ua Array of input current values in uA - * @param[in] num Number of values in @p in_mv - * @param[out] out_mw Array of output power values in uW - * - * @return Number of calculated power values, on success - * @return -ERANGE, if @p num is greater than INA3221_NUM_CH + * @param[in] ch Flags of which values in @p in_mv and @p in_ua are valid + * @param[in] in_mv Array of input bus voltage values in mV + * @param[in] in_ua Array of input current values in uA + * @param[out] out_mw Array of output power values in mW */ -int ina3221_calculate_power_uw(int16_t *in_mv, int32_t *in_ua, uint8_t num, - int32_t *out_mw); +void ina3221_calculate_power_uw(ina3221_ch_t ch, + const int16_t in_mv[INA3221_NUM_CH], + const int32_t in_ua[INA3221_NUM_CH], + int32_t out_mw[INA3221_NUM_CH]); /** - * @brief Align @p in_res to the number of channels - * For example: @p ch = (INA3221_CH1 | INA3221_CH3) - * @p in_res = {value_ch1, value_ch3}, then - * @p out_res will be {value_ch1, 0, value_ch3} + * @brief Set operation mode to INA3221_MODE_TRIGGER_SHUNT_ONLY + * to trigger shunt voltage measurement * - * @param[in] ch Channel flags - * @param[in] in_res Output of e.g. @see ina3221_calculate_current_ua - * @param[out] out_res Channel aligned result - * @param[in] res_val_size Size of a value in @p in_res in bytes - */ -void ina3221_ch_align(ina3221_channel_t ch, const void *in_res, void *out_res, - size_t res_val_size); - -/** - * @brief Set operation mode to INA3221_MODE_TRIGGER_SHUNT_ONLY to trigger shunt voltage measurement - * - * @param dev Device handle + * @param dev Device handle */ #define INA3221_TRIGGER_SHUNT(dev) \ ina3221_set_mode(dev, INA3221_MODE_TRIGGER_SHUNT_ONLY) /** - * @brief Set operation mode to INA3221_MODE_TRIGGER_BUS_ONLY to trigger bus voltage measurement + * @brief Set operation mode to INA3221_MODE_TRIGGER_BUS_ONLY + * to trigger bus voltage measurement * - * @param dev Device handle + * @param dev Device handle */ #define INA3221_TRIGGER_BUS(dev) \ ina3221_set_mode(dev, INA3221_MODE_TRIGGER_BUS_ONLY) /** - * @brief Set operation mode to INA3221_MODE_TRIGGER_SHUNT_BUS to trigger shunt and bus voltage measurement + * @brief Set operation mode to INA3221_MODE_TRIGGER_SHUNT_BUS + * to trigger shunt and bus voltage measurement * - * @param dev Device handle + * @param dev Device handle */ #define INA3221_TRIGGER_SHUNT_AND_BUS(dev) \ ina3221_set_mode(dev, INA3221_MODE_TRIGGER_SHUNT_BUS) diff --git a/drivers/saul/init_devs/auto_init_ina3221.c b/drivers/saul/init_devs/auto_init_ina3221.c index c81f7d99cd..2382de2888 100644 --- a/drivers/saul/init_devs/auto_init_ina3221.c +++ b/drivers/saul/init_devs/auto_init_ina3221.c @@ -42,7 +42,7 @@ void auto_init_ina3221(void) for (unsigned i = 0; i < INA3221_NUM; i++) { LOG_DEBUG("[auto_init_saul] initializing ina3221 #%u\n", i); int status = ina3221_init(&ina3221_devs[i], &ina3221_params[i]); - if (status != INA3221_OK) { + if (status != 0) { LOG_ERROR("[auto_init_saul] error(%d) initializing ina3221 #%u\n", status, i); continue;