xref: /aosp_15_r20/external/pigweed/pw_analog/microvolt_input_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2021 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 #include "pw_analog/microvolt_input.h"
15 
16 #include "pw_unit_test/framework.h"
17 
18 namespace pw {
19 namespace analog {
20 namespace {
21 
22 using namespace std::chrono_literals;
23 
24 constexpr int32_t kLimitsMax = 4096;
25 constexpr int32_t kLimitsMin = 0;
26 constexpr int32_t kReferenceMaxVoltageUv = 1800000;
27 constexpr int32_t kReferenceMinVoltageUv = 0;
28 constexpr chrono::SystemClock::duration kTimeout =
29     chrono::SystemClock::for_at_least(1ms);
30 
31 constexpr int32_t kBipolarLimitsMax = 4096;
32 constexpr int32_t kBipolarLimitsMin = -4096;
33 constexpr int32_t kBipolarReferenceMaxVoltageUv = 1800000;
34 constexpr int32_t kBipolarReferenceMinVoltageUv = -1800000;
35 
36 constexpr int32_t kCornerLimitsMax = std::numeric_limits<int32_t>::max();
37 constexpr int32_t kCornerLimitsMin = std::numeric_limits<int32_t>::min();
38 constexpr int32_t kCornerReferenceMaxVoltageUv =
39     std::numeric_limits<int32_t>::max();
40 constexpr int32_t kCornerReferenceMinVoltageUv =
41     std::numeric_limits<int32_t>::min();
42 
43 constexpr int32_t kInvertedLimitsMax = std::numeric_limits<int32_t>::min();
44 constexpr int32_t kInvertedLimitsMin = std::numeric_limits<int32_t>::max();
45 constexpr int32_t kInvertedReferenceMaxVoltageUv =
46     std::numeric_limits<int32_t>::min();
47 constexpr int32_t kInvertedReferenceMinVoltageUv =
48     std::numeric_limits<int32_t>::max();
49 
50 // Fake voltage input that's used for testing.
51 class TestMicrovoltInput : public MicrovoltInput {
52  public:
TestMicrovoltInput(AnalogInput::Limits limits,MicrovoltInput::References reference)53   constexpr explicit TestMicrovoltInput(AnalogInput::Limits limits,
54                                         MicrovoltInput::References reference)
55       : sample_(0), limits_(limits), reference_(reference) {}
56 
SetSampleValue(int32_t sample)57   void SetSampleValue(int32_t sample) { sample_ = sample; }
58 
59  private:
TryReadUntil(chrono::SystemClock::time_point)60   Result<int32_t> TryReadUntil(chrono::SystemClock::time_point) override {
61     return sample_;
62   }
63 
GetLimits() const64   Limits GetLimits() const override { return limits_; }
GetReferences() const65   References GetReferences() const override { return reference_; }
66 
67   uint32_t sample_;
68   const Limits limits_;
69   const References reference_;
70 };
71 
TEST(MicrovoltInputTest,Construction)72 TEST(MicrovoltInputTest, Construction) {
73   TestMicrovoltInput voltage_input =
74       TestMicrovoltInput({.min = kLimitsMin, .max = kLimitsMax},
75                          {.max_voltage_uv = kReferenceMaxVoltageUv,
76                           .min_voltage_uv = kReferenceMinVoltageUv});
77 }
78 
TEST(MicrovoltInputTest,ReadMicrovoltsWithSampleAtMin)79 TEST(MicrovoltInputTest, ReadMicrovoltsWithSampleAtMin) {
80   TestMicrovoltInput voltage_input =
81       TestMicrovoltInput({.min = kLimitsMin, .max = kLimitsMax},
82                          {.max_voltage_uv = kReferenceMaxVoltageUv,
83                           .min_voltage_uv = kReferenceMinVoltageUv});
84   voltage_input.SetSampleValue(kLimitsMin);
85 
86   Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
87   ASSERT_TRUE(result.status().ok());
88 
89   EXPECT_EQ(result.value(), 0);
90 }
91 
TEST(MicrovoltInputTest,ReadMicrovoltsWithSampleAtMax)92 TEST(MicrovoltInputTest, ReadMicrovoltsWithSampleAtMax) {
93   TestMicrovoltInput voltage_input =
94       TestMicrovoltInput({.min = kLimitsMin, .max = kLimitsMax},
95                          {.max_voltage_uv = kReferenceMaxVoltageUv,
96                           .min_voltage_uv = kReferenceMinVoltageUv});
97   voltage_input.SetSampleValue(kLimitsMax);
98 
99   Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
100   ASSERT_TRUE(result.status().ok());
101 
102   EXPECT_EQ(result.value(), kReferenceMaxVoltageUv);
103 }
104 
TEST(MicrovoltInputTest,ReadMicrovoltsWithSampleAtHalf)105 TEST(MicrovoltInputTest, ReadMicrovoltsWithSampleAtHalf) {
106   TestMicrovoltInput voltage_input =
107       TestMicrovoltInput({.min = kLimitsMin, .max = kLimitsMax},
108                          {.max_voltage_uv = kReferenceMaxVoltageUv,
109                           .min_voltage_uv = kReferenceMinVoltageUv});
110   voltage_input.SetSampleValue(kLimitsMax / 2);
111 
112   Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
113   ASSERT_TRUE(result.status().ok());
114 
115   EXPECT_EQ(result.value(), kReferenceMaxVoltageUv / 2);
116 }
117 
TEST(MicrovoltInputTest,ReadMicrovoltsWithBipolarAdcAtZero)118 TEST(MicrovoltInputTest, ReadMicrovoltsWithBipolarAdcAtZero) {
119   TestMicrovoltInput voltage_input =
120       TestMicrovoltInput({.min = kBipolarLimitsMin, .max = kBipolarLimitsMax},
121                          {.max_voltage_uv = kBipolarReferenceMaxVoltageUv,
122                           .min_voltage_uv = kBipolarReferenceMinVoltageUv});
123   voltage_input.SetSampleValue(0);
124 
125   Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
126   ASSERT_TRUE(result.status().ok());
127 
128   EXPECT_EQ(result.value(), 0);
129 }
130 
TEST(MicrovoltInputTest,ReadMicrovoltsWithBipolarAdcAtMin)131 TEST(MicrovoltInputTest, ReadMicrovoltsWithBipolarAdcAtMin) {
132   TestMicrovoltInput voltage_input =
133       TestMicrovoltInput({.min = kBipolarLimitsMin, .max = kBipolarLimitsMax},
134                          {.max_voltage_uv = kBipolarReferenceMaxVoltageUv,
135                           .min_voltage_uv = kBipolarReferenceMinVoltageUv});
136   voltage_input.SetSampleValue(kBipolarLimitsMin);
137 
138   Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
139   ASSERT_TRUE(result.status().ok());
140 
141   EXPECT_EQ(result.value(), kBipolarReferenceMinVoltageUv);
142 }
143 
TEST(MicrovoltInputTest,ReadMicrovoltsWithBipolarAdcAtMax)144 TEST(MicrovoltInputTest, ReadMicrovoltsWithBipolarAdcAtMax) {
145   TestMicrovoltInput voltage_input =
146       TestMicrovoltInput({.min = kBipolarLimitsMin, .max = kBipolarLimitsMax},
147                          {.max_voltage_uv = kBipolarReferenceMaxVoltageUv,
148                           .min_voltage_uv = kBipolarReferenceMinVoltageUv});
149   voltage_input.SetSampleValue(kBipolarLimitsMax);
150 
151   Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
152   ASSERT_TRUE(result.status().ok());
153 
154   EXPECT_EQ(result.value(), kBipolarReferenceMaxVoltageUv);
155 }
156 
TEST(MicrovoltInputTest,ReadMicrovoltsWithBipolarAdcAtUpperHalf)157 TEST(MicrovoltInputTest, ReadMicrovoltsWithBipolarAdcAtUpperHalf) {
158   TestMicrovoltInput voltage_input =
159       TestMicrovoltInput({.min = kBipolarLimitsMin, .max = kBipolarLimitsMax},
160                          {.max_voltage_uv = kBipolarReferenceMaxVoltageUv,
161                           .min_voltage_uv = kBipolarReferenceMinVoltageUv});
162   voltage_input.SetSampleValue(kBipolarLimitsMax / 2);
163 
164   Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
165   ASSERT_TRUE(result.status().ok());
166 
167   EXPECT_EQ(result.value(), kBipolarReferenceMaxVoltageUv / 2);
168 }
169 
TEST(MicrovoltInputTest,ReadMicrovoltsWithBipolarAdcAtLowerHalf)170 TEST(MicrovoltInputTest, ReadMicrovoltsWithBipolarAdcAtLowerHalf) {
171   TestMicrovoltInput voltage_input =
172       TestMicrovoltInput({.min = kBipolarLimitsMin, .max = kBipolarLimitsMax},
173                          {.max_voltage_uv = kBipolarReferenceMaxVoltageUv,
174                           .min_voltage_uv = kBipolarReferenceMinVoltageUv});
175   voltage_input.SetSampleValue(kBipolarLimitsMin / 2);
176 
177   Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
178   ASSERT_TRUE(result.status().ok());
179 
180   EXPECT_EQ(result.value(), kBipolarReferenceMinVoltageUv / 2);
181 }
182 
TEST(MicrovoltInputTest,ReadMicrovoltsWithBipolarReferenceAtZero)183 TEST(MicrovoltInputTest, ReadMicrovoltsWithBipolarReferenceAtZero) {
184   TestMicrovoltInput voltage_input =
185       TestMicrovoltInput({.min = kLimitsMin, .max = kLimitsMax},
186                          {.max_voltage_uv = kBipolarReferenceMaxVoltageUv,
187                           .min_voltage_uv = kBipolarReferenceMinVoltageUv});
188   voltage_input.SetSampleValue(0);
189 
190   Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
191   ASSERT_TRUE(result.status().ok());
192 
193   EXPECT_EQ(result.value(), kBipolarReferenceMinVoltageUv);
194 }
195 
TEST(MicrovoltInputTest,ReadMicrovoltsWithBipolarReferenceAtMin)196 TEST(MicrovoltInputTest, ReadMicrovoltsWithBipolarReferenceAtMin) {
197   TestMicrovoltInput voltage_input =
198       TestMicrovoltInput({.min = kLimitsMin, .max = kLimitsMax},
199                          {.max_voltage_uv = kBipolarReferenceMaxVoltageUv,
200                           .min_voltage_uv = kBipolarReferenceMinVoltageUv});
201   voltage_input.SetSampleValue(kLimitsMin);
202 
203   Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
204   ASSERT_TRUE(result.status().ok());
205 
206   EXPECT_EQ(result.value(), kBipolarReferenceMinVoltageUv);
207 }
208 
TEST(MicrovoltInputTest,ReadMicrovoltsWithBipolarReferenceAtMax)209 TEST(MicrovoltInputTest, ReadMicrovoltsWithBipolarReferenceAtMax) {
210   TestMicrovoltInput voltage_input =
211       TestMicrovoltInput({.min = kLimitsMin, .max = kLimitsMax},
212                          {.max_voltage_uv = kBipolarReferenceMaxVoltageUv,
213                           .min_voltage_uv = kBipolarReferenceMinVoltageUv});
214   voltage_input.SetSampleValue(kLimitsMax);
215 
216   Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
217   ASSERT_TRUE(result.status().ok());
218 
219   EXPECT_EQ(result.value(), kBipolarReferenceMaxVoltageUv);
220 }
221 
TEST(MicrovoltInputTest,ReadMicrovoltsWithBipolarReferenceAtHalf)222 TEST(MicrovoltInputTest, ReadMicrovoltsWithBipolarReferenceAtHalf) {
223   TestMicrovoltInput voltage_input =
224       TestMicrovoltInput({.min = kLimitsMin, .max = kLimitsMax},
225                          {.max_voltage_uv = kBipolarReferenceMaxVoltageUv,
226                           .min_voltage_uv = kBipolarReferenceMinVoltageUv});
227   voltage_input.SetSampleValue(kLimitsMax / 2);
228 
229   Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
230   ASSERT_TRUE(result.status().ok());
231 
232   EXPECT_EQ(result.value(), 0);
233 }
234 
TEST(MicrovoltInputTest,ReadMicrovoltsWithSampleAtMinCornerCase)235 TEST(MicrovoltInputTest, ReadMicrovoltsWithSampleAtMinCornerCase) {
236   TestMicrovoltInput voltage_input =
237       TestMicrovoltInput({.min = kCornerLimitsMin, .max = kCornerLimitsMax},
238                          {.max_voltage_uv = kCornerReferenceMaxVoltageUv,
239                           .min_voltage_uv = kCornerReferenceMinVoltageUv});
240   voltage_input.SetSampleValue(kCornerLimitsMin);
241 
242   Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
243   ASSERT_EQ(result.status(), pw::Status::Internal());
244 }
245 
TEST(MicrovoltInputTest,ReadMicrovoltsWithSampleAtMaxCornerCase)246 TEST(MicrovoltInputTest, ReadMicrovoltsWithSampleAtMaxCornerCase) {
247   TestMicrovoltInput voltage_input =
248       TestMicrovoltInput({.min = kCornerLimitsMin, .max = kCornerLimitsMax},
249                          {.max_voltage_uv = kCornerReferenceMaxVoltageUv,
250                           .min_voltage_uv = kCornerReferenceMinVoltageUv});
251   voltage_input.SetSampleValue(kCornerLimitsMax);
252 
253   Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
254   ASSERT_EQ(result.status(), pw::Status::Internal());
255 }
256 
TEST(MicrovoltInputTest,ReadMicrovoltsWithInvertedReferenceAtMax)257 TEST(MicrovoltInputTest, ReadMicrovoltsWithInvertedReferenceAtMax) {
258   TestMicrovoltInput voltage_input =
259       TestMicrovoltInput({.min = kInvertedLimitsMin, .max = kInvertedLimitsMax},
260                          {.max_voltage_uv = kInvertedReferenceMaxVoltageUv,
261                           .min_voltage_uv = kInvertedReferenceMinVoltageUv});
262   voltage_input.SetSampleValue(kInvertedLimitsMax);
263 
264   Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
265   ASSERT_EQ(result.status(), pw::Status::Internal());
266 }
267 
TEST(MicrovoltInputTest,ReadMicrovoltsWithInvertedReferenceAtMin)268 TEST(MicrovoltInputTest, ReadMicrovoltsWithInvertedReferenceAtMin) {
269   TestMicrovoltInput voltage_input =
270       TestMicrovoltInput({.min = kInvertedLimitsMin, .max = kInvertedLimitsMax},
271                          {.max_voltage_uv = kInvertedReferenceMaxVoltageUv,
272                           .min_voltage_uv = kInvertedReferenceMinVoltageUv});
273   voltage_input.SetSampleValue(kInvertedLimitsMin);
274 
275   Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
276   ASSERT_EQ(result.status(), pw::Status::Internal());
277 }
278 
279 }  // namespace
280 }  // namespace analog
281 }  // namespace pw
282