1 /*
2 * Copyright (c) 2022 Nordic Semiconductor ASA
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6 #include <zephyr/device.h>
7 #include <zephyr/devicetree.h>
8 #include <zephyr/drivers/adc.h>
9 #include <zephyr/drivers/regulator.h>
10 #include <zephyr/sys/util.h>
11 #include <zephyr/ztest.h>
12
13 #define ADC_INIT(node_id, prop, idx) \
14 ADC_DT_SPEC_GET_BY_IDX(node_id, idx),
15
16 static const struct device *regs[] = {
17 DT_FOREACH_PROP_ELEM_SEP(DT_NODELABEL(resources), regulators, DEVICE_DT_GET_BY_IDX, (,))
18 };
19
20 static const struct adc_dt_spec adc_chs[] = {
21 DT_FOREACH_PROP_ELEM(DT_NODELABEL(resources), io_channels, ADC_INIT)
22 };
23
24 static const int32_t tols[] =
25 DT_PROP(DT_NODELABEL(resources), tolerance_microvolt);
26
27 static const unsigned int adc_avg_count = DT_PROP(DT_NODELABEL(resources),
28 adc_avg_count);
29 static const int32_t set_read_delay_ms = DT_PROP(DT_NODELABEL(resources),
30 set_read_delay_ms);
31
32 static const int32_t min_microvolt = DT_PROP(DT_NODELABEL(resources), min_microvolt);
33 static const int32_t max_microvolt = DT_PROP(DT_NODELABEL(resources), max_microvolt);
34
ZTEST(regulator_voltage,test_output_voltage)35 ZTEST(regulator_voltage, test_output_voltage)
36 {
37 int16_t buf;
38 struct adc_sequence sequence = {
39 .buffer = &buf,
40 .buffer_size = sizeof(buf),
41 };
42
43 for (size_t i = 0U; i < ARRAY_SIZE(regs); i++) {
44 int ret;
45 unsigned int volt_cnt;
46 int32_t volt_uv;
47
48 ret = adc_sequence_init_dt(&adc_chs[i], &sequence);
49 zassert_equal(ret, 0);
50
51 volt_cnt = regulator_count_voltages(regs[i]);
52 zassume_not_equal(volt_cnt, 0U);
53
54 TC_PRINT("Testing %s, %u voltage/s (tolerance: %d uV)\n",
55 regs[i]->name, volt_cnt, tols[i]);
56
57 ret = regulator_enable(regs[i]);
58 zassert_equal(ret, 0);
59
60 for (unsigned int j = 0U; j < volt_cnt; j++) {
61 int32_t val_mv = 0;
62
63 (void)regulator_list_voltage(regs[i], j, &volt_uv);
64 /* Check if voltage is outside user constraints */
65 if (!regulator_is_supported_voltage(regs[i],
66 volt_uv, volt_uv)) {
67 continue;
68 }
69
70 if ((volt_uv < min_microvolt) || (volt_uv > max_microvolt)) {
71 TC_PRINT("Skip: %d uV\n", volt_uv);
72 continue;
73 }
74
75 ret = regulator_set_voltage(regs[i], volt_uv, volt_uv);
76 zassert_equal(ret, 0);
77
78 if (set_read_delay_ms > 0) {
79 k_msleep(set_read_delay_ms);
80 }
81
82 for (unsigned int k = 0U; k < adc_avg_count; k++) {
83 ret = adc_read_dt(&adc_chs[i], &sequence);
84 zassert_equal(ret, 0);
85
86 val_mv += buf;
87 }
88
89 val_mv /= (int32_t)adc_avg_count;
90
91 ret = adc_raw_to_millivolts_dt(&adc_chs[i], &val_mv);
92 zassert_equal(ret, 0);
93
94 TC_PRINT("Set: %d, read: %d uV\n", volt_uv,
95 val_mv * 1000);
96
97 zassert_between_inclusive(val_mv * 1000,
98 volt_uv - tols[i],
99 volt_uv + tols[i]);
100 }
101
102 ret = regulator_disable(regs[i]);
103 zassert_equal(ret, 0);
104 }
105 }
106
setup(void)107 void *setup(void)
108 {
109 zassert_equal(ARRAY_SIZE(regs), ARRAY_SIZE(adc_chs));
110 zassert_equal(ARRAY_SIZE(regs), ARRAY_SIZE(tols));
111
112 for (size_t i = 0U; i < ARRAY_SIZE(regs); i++) {
113 zassert_true(device_is_ready(regs[i]));
114 zassert_true(adc_is_ready_dt(&adc_chs[i]));
115 zassert_equal(adc_channel_setup_dt(&adc_chs[i]), 0);
116 }
117
118 return NULL;
119 }
120
121 ZTEST_SUITE(regulator_voltage, NULL, setup, NULL, NULL, NULL);
122