Skip to content

Commit 3590467

Browse files
committed
drivers: current_sense_amplifier: add zero-current-voltage binding
some current sense amplifiers have a non zero offset voltage that correlates to zero current. adding this offset voltage binding allows the driver to be used with this type of circuitry. Signed-off-by: Brandon Allen <brandon.allen@exacttechnology.com>
1 parent 7abda99 commit 3590467

File tree

6 files changed

+60
-1
lines changed

6 files changed

+60
-1
lines changed

drivers/sensor/current_amp/current_amp.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,10 @@ static int current_init(const struct device *dev)
173173
\
174174
SENSOR_DEVICE_DT_INST_DEFINE(inst, &current_init, PM_DEVICE_DT_INST_GET(inst), \
175175
&current_amp_##inst##_data, &current_amp_##inst##_config, \
176-
POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &current_api);
176+
POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &current_api); \
177+
\
178+
BUILD_ASSERT((DT_INST_PROP(inst, zero_current_voltage_mv) == 0) || \
179+
(DT_INST_PROP(inst, sense_resistor_milli_ohms) == 1), \
180+
"zero_current_voltage_mv requires sense_resistor_milli_ohms == 1");
177181

178182
DT_INST_FOREACH_STATUS_OKAY(CURRENT_SENSE_AMPLIFIER_INIT)

dts/bindings/iio/afe/current-sense-amplifier.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,18 @@ properties:
3838
description: |
3939
Amplifier gain divider. The default is <1>. The maximum value is <65535>.
4040
41+
zero-current-voltage-mv:
42+
type: int
43+
default: 0
44+
description: |
45+
The zero-current voltage in millivolts. Defaults to <0>, with a range of <-32768> to <32767>.
46+
47+
Some current sense amplifiers output a voltage proportional to current, independent of a
48+
current sense resistor (e.g., Hall-effect current sensors). These sensors often have a
49+
nonzero offset voltage that corresponds to zero current.
50+
51+
To use this driver with such sensors, `sense-resistor-milli-ohms` should be set to 1.
52+
4153
power-gpios:
4254
type: phandle-array
4355
description: |

include/zephyr/drivers/adc/current_sense_amplifier.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ struct current_sense_amplifier_dt_spec {
1717
uint16_t sense_gain_mult;
1818
uint16_t sense_gain_div;
1919
uint16_t noise_threshold;
20+
int16_t zero_current_voltage_mv;
2021
bool enable_calibration;
2122
};
2223

@@ -38,6 +39,7 @@ struct current_sense_amplifier_dt_spec {
3839
.sense_gain_mult = DT_PROP(node_id, sense_gain_mult), \
3940
.sense_gain_div = DT_PROP(node_id, sense_gain_div), \
4041
.noise_threshold = DT_PROP(node_id, zephyr_noise_threshold), \
42+
.zero_current_voltage_mv = DT_PROP(node_id, zero_current_voltage_mv), \
4143
.enable_calibration = DT_PROP_OR(node_id, enable_calibration, false), \
4244
}
4345

@@ -58,6 +60,7 @@ current_sense_amplifier_scale_dt(const struct current_sense_amplifier_dt_spec *s
5860
/* (INT32_MAX * 1000 * UINT16_MAX) < INT64_MAX
5961
* Therefore all multiplications can be done before divisions, preserving resolution.
6062
*/
63+
tmp = tmp - spec->zero_current_voltage_mv;
6164
tmp = tmp * 1000 * spec->sense_gain_div / spec->sense_milli_ohms / spec->sense_gain_mult;
6265

6366
*v_to_i = (int32_t)tmp;

tests/drivers/adc/adc_rescale/boards/native_sim.overlay

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@
2727
sense-gain-mult = <100>;
2828
};
2929

30+
sensor3: tmcs1108A2B {
31+
compatible = "current-sense-amplifier";
32+
io-channels = <&adc0 2>;
33+
sense-resistor-milli-ohms = <1>;
34+
sense-gain-mult = <100>;
35+
zero-current-voltage-mv = <1650>;
36+
};
37+
3038
adc0: adc {
3139
compatible = "zephyr,adc-emul";
3240
nchannels = <3>;

tests/drivers/adc/adc_rescale/src/main.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define ADC_TEST_NODE_0 DT_NODELABEL(sensor0)
1919
#define ADC_TEST_NODE_1 DT_NODELABEL(sensor1)
2020
#define ADC_TEST_NODE_2 DT_NODELABEL(sensor2)
21+
#define ADC_TEST_NODE_3 DT_NODELABEL(sensor3)
2122

2223
/**
2324
* @brief Get ADC emulated device
@@ -169,6 +170,36 @@ ZTEST_USER(adc_rescale, test_adc_current_sense_amplifier)
169170
zassert_true(test_task_current_sense_amplifier() == TC_PASS);
170171
}
171172

173+
ZTEST(adc_rescale, test_adc_current_sense_amplifier_with_offset)
174+
{
175+
int32_t v_to_i;
176+
const struct current_sense_amplifier_dt_spec amplifier_spec =
177+
CURRENT_SENSE_AMPLIFIER_DT_SPEC_GET(ADC_TEST_NODE_3);
178+
179+
/**
180+
* test a voltage that corresponds to 0 mA
181+
*/
182+
v_to_i = amplifier_spec.zero_current_voltage_mv;
183+
current_sense_amplifier_scale_dt(&amplifier_spec, &v_to_i);
184+
zassert_equal(v_to_i, 0);
185+
186+
/**
187+
* test a voltage that corresponds to 200 mA
188+
*/
189+
v_to_i = (200 * amplifier_spec.sense_gain_mult / amplifier_spec.sense_gain_div) / 1000;
190+
v_to_i = v_to_i + amplifier_spec.zero_current_voltage_mv;
191+
current_sense_amplifier_scale_dt(&amplifier_spec, &v_to_i);
192+
zassert_equal(v_to_i, 200);
193+
194+
/**
195+
* test a voltage that corresponds to -1100 mA
196+
*/
197+
v_to_i = (-1100 * amplifier_spec.sense_gain_mult / amplifier_spec.sense_gain_div) / 1000;
198+
v_to_i = v_to_i + amplifier_spec.zero_current_voltage_mv;
199+
current_sense_amplifier_scale_dt(&amplifier_spec, &v_to_i);
200+
zassert_equal(v_to_i, -1100);
201+
}
202+
172203
void *adc_rescale_setup(void)
173204
{
174205
k_object_access_grant(get_adc_device(), k_current_get());

tests/drivers/build_all/sensor/adc.dtsi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ test_current: current_amp {
3434
sense-resistor-milli-ohms = <1>;
3535
sense-gain-mult = <1>;
3636
sense-gain-div = <1>;
37+
zero-current-voltage-mv = <0>;
3738
};
3839

3940
test_composite_fuel_gauge: composite_fuel_gauge {

0 commit comments

Comments
 (0)