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