• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "gtest/gtest.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 = 1ms;
29 
30 constexpr int32_t kBipolarLimitsMax = 4096;
31 constexpr int32_t kBipolarLimitsMin = -4096;
32 constexpr int32_t kBipolarReferenceMaxVoltageUv = 1800000;
33 constexpr int32_t kBipolarReferenceMinVoltageUv = -1800000;
34 
35 constexpr int32_t kCornerLimitsMax = std::numeric_limits<int32_t>::max();
36 constexpr int32_t kCornerLimitsMin = std::numeric_limits<int32_t>::min();
37 constexpr int32_t kCornerReferenceMaxVoltageUv =
38     std::numeric_limits<int32_t>::max();
39 constexpr int32_t kCornerReferenceMinVoltageUv =
40     std::numeric_limits<int32_t>::min();
41 
42 constexpr int32_t kInvertedLimitsMax = std::numeric_limits<int32_t>::min();
43 constexpr int32_t kInvertedLimitsMin = std::numeric_limits<int32_t>::max();
44 constexpr int32_t kInvertedReferenceMaxVoltageUv =
45     std::numeric_limits<int32_t>::min();
46 constexpr int32_t kInvertedReferenceMinVoltageUv =
47     std::numeric_limits<int32_t>::max();
48 
49 // Fake voltage input that's used for testing.
50 class TestMicrovoltInput : public MicrovoltInput {
51  public:
TestMicrovoltInput(AnalogInput::Limits limits,MicrovoltInput::References reference)52   constexpr explicit TestMicrovoltInput(AnalogInput::Limits limits,
53                                         MicrovoltInput::References reference)
54       : sample_(0), limits_(limits), reference_(reference) {}
55 
SetSampleValue(int32_t sample)56   void SetSampleValue(int32_t sample) { sample_ = sample; }
57 
58  private:
TryReadUntil(chrono::SystemClock::time_point)59   Result<int32_t> TryReadUntil(chrono::SystemClock::time_point) override {
60     return sample_;
61   }
62 
GetLimits() const63   Limits GetLimits() const override { return limits_; }
GetReferences() const64   References GetReferences() const override { return reference_; }
65 
66   uint32_t sample_;
67   const Limits limits_;
68   const References reference_;
69 };
70 
TEST(MicrovoltInputTest,Construction)71 TEST(MicrovoltInputTest, Construction) {
72   TestMicrovoltInput voltage_input =
73       TestMicrovoltInput({.min = kLimitsMin, .max = kLimitsMax},
74                          {.max_voltage_uv = kReferenceMaxVoltageUv,
75                           .min_voltage_uv = kReferenceMinVoltageUv});
76 }
77 
TEST(MicrovoltInputTest,ReadMicrovoltsWithSampleAtMin)78 TEST(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 
TEST(MicrovoltInputTest,ReadMicrovoltsWithSampleAtMax)91 TEST(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 
TEST(MicrovoltInputTest,ReadMicrovoltsWithSampleAtHalf)104 TEST(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 
TEST(MicrovoltInputTest,ReadMicrovoltsWithBipolarAdcAtZero)117 TEST(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 
TEST(MicrovoltInputTest,ReadMicrovoltsWithBipolarAdcAtMin)130 TEST(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 
TEST(MicrovoltInputTest,ReadMicrovoltsWithBipolarAdcAtMax)143 TEST(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 
TEST(MicrovoltInputTest,ReadMicrovoltsWithBipolarAdcAtUpperHalf)156 TEST(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 
TEST(MicrovoltInputTest,ReadMicrovoltsWithBipolarAdcAtLowerHalf)169 TEST(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 
TEST(MicrovoltInputTest,ReadMicrovoltsWithBipolarReferenceAtZero)182 TEST(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 
TEST(MicrovoltInputTest,ReadMicrovoltsWithBipolarReferenceAtMin)195 TEST(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 
TEST(MicrovoltInputTest,ReadMicrovoltsWithBipolarReferenceAtMax)208 TEST(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 
TEST(MicrovoltInputTest,ReadMicrovoltsWithBipolarReferenceAtHalf)221 TEST(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 
TEST(MicrovoltInputTest,ReadMicrovoltsWithSampleAtMinCornerCase)234 TEST(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_EQ(result.status(), pw::Status::Internal());
243 }
244 
TEST(MicrovoltInputTest,ReadMicrovoltsWithSampleAtMaxCornerCase)245 TEST(MicrovoltInputTest, ReadMicrovoltsWithSampleAtMaxCornerCase) {
246   TestMicrovoltInput voltage_input =
247       TestMicrovoltInput({.min = kCornerLimitsMin, .max = kCornerLimitsMax},
248                          {.max_voltage_uv = kCornerReferenceMaxVoltageUv,
249                           .min_voltage_uv = kCornerReferenceMinVoltageUv});
250   voltage_input.SetSampleValue(kCornerLimitsMax);
251 
252   Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
253   ASSERT_EQ(result.status(), pw::Status::Internal());
254 }
255 
TEST(MicrovoltInputTest,ReadMicrovoltsWithInvertedReferenceAtMax)256 TEST(MicrovoltInputTest, ReadMicrovoltsWithInvertedReferenceAtMax) {
257   TestMicrovoltInput voltage_input =
258       TestMicrovoltInput({.min = kInvertedLimitsMin, .max = kInvertedLimitsMax},
259                          {.max_voltage_uv = kInvertedReferenceMaxVoltageUv,
260                           .min_voltage_uv = kInvertedReferenceMinVoltageUv});
261   voltage_input.SetSampleValue(kInvertedLimitsMax);
262 
263   Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
264   ASSERT_EQ(result.status(), pw::Status::Internal());
265 }
266 
TEST(MicrovoltInputTest,ReadMicrovoltsWithInvertedReferenceAtMin)267 TEST(MicrovoltInputTest, ReadMicrovoltsWithInvertedReferenceAtMin) {
268   TestMicrovoltInput voltage_input =
269       TestMicrovoltInput({.min = kInvertedLimitsMin, .max = kInvertedLimitsMax},
270                          {.max_voltage_uv = kInvertedReferenceMaxVoltageUv,
271                           .min_voltage_uv = kInvertedReferenceMinVoltageUv});
272   voltage_input.SetSampleValue(kInvertedLimitsMin);
273 
274   Result<int32_t> result = voltage_input.TryReadMicrovoltsFor(kTimeout);
275   ASSERT_EQ(result.status(), pw::Status::Internal());
276 }
277 
278 }  // namespace
279 }  // namespace analog
280 }  // namespace pw
281