blob: bb14a6add95f9a27982d86e3c44d5b47fe36ba24 [file] [log] [blame]
Kevin Zengc24e3322021-05-04 20:20:53 -07001// 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 "gtest/gtest.h"
17
18namespace pw {
19namespace analog {
20namespace {
21
22using namespace std::chrono_literals;
23
24constexpr int32_t kLimitsMax = 4096;
25constexpr int32_t kLimitsMin = 0;
26constexpr int32_t kReferenceMaxVoltageUv = 1800000;
27constexpr int32_t kReferenceMinVoltageUv = 0;
28constexpr chrono::SystemClock::duration kTimeout = 1ms;
29
30constexpr int32_t kBipolarLimitsMax = 4096;
31constexpr int32_t kBipolarLimitsMin = -4096;
32constexpr int32_t kBipolarReferenceMaxVoltageUv = 1800000;
33constexpr int32_t kBipolarReferenceMinVoltageUv = -1800000;
34
35constexpr int32_t kCornerLimitsMax = std::numeric_limits<int32_t>::max();
36constexpr int32_t kCornerLimitsMin = std::numeric_limits<int32_t>::min();
37constexpr int32_t kCornerReferenceMaxVoltageUv =
38 std::numeric_limits<int32_t>::max();
39constexpr int32_t kCornerReferenceMinVoltageUv =
40 std::numeric_limits<int32_t>::min();
41
42constexpr int32_t kInvertedLimitsMax = std::numeric_limits<int32_t>::max();
43constexpr int32_t kInvertedLimitsMin = std::numeric_limits<int32_t>::min();
44constexpr int32_t kInvertedReferenceMaxVoltageUv =
45 std::numeric_limits<int32_t>::min();
46constexpr int32_t kInvertedReferenceMinVoltageUv =
47 std::numeric_limits<int32_t>::max();
48
Rob Mohr4c05a062021-05-27 10:28:54 -070049// Fake voltage input that's used for testing.
Kevin Zengc24e3322021-05-04 20:20:53 -070050class TestMicrovoltInput : public MicrovoltInput {
51 public:
52 constexpr explicit TestMicrovoltInput(AnalogInput::Limits limits,
53 MicrovoltInput::References reference)
54 : sample_(0), limits_(limits), reference_(reference) {}
55
56 void SetSampleValue(int32_t sample) { sample_ = sample; }
57
58 private:
59 Result<int32_t> TryReadUntil(chrono::SystemClock::time_point) override {
60 return sample_;
61 }
62
63 Limits GetLimits() const override { return limits_; }
64 References GetReferences() const override { return reference_; }
65
66 uint32_t sample_;
67 const Limits limits_;
68 const References reference_;
69};
70
71TEST(MicrovoltInputTest, Construction) {
72 TestMicrovoltInput voltage_input =
73 TestMicrovoltInput({.min = kLimitsMin, .max = kLimitsMax},
74 {.max_voltage_uv = kReferenceMaxVoltageUv,
75 .min_voltage_uv = kReferenceMinVoltageUv});
76}
77
78TEST(MicrovoltInputTest, ReadMicrovoltsWithSampleAtMin) {
79 TestMicrovoltInput voltage_input =
80 TestMicrovoltInput({.min = kLimitsMin, .max = kLimitsMax},
81 {.max_voltage_uv = kReferenceMaxVoltageUv,
82 .min_voltage_uv = kReferenceMinVoltageUv});
83 voltage_input.SetSampleValue(kLimitsMin);
84
85 Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
86 ASSERT_TRUE(result.status().ok());
87
88 EXPECT_EQ(result.value(), 0);
89}
90
91TEST(MicrovoltInputTest, ReadMicrovoltsWithSampleAtMax) {
92 TestMicrovoltInput voltage_input =
93 TestMicrovoltInput({.min = kLimitsMin, .max = kLimitsMax},
94 {.max_voltage_uv = kReferenceMaxVoltageUv,
95 .min_voltage_uv = kReferenceMinVoltageUv});
96 voltage_input.SetSampleValue(kLimitsMax);
97
98 Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
99 ASSERT_TRUE(result.status().ok());
100
101 EXPECT_EQ(result.value(), kReferenceMaxVoltageUv);
102}
103
104TEST(MicrovoltInputTest, ReadMicrovoltsWithSampleAtHalf) {
105 TestMicrovoltInput voltage_input =
106 TestMicrovoltInput({.min = kLimitsMin, .max = kLimitsMax},
107 {.max_voltage_uv = kReferenceMaxVoltageUv,
108 .min_voltage_uv = kReferenceMinVoltageUv});
109 voltage_input.SetSampleValue(kLimitsMax / 2);
110
111 Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
112 ASSERT_TRUE(result.status().ok());
113
114 EXPECT_EQ(result.value(), kReferenceMaxVoltageUv / 2);
115}
116
117TEST(MicrovoltInputTest, ReadMicrovoltsWithBipolarAdcAtZero) {
118 TestMicrovoltInput voltage_input =
119 TestMicrovoltInput({.min = kBipolarLimitsMin, .max = kBipolarLimitsMax},
120 {.max_voltage_uv = kBipolarReferenceMaxVoltageUv,
121 .min_voltage_uv = kBipolarReferenceMinVoltageUv});
122 voltage_input.SetSampleValue(0);
123
124 Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
125 ASSERT_TRUE(result.status().ok());
126
127 EXPECT_EQ(result.value(), 0);
128}
129
130TEST(MicrovoltInputTest, ReadMicrovoltsWithBipolarAdcAtMin) {
131 TestMicrovoltInput voltage_input =
132 TestMicrovoltInput({.min = kBipolarLimitsMin, .max = kBipolarLimitsMax},
133 {.max_voltage_uv = kBipolarReferenceMaxVoltageUv,
134 .min_voltage_uv = kBipolarReferenceMinVoltageUv});
135 voltage_input.SetSampleValue(kBipolarLimitsMin);
136
137 Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
138 ASSERT_TRUE(result.status().ok());
139
140 EXPECT_EQ(result.value(), kBipolarReferenceMinVoltageUv);
141}
142
143TEST(MicrovoltInputTest, ReadMicrovoltsWithBipolarAdcAtMax) {
144 TestMicrovoltInput voltage_input =
145 TestMicrovoltInput({.min = kBipolarLimitsMin, .max = kBipolarLimitsMax},
146 {.max_voltage_uv = kBipolarReferenceMaxVoltageUv,
147 .min_voltage_uv = kBipolarReferenceMinVoltageUv});
148 voltage_input.SetSampleValue(kBipolarLimitsMax);
149
150 Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
151 ASSERT_TRUE(result.status().ok());
152
153 EXPECT_EQ(result.value(), kBipolarReferenceMaxVoltageUv);
154}
155
156TEST(MicrovoltInputTest, ReadMicrovoltsWithBipolarAdcAtUpperHalf) {
157 TestMicrovoltInput voltage_input =
158 TestMicrovoltInput({.min = kBipolarLimitsMin, .max = kBipolarLimitsMax},
159 {.max_voltage_uv = kBipolarReferenceMaxVoltageUv,
160 .min_voltage_uv = kBipolarReferenceMinVoltageUv});
161 voltage_input.SetSampleValue(kBipolarLimitsMax / 2);
162
163 Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
164 ASSERT_TRUE(result.status().ok());
165
166 EXPECT_EQ(result.value(), kBipolarReferenceMaxVoltageUv / 2);
167}
168
169TEST(MicrovoltInputTest, ReadMicrovoltsWithBipolarAdcAtLowerHalf) {
170 TestMicrovoltInput voltage_input =
171 TestMicrovoltInput({.min = kBipolarLimitsMin, .max = kBipolarLimitsMax},
172 {.max_voltage_uv = kBipolarReferenceMaxVoltageUv,
173 .min_voltage_uv = kBipolarReferenceMinVoltageUv});
174 voltage_input.SetSampleValue(kBipolarLimitsMin / 2);
175
176 Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
177 ASSERT_TRUE(result.status().ok());
178
179 EXPECT_EQ(result.value(), kBipolarReferenceMinVoltageUv / 2);
180}
181
182TEST(MicrovoltInputTest, ReadMicrovoltsWithBipolarReferenceAtZero) {
183 TestMicrovoltInput voltage_input =
184 TestMicrovoltInput({.min = kLimitsMin, .max = kLimitsMax},
185 {.max_voltage_uv = kBipolarReferenceMaxVoltageUv,
186 .min_voltage_uv = kBipolarReferenceMinVoltageUv});
187 voltage_input.SetSampleValue(0);
188
189 Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
190 ASSERT_TRUE(result.status().ok());
191
192 EXPECT_EQ(result.value(), kBipolarReferenceMinVoltageUv);
193}
194
195TEST(MicrovoltInputTest, ReadMicrovoltsWithBipolarReferenceAtMin) {
196 TestMicrovoltInput voltage_input =
197 TestMicrovoltInput({.min = kLimitsMin, .max = kLimitsMax},
198 {.max_voltage_uv = kBipolarReferenceMaxVoltageUv,
199 .min_voltage_uv = kBipolarReferenceMinVoltageUv});
200 voltage_input.SetSampleValue(kLimitsMin);
201
202 Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
203 ASSERT_TRUE(result.status().ok());
204
205 EXPECT_EQ(result.value(), kBipolarReferenceMinVoltageUv);
206}
207
208TEST(MicrovoltInputTest, ReadMicrovoltsWithBipolarReferenceAtMax) {
209 TestMicrovoltInput voltage_input =
210 TestMicrovoltInput({.min = kLimitsMin, .max = kLimitsMax},
211 {.max_voltage_uv = kBipolarReferenceMaxVoltageUv,
212 .min_voltage_uv = kBipolarReferenceMinVoltageUv});
213 voltage_input.SetSampleValue(kLimitsMax);
214
215 Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
216 ASSERT_TRUE(result.status().ok());
217
218 EXPECT_EQ(result.value(), kBipolarReferenceMaxVoltageUv);
219}
220
221TEST(MicrovoltInputTest, ReadMicrovoltsWithBipolarReferenceAtHalf) {
222 TestMicrovoltInput voltage_input =
223 TestMicrovoltInput({.min = kLimitsMin, .max = kLimitsMax},
224 {.max_voltage_uv = kBipolarReferenceMaxVoltageUv,
225 .min_voltage_uv = kBipolarReferenceMinVoltageUv});
226 voltage_input.SetSampleValue(kLimitsMax / 2);
227
228 Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
229 ASSERT_TRUE(result.status().ok());
230
231 EXPECT_EQ(result.value(), 0);
232}
233
234TEST(MicrovoltInputTest, ReadMicrovoltsWithSampleAtMinCornerCase) {
235 TestMicrovoltInput voltage_input =
236 TestMicrovoltInput({.min = kCornerLimitsMin, .max = kCornerLimitsMax},
237 {.max_voltage_uv = kCornerReferenceMaxVoltageUv,
238 .min_voltage_uv = kCornerReferenceMinVoltageUv});
239 voltage_input.SetSampleValue(kCornerLimitsMin);
240
241 Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
242 ASSERT_TRUE(result.status().ok());
243
244 EXPECT_EQ(result.value(), kCornerReferenceMinVoltageUv);
245}
246
247TEST(MicrovoltInputTest, ReadMicrovoltsWithSampleAtMaxCornerCase) {
248 TestMicrovoltInput voltage_input =
249 TestMicrovoltInput({.min = kCornerLimitsMin, .max = kCornerLimitsMax},
250 {.max_voltage_uv = kCornerReferenceMaxVoltageUv,
251 .min_voltage_uv = kCornerReferenceMinVoltageUv});
252 voltage_input.SetSampleValue(kCornerLimitsMax);
253
254 Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
255 ASSERT_TRUE(result.status().ok());
256
257 EXPECT_EQ(result.value(), kCornerReferenceMaxVoltageUv);
258}
259
260TEST(MicrovoltInputTest, ReadMicrovoltsWithInvertedReferenceAtMax) {
261 TestMicrovoltInput voltage_input =
262 TestMicrovoltInput({.min = kInvertedLimitsMin, .max = kInvertedLimitsMax},
263 {.max_voltage_uv = kInvertedReferenceMaxVoltageUv,
264 .min_voltage_uv = kInvertedReferenceMinVoltageUv});
265 voltage_input.SetSampleValue(kInvertedLimitsMax);
266
267 Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
268 ASSERT_TRUE(result.status().ok());
269
270 EXPECT_EQ(result.value(), kInvertedReferenceMaxVoltageUv);
271}
272
273TEST(MicrovoltInputTest, ReadMicrovoltsWithInvertedReferenceAtMin) {
274 TestMicrovoltInput voltage_input =
275 TestMicrovoltInput({.min = kInvertedLimitsMin, .max = kInvertedLimitsMax},
276 {.max_voltage_uv = kInvertedReferenceMaxVoltageUv,
277 .min_voltage_uv = kInvertedReferenceMinVoltageUv});
278 voltage_input.SetSampleValue(kInvertedLimitsMin);
279
280 Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
281 ASSERT_TRUE(result.status().ok());
282
283 EXPECT_EQ(result.value(), kInvertedReferenceMinVoltageUv);
284}
285} // namespace
286} // namespace analog
287} // namespace pw