mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #15915 from fabian18/ina3221-fixes
drivers/ina3221: style fixes and improvements
This commit is contained in:
commit
b6a2d08afc
@ -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;
|
||||
}
|
||||
|
@ -24,39 +24,24 @@
|
||||
#include <string.h>
|
||||
#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));
|
||||
}
|
||||
|
@ -26,116 +26,82 @@
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#define SAUL_INA3221_NO_VALUE (0)
|
||||
|
||||
static int read_bus_voltage(const void *dev, phydat_t *res)
|
||||
{
|
||||
ina3221_t *_dev = (ina3221_t *)dev;
|
||||
uint16_t ench = 0;
|
||||
int16_t voltage[INA3221_NUM_CH] = { 0 };
|
||||
int num_ch = _ina3221_get_enable_channel(_dev, &ench);
|
||||
|
||||
if (!num_ch) {
|
||||
return -ECANCELED;
|
||||
}
|
||||
ina3221_channel_t ch = (((ench & INA3221_ENABLE_CH1) ? INA3221_CH1 : 0) |
|
||||
((ench & INA3221_ENABLE_CH2) ? INA3221_CH2 : 0) |
|
||||
((ench & INA3221_ENABLE_CH3) ? INA3221_CH3 : 0));
|
||||
ina3221_read_bus_mv(_dev, ch, voltage, NULL);
|
||||
res->scale = -3; /* mV to V*/
|
||||
res->unit = UNIT_V;
|
||||
for (int i = 0, j = 0; i < INA3221_NUM_CH; i++) {
|
||||
res->val[i] = (ch & (1 << i))
|
||||
? voltage[j++] : SAUL_INA3221_NO_VALUE;
|
||||
ina3221_ch_t ch = 0;
|
||||
int32_t values[INA3221_NUM_CH] = { 0 };
|
||||
ina3221_get_enable_channel(dev, &ch);
|
||||
if (ch) {
|
||||
int16_t voltage[INA3221_NUM_CH];
|
||||
ch &= ina3221_read_bus_mv(dev, voltage, NULL);
|
||||
res->scale = -3; /* mV to V */
|
||||
res->unit = UNIT_V;
|
||||
for (int i = 0; i < INA3221_NUM_CH; i++) {
|
||||
values[i] = voltage[i];
|
||||
}
|
||||
}
|
||||
phydat_fit(res, values, 3);
|
||||
return INA3221_NUM_CH;
|
||||
}
|
||||
|
||||
static int read_current(const void *dev, phydat_t *res)
|
||||
{
|
||||
ina3221_t *_dev = (ina3221_t *)dev;
|
||||
uint16_t ench = 0;
|
||||
int32_t shunt_uv[INA3221_NUM_CH] = { 0 };
|
||||
ina3221_ch_t ch = 0;
|
||||
int32_t current[INA3221_NUM_CH] = { 0 };
|
||||
int num_ch = _ina3221_get_enable_channel(_dev, &ench);
|
||||
|
||||
if (!num_ch) {
|
||||
return -ECANCELED;
|
||||
ina3221_get_enable_channel(dev, &ch);
|
||||
if (ch) {
|
||||
int32_t shunt_uv[INA3221_NUM_CH];
|
||||
ch &= ina3221_read_shunt_uv(dev, shunt_uv, NULL);
|
||||
ina3221_calculate_current_ua(ch, ((const ina3221_t *)dev)->params.rshunt_mohm,
|
||||
shunt_uv, current);
|
||||
res->scale = -6; /* uA to A */
|
||||
res->unit = UNIT_A;
|
||||
}
|
||||
ina3221_channel_t ch = (((ench & INA3221_ENABLE_CH1) ? INA3221_CH1 : 0) |
|
||||
((ench & INA3221_ENABLE_CH2) ? INA3221_CH2 : 0) |
|
||||
((ench & INA3221_ENABLE_CH3) ? INA3221_CH3 : 0));
|
||||
ina3221_read_shunt_uv(_dev, ch, shunt_uv, NULL);
|
||||
ina3221_calculate_current_ua(_dev, ch, shunt_uv, current);
|
||||
res->scale = -6; /* uA to A*/
|
||||
res->unit = UNIT_A;
|
||||
for (int i = 0, j = 0; i < INA3221_NUM_CH; i++) {
|
||||
res->val[i] = (ch & (1 << i))
|
||||
? (int16_t)current[j++] : SAUL_INA3221_NO_VALUE;
|
||||
}
|
||||
ina3221_ch_align(ch, current, current, sizeof(int32_t));
|
||||
phydat_fit(res, current, 3);
|
||||
return INA3221_NUM_CH;
|
||||
}
|
||||
|
||||
static int read_power(const void *dev, phydat_t *res)
|
||||
{
|
||||
ina3221_t *_dev = (ina3221_t *)dev;
|
||||
uint16_t ench = 0;
|
||||
int32_t shunt_uv[INA3221_NUM_CH] = { 0 };
|
||||
int32_t current_ua[INA3221_NUM_CH] = { 0 };
|
||||
int16_t bus_mv[INA3221_NUM_CH] = { 0 };
|
||||
ina3221_ch_t ch = 0;
|
||||
int32_t power[INA3221_NUM_CH] = { 0 };
|
||||
int num_ch = _ina3221_get_enable_channel(_dev, &ench);
|
||||
|
||||
if (!num_ch) {
|
||||
return -ECANCELED;
|
||||
ina3221_get_enable_channel(dev, &ch);
|
||||
if (ch) {
|
||||
int32_t shunt_uv[INA3221_NUM_CH];
|
||||
int32_t current_ua[INA3221_NUM_CH];
|
||||
int16_t bus_mv[INA3221_NUM_CH];
|
||||
ch &= ina3221_read_shunt_uv(dev, shunt_uv, NULL);
|
||||
ch &= ina3221_read_bus_mv(dev, bus_mv, NULL);
|
||||
ina3221_calculate_current_ua(ch, ((const ina3221_t *)dev)->params.rshunt_mohm,
|
||||
shunt_uv, current_ua);
|
||||
ina3221_calculate_power_uw(ch, bus_mv, current_ua, power);
|
||||
res->scale = -6; /* uW to W */
|
||||
res->unit = UNIT_W;
|
||||
}
|
||||
ina3221_channel_t ch = (((ench & INA3221_ENABLE_CH1) ? INA3221_CH1 : 0) |
|
||||
((ench & INA3221_ENABLE_CH2) ? INA3221_CH2 : 0) |
|
||||
((ench & INA3221_ENABLE_CH3) ? INA3221_CH3 : 0));
|
||||
int num_ch_shunt_uv = ina3221_read_shunt_uv(_dev, ch, shunt_uv, NULL);
|
||||
ina3221_calculate_current_ua(_dev, ch, shunt_uv, current_ua);
|
||||
ina3221_read_bus_mv(_dev, ch, bus_mv, NULL);
|
||||
ina3221_calculate_power_uw(bus_mv, current_ua, num_ch_shunt_uv, power);
|
||||
res->scale = -6; /* uW to W*/
|
||||
res->unit = UNIT_W;
|
||||
for (int i = 0, j = 0; i < INA3221_NUM_CH; i++) {
|
||||
res->val[i] = (ch & (1 << i))
|
||||
? (int16_t)power[j++] : SAUL_INA3221_NO_VALUE;
|
||||
}
|
||||
ina3221_ch_align(ch, power, power, sizeof(int32_t));
|
||||
phydat_fit(res, power, 3);
|
||||
return INA3221_NUM_CH;
|
||||
}
|
||||
|
||||
static int read_shunt_voltage_sum(const void *dev, phydat_t *res)
|
||||
{
|
||||
ina3221_t *_dev = (ina3221_t *)dev;
|
||||
uint16_t ench = 0;
|
||||
int32_t shunt_voltage_sum = SAUL_INA3221_NO_VALUE;
|
||||
int num_ch = _ina3221_get_enable_channel(_dev, &ench);
|
||||
|
||||
if (!num_ch) {
|
||||
return -ECANCELED;
|
||||
ina3221_ch_t ch = 0;
|
||||
int32_t shunt_voltage_sum = 0;
|
||||
ina3221_get_enable_channel(dev, &ch);
|
||||
if (ch) {
|
||||
ina3221_read_shunt_sum_uv(dev, &shunt_voltage_sum, NULL);
|
||||
res->scale = -6; /* uV to V */
|
||||
res->unit = UNIT_V;
|
||||
}
|
||||
ina3221_read_shunt_sum_uv(_dev, &shunt_voltage_sum, NULL);
|
||||
res->scale = -6; /* uV to V*/
|
||||
res->unit = UNIT_V;
|
||||
res->val[0] = shunt_voltage_sum;
|
||||
phydat_fit(res, &shunt_voltage_sum, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int configure_channel(const void *dev, phydat_t *data)
|
||||
{
|
||||
ina3221_t *_dev = (ina3221_t *)dev;
|
||||
uint16_t ench =
|
||||
((data->val[0] & INA3221_CH1) ? INA3221_ENABLE_CH1 : 0) |
|
||||
((data->val[0] & INA3221_CH2) ? INA3221_ENABLE_CH2 : 0) |
|
||||
((data->val[0] & INA3221_CH3) ? INA3221_ENABLE_CH3 : 0);
|
||||
|
||||
if (_ina3221_set_enable_channel(_dev, ench) != INA3221_OK) {
|
||||
ina3221_ch_t ch = (data->val[0] ? INA3221_CH1 : 0) |
|
||||
(data->val[1] ? INA3221_CH2 : 0) |
|
||||
(data->val[2] ? INA3221_CH3 : 0);
|
||||
if (ina3221_set_enable_channel((ina3221_t *)dev, ch) != 0) {
|
||||
return -ECANCELED;
|
||||
}
|
||||
return INA3221_NUM_CH;
|
||||
@ -143,13 +109,10 @@ static int configure_channel(const void *dev, phydat_t *data)
|
||||
|
||||
static int configure_channel_sum(const void *dev, phydat_t *data)
|
||||
{
|
||||
ina3221_t *_dev = (ina3221_t *)dev;
|
||||
uint16_t esch =
|
||||
((data->val[0] & INA3221_CH1) ? INA3221_ENABLE_SUM_CH1 : 0) |
|
||||
((data->val[0] & INA3221_CH2) ? INA3221_ENABLE_SUM_CH2 : 0) |
|
||||
((data->val[0] & INA3221_CH3) ? INA3221_ENABLE_SUM_CH3 : 0);
|
||||
|
||||
if (_ina3221_set_enable_sum_channel(_dev, esch) != INA3221_OK) {
|
||||
ina3221_ch_t ch = (data->val[0] ? INA3221_CH1 : 0) |
|
||||
(data->val[1] ? INA3221_CH2 : 0) |
|
||||
(data->val[2] ? INA3221_CH3 : 0);
|
||||
if (ina3221_set_enable_sum_channel(dev, ch) != 0) {
|
||||
return -ECANCELED;
|
||||
}
|
||||
return INA3221_NUM_CH;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
|
@ -80,8 +80,6 @@ static void power_valid_alert(void *arg)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
xtimer_init();
|
||||
|
||||
int status;
|
||||
ina3221_t dev;
|
||||
|
||||
@ -123,7 +121,7 @@ int main(void)
|
||||
}
|
||||
|
||||
status = ina3221_init(&dev, &ina3221_params[0]);
|
||||
if (status != INA3221_OK) {
|
||||
if (status != 0) {
|
||||
printf("[FAILURE] ina3221_init: %d\n", status);
|
||||
return 1;
|
||||
}
|
||||
@ -136,7 +134,7 @@ int main(void)
|
||||
if (status == -ENOTSUP) {
|
||||
puts("[WARNING] INA3221_ALERT_WRN not supported");
|
||||
}
|
||||
else if (status != INA3221_OK) {
|
||||
else if (status != 0) {
|
||||
printf("[FAILURE] ina3221_enable_alert INA3221_ALERT_WRN: %d\n",
|
||||
status);
|
||||
return 1;
|
||||
@ -146,7 +144,7 @@ int main(void)
|
||||
if (status == -ENOTSUP) {
|
||||
puts("[WARNING] INA3221_ALERT_CRT not supported");
|
||||
}
|
||||
else if (status != INA3221_OK) {
|
||||
else if (status != 0) {
|
||||
printf("[FAILURE] ina3221_enable_alert INA3221_ALERT_CRT: %d\n",
|
||||
status);
|
||||
return 1;
|
||||
@ -157,7 +155,7 @@ int main(void)
|
||||
if (status == -ENOTSUP) {
|
||||
puts("[WARNING] INA3221_ALERT_TC not supported");
|
||||
}
|
||||
else if (status != INA3221_OK) {
|
||||
else if (status != 0) {
|
||||
printf("[FAILURE] ina3221_enable_alert INA3221_ALERT_TC: %d\n", status);
|
||||
return 1;
|
||||
}
|
||||
@ -166,74 +164,47 @@ int main(void)
|
||||
if (status == -ENOTSUP) {
|
||||
puts("[WARNING] INA3221_ALERT_PV not supported");
|
||||
}
|
||||
else if (status != INA3221_OK) {
|
||||
else if (status != 0) {
|
||||
printf("[FAILURE] ina3221_enable_alert INA3221_ALERT_PV: %d\n", status);
|
||||
return 1;
|
||||
}
|
||||
puts("[SUCCESS] ina3221_enable_alert");
|
||||
#endif
|
||||
|
||||
int32_t shunt_uv[INA3221_NUM_CH] = { 0 };
|
||||
int16_t bus_mv[INA3221_NUM_CH] = { 0 };
|
||||
int32_t sum_shunt_uv = 0;
|
||||
int32_t current_ua[INA3221_NUM_CH] = { 0 };
|
||||
int32_t power_uw[INA3221_NUM_CH] = { 0 };
|
||||
uint16_t flags = 0;
|
||||
int32_t shunt_uv[INA3221_NUM_CH];
|
||||
int16_t bus_mv[INA3221_NUM_CH];
|
||||
int32_t sum_shunt_uv;
|
||||
int32_t current_ua[INA3221_NUM_CH];
|
||||
int32_t power_uw[INA3221_NUM_CH];
|
||||
uint16_t flags;
|
||||
ina3221_ch_t ch = 0;
|
||||
ina3221_get_enable_channel(&dev, &ch);
|
||||
|
||||
status = ina3221_read_shunt_uv(&dev,
|
||||
INA3221_CH1 | INA3221_CH2 | INA3221_CH3,
|
||||
shunt_uv, &flags);
|
||||
if (status != INA3221_NUM_CH) {
|
||||
printf("[FAILURE] ina3221_read_shunt_uv: %d\n", status);
|
||||
if (ch != ina3221_read_shunt_uv(&dev, shunt_uv, &flags)) {
|
||||
puts("[FAILURE] ina3221_read_shunt_uv");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
puts("[SUCCESS] ina3221_read_shunt_uv");
|
||||
}
|
||||
|
||||
status = ina3221_calculate_current_ua(&dev,
|
||||
INA3221_CH1 | INA3221_CH2 | INA3221_CH3, shunt_uv,
|
||||
current_ua);
|
||||
if (status != INA3221_NUM_CH) {
|
||||
printf("[FAILURE] ina3221_calculate_current_ua: %d\n", status);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
puts("[SUCCESS] ina3221_calculate_current_ua");
|
||||
}
|
||||
|
||||
status = ina3221_read_bus_mv(&dev, INA3221_CH1 | INA3221_CH2 | INA3221_CH3,
|
||||
bus_mv, &flags);
|
||||
if (status != INA3221_NUM_CH) {
|
||||
printf("[FAILURE] ina3221_read_bus_mv: %d\n", status);
|
||||
if (ch != ina3221_read_bus_mv(&dev, bus_mv, &flags)) {
|
||||
puts("[FAILURE] ina3221_read_bus_mv");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
puts("[SUCCESS] ina3221_read_bus_mv");
|
||||
}
|
||||
|
||||
status = ina3221_calculate_power_uw(bus_mv, current_ua, status, power_uw);
|
||||
if (status != INA3221_NUM_CH) {
|
||||
printf("[FAILURE] ina3221_calculate_power_uw: %d\n", status);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
puts("[SUCCESS] ina3221_calculate_power_uw");
|
||||
}
|
||||
|
||||
status = ina3221_set_enable_sum_channel(&dev, INA3221_CH_ENABLE,
|
||||
INA3221_CH_ENABLE,
|
||||
INA3221_CH_ENABLE);
|
||||
if (status < 0) {
|
||||
if ((status = ina3221_set_enable_sum_channel(&dev, ch)) != 0) {
|
||||
printf("[FAILURE] ina3221_set_enable_sum_channel: %d\n", status);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
printf("[SUCCESS] ina3221_set_enable_sum_channel");
|
||||
puts("[SUCCESS] ina3221_set_enable_sum_channel");
|
||||
}
|
||||
|
||||
status = ina3221_read_shunt_sum_uv(&dev, &sum_shunt_uv, &flags);
|
||||
if (status != INA3221_OK) {
|
||||
if ((status = ina3221_read_shunt_sum_uv(&dev, &sum_shunt_uv, &flags)) != 0) {
|
||||
printf("[FAILURE] ina3221_read_shunt_sum_uv: %d\n", status);
|
||||
return 1;
|
||||
}
|
||||
@ -241,8 +212,7 @@ int main(void)
|
||||
puts("[SUCCESS] ina3221_read_shunt_sum_uv");
|
||||
}
|
||||
|
||||
status = INA3221_TRIGGER_SHUNT_AND_BUS(&dev);
|
||||
if (status < 0) {
|
||||
if ((status = INA3221_TRIGGER_SHUNT_AND_BUS(&dev)) != 0) {
|
||||
printf("[FAILURE] INA3221_TRIGGER_SHUNT_AND_BUS: %d\n", status);
|
||||
return 1;
|
||||
}
|
||||
@ -251,27 +221,20 @@ int main(void)
|
||||
}
|
||||
flags = 0;
|
||||
while (!(flags & INA3221_FLAG_CONV_READY)) {
|
||||
status = ina3221_read_flags(&dev, &flags);
|
||||
if (status < 0) {
|
||||
if ((status = ina3221_read_flags(&dev, &flags)) != 0) {
|
||||
printf("[FAILURE] ina3221_read_flags: %d\n", status);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
status = ina3221_read_shunt_uv(&dev,
|
||||
INA3221_CH1 | INA3221_CH2 | INA3221_CH3,
|
||||
shunt_uv, &flags);
|
||||
if (status != INA3221_NUM_CH) {
|
||||
printf("[FAILURE] ina3221_read_shunt_uv (triggered): %d\n", status);
|
||||
if (ch != ina3221_read_shunt_uv(&dev, shunt_uv, &flags)) {
|
||||
puts("[FAILURE] ina3221_read_shunt_uv (triggered)");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
puts("[SUCCESS] ina3221_read_shunt_uv (triggered)");
|
||||
}
|
||||
|
||||
status = ina3221_read_bus_mv(&dev, INA3221_CH1 | INA3221_CH2 | INA3221_CH3,
|
||||
bus_mv, &flags);
|
||||
if (status != INA3221_NUM_CH) {
|
||||
printf("[FAILURE] ina3221_read_bus_mv (triggered): %d\n", status);
|
||||
if (ch != ina3221_read_bus_mv(&dev, bus_mv, &flags)) {
|
||||
puts("[FAILURE] ina3221_read_bus_mv (triggered)");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
@ -279,11 +242,9 @@ int main(void)
|
||||
}
|
||||
|
||||
int32_t crit_alert_lim = CRIT_ALERT_LIM_UV;
|
||||
status = ina3221_set_crit_alert_limit(&dev,
|
||||
INA3221_CH1 | INA3221_CH2 | INA3221_CH3,
|
||||
crit_alert_lim);
|
||||
if (status != INA3221_NUM_CH) {
|
||||
printf("[FAILURE] ina3221_set_crit_alert_limit: %d\n", status);
|
||||
ina3221_ch_t crit_ch = INA3221_CH1 | INA3221_CH2 | INA3221_CH3;
|
||||
if (crit_ch != ina3221_set_crit_alert_limit(&dev, crit_ch, crit_alert_lim)) {
|
||||
puts("[FAILURE] ina3221_set_crit_alert_limit");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
@ -291,11 +252,9 @@ int main(void)
|
||||
}
|
||||
|
||||
int32_t warn_alert_lim = WARN_ALERT_LIM_UV;
|
||||
status = ina3221_set_warn_alert_limit(&dev,
|
||||
INA3221_CH1 | INA3221_CH2 | INA3221_CH3,
|
||||
warn_alert_lim);
|
||||
if (status != INA3221_NUM_CH) {
|
||||
printf("[FAILURE] ina3221_set_warn_alert_limit: %d\n", status);
|
||||
ina3221_ch_t warn_ch = INA3221_CH1 | INA3221_CH2 | INA3221_CH3;
|
||||
if (warn_ch != ina3221_set_warn_alert_limit(&dev, warn_ch, warn_alert_lim)) {
|
||||
puts("[FAILURE] ina3221_set_warn_alert_limit");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
@ -303,8 +262,7 @@ int main(void)
|
||||
}
|
||||
|
||||
int32_t pv_lower_lim = PV_LOWER_LIM_MV;
|
||||
status = ina3221_set_power_valid_lower_limit(&dev, pv_lower_lim);
|
||||
if (status != INA3221_OK) {
|
||||
if ((status = ina3221_set_power_valid_lower_limit(&dev, pv_lower_lim)) != 0) {
|
||||
printf("[FAILURE] ina3221_set_power_valid_lower_limit: %d\n", status);
|
||||
return 1;
|
||||
}
|
||||
@ -313,8 +271,7 @@ int main(void)
|
||||
}
|
||||
|
||||
int32_t pv_upper_lim = PV_UPPER_LIM_MV;
|
||||
status = ina3221_set_power_valid_upper_limit(&dev, pv_upper_lim);
|
||||
if (status != INA3221_OK) {
|
||||
if ((status = ina3221_set_power_valid_upper_limit(&dev, pv_upper_lim)) != 0) {
|
||||
printf("[FAILURE] ina3221_set_power_valid_upper_limit: %d\n", status);
|
||||
return 1;
|
||||
}
|
||||
@ -323,27 +280,23 @@ int main(void)
|
||||
}
|
||||
|
||||
int32_t sum_shunt_alert_lim = SUM_SHUNT_ALERT_LIM_UV;
|
||||
status =
|
||||
ina3221_set_shunt_voltage_sum_alert_limit(&dev, sum_shunt_alert_lim);
|
||||
if (status != INA3221_OK) {
|
||||
printf("[FAILURE] ina3221_set_shunt_voltage_sum_alert_limit: %d\n",
|
||||
status);
|
||||
if ((status = ina3221_set_shunt_voltage_sum_alert_limit(&dev, sum_shunt_alert_lim))
|
||||
!= 0) {
|
||||
printf("[FAILURE] ina3221_set_shunt_voltage_sum_alert_limit: %d\n", status);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
puts("[SUCCESS] ina3221_set_shunt_voltage_sum_alert_limit");
|
||||
}
|
||||
|
||||
status = ina3221_set_mode(&dev, INA3221_MODE_CONTINUOUS_SHUNT_BUS);
|
||||
if (status != INA3221_OK) {
|
||||
if ((status = ina3221_set_mode(&dev, INA3221_MODE_CONTINUOUS_SHUNT_BUS)) != 0) {
|
||||
printf("[FAILURE] ina3221_set_mode: %d\n", status);
|
||||
return 1;
|
||||
}
|
||||
char line_buffer[strlen(THEAD) + 1];
|
||||
char col_buffer[strlen(COL) + 1];
|
||||
char line_buffer[sizeof(THEAD)];
|
||||
char col_buffer[sizeof(COL)];
|
||||
while (1) {
|
||||
status = ina3221_read_flags(&dev, &flags);
|
||||
if (status != INA3221_OK) {
|
||||
if ((status = ina3221_read_flags(&dev, &flags)) != 0) {
|
||||
printf("[FAILURE] ina3221_read_flags: %d\n", status);
|
||||
return 1;
|
||||
}
|
||||
@ -351,33 +304,16 @@ int main(void)
|
||||
xtimer_sleep(2);
|
||||
continue;
|
||||
}
|
||||
status = ina3221_read_shunt_uv(&dev,
|
||||
INA3221_CH1 | INA3221_CH2 | INA3221_CH3,
|
||||
shunt_uv, NULL);
|
||||
if (status != INA3221_NUM_CH) {
|
||||
printf("[FAILURE] ina3221_read_shunt_uv: %d\n", status);
|
||||
if (ch != ina3221_read_shunt_uv(&dev, shunt_uv, NULL)) {
|
||||
puts("[FAILURE] ina3221_read_shunt_uv");
|
||||
return 1;
|
||||
}
|
||||
status = ina3221_read_bus_mv(&dev,
|
||||
INA3221_CH1 | INA3221_CH2 | INA3221_CH3,
|
||||
bus_mv, NULL);
|
||||
if (status != INA3221_NUM_CH) {
|
||||
printf("[FAILURE] ina3221_read_bus_mv: %d\n", status);
|
||||
return 1;
|
||||
}
|
||||
status = ina3221_calculate_current_ua(&dev,
|
||||
INA3221_CH1 | INA3221_CH2 | INA3221_CH3, shunt_uv,
|
||||
current_ua);
|
||||
if (status != INA3221_NUM_CH) {
|
||||
printf("[FAILURE] ina3221_calculate_current_ua: %d\n", status);
|
||||
return 1;
|
||||
}
|
||||
status = ina3221_calculate_power_uw(bus_mv, current_ua, INA3221_NUM_CH,
|
||||
power_uw);
|
||||
if (status != INA3221_NUM_CH) {
|
||||
printf("[FAILURE] ina3221_calculate_power_uw: %d\n", status);
|
||||
if (ch != ina3221_read_bus_mv(&dev, bus_mv, NULL)) {
|
||||
puts("[FAILURE] ina3221_read_bus_mv");
|
||||
return 1;
|
||||
}
|
||||
ina3221_calculate_current_ua(ch, dev.params.rshunt_mohm, shunt_uv, current_ua);
|
||||
ina3221_calculate_power_uw(ch, bus_mv, current_ua, power_uw);
|
||||
puts(THEAD);
|
||||
puts(HLINE);
|
||||
for (int8_t i = 0; i < INA3221_NUM_CH; i++) {
|
||||
|
Loading…
Reference in New Issue
Block a user