Skip to content

Commit

Permalink
drivers: sensor: ti: ina23x: Refactor INA230 trigger
Browse files Browse the repository at this point in the history
Trigger use own thread or system work queue to handle interrupts. This
allows to read the device state in the trigger handler.
Also trigger can distinguish between data ready and alert functionality,
and does not require prepare device state before setting trigger.

Signed-off-by: Tomáš Juřena <jurenatomas@gmail.com>
  • Loading branch information
jurenat committed Dec 21, 2024
1 parent e8c5405 commit 64fb6f0
Show file tree
Hide file tree
Showing 8 changed files with 384 additions and 77 deletions.
35 changes: 32 additions & 3 deletions drivers/sensor/ti/ina23x/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,41 @@ config INA237_VSHUNT
measurement is required.

config INA230_TRIGGER
bool "INA230 trigger mode"
bool

choice
prompt "Trigger mode"
default INA230_TRIGGER_GLOBAL_THREAD
help
Specify the type of triggering to be used by the driver.

config INA230_TRIGGER_OWN_THREAD
bool "Use own thread"
depends on INA230
depends on GPIO
depends on $(dt_compat_any_has_prop,$(DT_COMPAT_TI_INA230),alert-gpios) || $(dt_compat_any_has_prop,$(DT_COMPAT_TI_INA236),alert-gpios)
select INA230_TRIGGER

config INA230_TRIGGER_GLOBAL_THREAD
bool "Use global thread"
depends on INA230
depends on GPIO
depends on $(dt_compat_any_has_prop,$(DT_COMPAT_TI_INA230),alert-gpios) || $(dt_compat_any_has_prop,$(DT_COMPAT_TI_INA236),alert-gpios)
select INA230_TRIGGER
endchoice

config INA230_THREAD_PRIORITY
int "Own thread priority"
depends on INA230_TRIGGER_OWN_THREAD
default 10
help
The priority of the thread used for handling interrupts.

config INA230_THREAD_STACK_SIZE
int "Own thread stack size"
depends on INA230_TRIGGER_OWN_THREAD
default 1024
help
Set to enable trigger mode using gpio interrupt, where
interrupts are configured to line ALERT PIN.
The thread stack size.

endif # INA23X
78 changes: 56 additions & 22 deletions drivers/sensor/ti/ina23x/ina230.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <zephyr/logging/log.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/dt-bindings/sensor/ina230.h>

LOG_MODULE_REGISTER(INA230, CONFIG_SENSOR_LOG_LEVEL);

Expand All @@ -24,13 +25,17 @@ LOG_MODULE_REGISTER(INA230, CONFIG_SENSOR_LOG_LEVEL);
#define INA230_POWER_SCALING 25
#define INA236_POWER_SCALING 32

#define INA230_VSHUNT_NV_LSV 2500

#define INA230_MASK_REG_MASK (INA230_ALERT_POLARITY | INA230_ALERT_LATCH_ENABLE)

static int ina230_channel_get(const struct device *dev, enum sensor_channel chan,
struct sensor_value *val)
{
struct ina230_data *data = dev->data;
const struct ina230_config *const config = dev->config;
uint32_t bus_uv, power_uw;
int32_t current_ua;
int32_t current_ua, shunt_nv;

switch (chan) {
case SENSOR_CHAN_VOLTAGE:
Expand All @@ -54,9 +59,16 @@ static int ina230_channel_get(const struct device *dev, enum sensor_channel chan
power_uw = data->power * config->power_scale * config->current_lsb;

/* convert to fractional watts */
val->val1 = (int32_t)(power_uw / 1000000U);
val->val2 = (int32_t)(power_uw % 1000000U);
val->val1 = power_uw / 1000000U;
val->val2 = power_uw % 1000000U;
break;

case SENSOR_CHAN_VSHUNT:
shunt_nv = data->shunt_voltage * INA230_VSHUNT_NV_LSV;

/* convert to fractional milli-volts */
val->val1 = shunt_nv / 1000000L;
val->val2 = shunt_nv % 1000000L;
break;

default:
Expand All @@ -73,7 +85,7 @@ static int ina230_sample_fetch(const struct device *dev, enum sensor_channel cha
int ret;

if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_VOLTAGE && chan != SENSOR_CHAN_CURRENT &&
chan != SENSOR_CHAN_POWER) {
chan != SENSOR_CHAN_POWER && chan != SENSOR_CHAN_VSHUNT) {
return -ENOTSUP;
}

Expand Down Expand Up @@ -101,22 +113,41 @@ static int ina230_sample_fetch(const struct device *dev, enum sensor_channel cha
}
}

if ((chan == SENSOR_CHAN_ALL) || (chan == SENSOR_CHAN_VSHUNT)) {
ret = ina23x_reg_read_16(&config->bus, INA230_REG_SHUNT_VOLT, &data->shunt_voltage);
if (ret < 0) {
LOG_ERR("Failed to read shunt voltage");
return ret;
}
}

return 0;
}

static int ina230_attr_set(const struct device *dev, enum sensor_channel chan,
enum sensor_attribute attr, const struct sensor_value *val)
{
const struct ina230_config *config = dev->config;
struct ina230_data *d = dev->data;
uint16_t data = val->val1;
uint16_t new_val;
int ret;

switch (attr) {
case SENSOR_ATTR_CONFIGURATION:
return ina23x_reg_write(&config->bus, INA230_REG_CONFIG, data);
case SENSOR_ATTR_CALIBRATION:
return ina23x_reg_write(&config->bus, INA230_REG_CALIB, data);
case SENSOR_ATTR_FEATURE_MASK:
return ina23x_reg_write(&config->bus, INA230_REG_MASK, data);
new_val = (d->mask & ~INA230_MASK_REG_MASK) | (data & INA230_MASK_REG_MASK);

ret = ina23x_reg_write(&config->bus, INA230_REG_MASK, new_val);
if (!ret) {
d->mask = new_val;
}

return ret;

case SENSOR_ATTR_ALERT:
return ina23x_reg_write(&config->bus, INA230_REG_ALERT, data);
default:
Expand Down Expand Up @@ -185,6 +216,9 @@ static int ina230_calibrate(const struct device *dev)
static int ina230_init(const struct device *dev)
{
const struct ina230_config *const config = dev->config;
#ifdef CONFIG_INA230_TRIGGER
struct ina230_data *data = dev->data;
#endif
int ret;

if (!device_is_ready(config->bus.bus)) {
Expand All @@ -205,25 +239,25 @@ static int ina230_init(const struct device *dev)
}

#ifdef CONFIG_INA230_TRIGGER
if (config->trig_enabled) {
ret = ina230_trigger_mode_init(dev);
if (ret < 0) {
LOG_ERR("Failed to init trigger mode\n");
return ret;
}
ret = ina230_trigger_mode_init(dev);
if (ret < 0) {
LOG_ERR("Failed to init trigger mode\n");
return ret;
}

ret = ina23x_reg_write(&config->bus, INA230_REG_ALERT, config->alert_limit);
if (ret < 0) {
LOG_ERR("Failed to write alert register!");
return ret;
}
ret = ina23x_reg_write(&config->bus, INA230_REG_ALERT, config->alert_limit);
if (ret < 0) {
LOG_ERR("Failed to write alert register!");
return ret;
}

ret = ina23x_reg_write(&config->bus, INA230_REG_MASK, config->mask);
if (ret < 0) {
LOG_ERR("Failed to write mask register!");
return ret;
}
ret = ina23x_reg_write(&config->bus, INA230_REG_MASK, config->mask);
if (ret < 0) {
LOG_ERR("Failed to write mask register!");
return ret;
}

data->mask = config->mask;
#endif /* CONFIG_INA230_TRIGGER */

return 0;
Expand All @@ -241,7 +275,7 @@ static DEVICE_API(sensor, ina230_driver_api) = {

#ifdef CONFIG_INA230_TRIGGER
#define INA230_CFG_IRQ(inst) \
.trig_enabled = true, .mask = DT_INST_PROP(inst, mask), \
.mask = DT_INST_PROP(inst, mask) & INA230_MASK_REG_MASK, \
.alert_limit = DT_INST_PROP(inst, alert_limit), \
.alert_gpio = GPIO_DT_SPEC_INST_GET(inst, alert_gpios)
#else
Expand Down
11 changes: 9 additions & 2 deletions drivers/sensor/ti/ina23x/ina230.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,20 @@ struct ina230_data {
int16_t current;
uint16_t bus_voltage;
uint16_t power;
int16_t shunt_voltage;
uint16_t mask;
#ifdef CONFIG_INA230_TRIGGER
const struct device *gpio;
struct gpio_callback gpio_cb;
struct k_work work;
sensor_trigger_handler_t handler_alert;
const struct sensor_trigger *trig_alert;
sensor_trigger_handler_t handler_cnvr;
const struct sensor_trigger *trig_cnvr;
#if CONFIG_INA230_TRIGGER_OWN_THREAD
struct k_sem sem;
#elif CONFIG_INA230_TRIGGER_GLOBAL_THREAD
struct k_work work;
#endif
#endif /* CONFIG_INA230_TRIGGER */
};

Expand All @@ -56,7 +64,6 @@ struct ina230_config {
uint8_t power_scale;
uint32_t uv_lsb;
#ifdef CONFIG_INA230_TRIGGER
bool trig_enabled;
uint16_t mask;
const struct gpio_dt_spec alert_gpio;
uint16_t alert_limit;
Expand Down
Loading

0 comments on commit 64fb6f0

Please sign in to comment.