1use num_enum::{IntoPrimitive, TryFromPrimitive};
5
6#[derive(Clone, Copy, Debug, PartialEq, IntoPrimitive, TryFromPrimitive)]
11#[repr(u8)]
12pub enum Address {
13 Low = 0x68,
14 High = 0x69,
15}
16
17#[cfg(test)]
18mod address_test {
19 use super::Address;
20 use core::convert::TryFrom;
21
22 #[test]
23 fn try_low() {
24 let low = Address::try_from(0x68);
25 assert!(low.is_ok());
26 assert_eq!(low.unwrap(), Address::Low);
27 }
28
29 #[test]
30 fn try_high() {
31 let high = Address::try_from(0x69);
32 assert!(high.is_ok());
33 assert_eq!(high.unwrap(), Address::High);
34 }
35
36 #[test]
37 fn try_undefined() {
38 let zero = Address::try_from(0);
39 assert!(zero.is_err());
40 }
41}
42
43#[derive(Clone, Copy, Debug, PartialEq, IntoPrimitive, TryFromPrimitive)]
45#[repr(u8)]
46pub enum Register {
47 PowerControl = 0x00,
50
51 Reset = 0x01,
54
55 FrameRate = 0x02,
58
59 InterruptControl = 0x03,
62
63 Status = 0x04,
67
68 StatusClear = 0x05,
71
72 Average = 0x07,
75
76 AverageData = 0x1F,
79
80 InterruptLevelHighLower = 0x08,
84
85 InterruptLevelLowLower = 0x0A,
89
90 InterruptHysteresisLower = 0x0C,
94
95 ThermistorLower = 0x0E,
99
100 InterruptTableStart = 0x10,
106
107 PixelTemperatureStart = 0x80,
111}
112
113#[derive(Clone, Copy, Debug, PartialEq, IntoPrimitive, TryFromPrimitive)]
126#[repr(u8)]
127pub enum PowerControlValue {
128 Normal = 0x00,
130
131 Sleep = 0x10,
133
134 Standby60 = 0x20,
136
137 Standby10 = 0x21,
139}
140
141#[cfg(test)]
142mod power_control_value_tests {
143 use super::PowerControlValue;
144 use core::convert::TryFrom;
145
146 #[test]
147 fn try_normal() {
148 let normal = PowerControlValue::try_from(0x0);
149 assert!(normal.is_ok());
150 assert_eq!(normal.unwrap(), PowerControlValue::Normal);
151 }
152
153 #[test]
154 fn try_sleep() {
155 let sleep = PowerControlValue::try_from(0x10);
156 assert!(sleep.is_ok());
157 assert_eq!(sleep.unwrap(), PowerControlValue::Sleep);
158 }
159
160 #[test]
161 fn try_standby_60() {
162 let standby_60 = PowerControlValue::try_from(0x20);
163 assert!(standby_60.is_ok());
164 assert_eq!(standby_60.unwrap(), PowerControlValue::Standby60);
165 }
166
167 #[test]
168 fn try_standby_10() {
169 let standby_10 = PowerControlValue::try_from(0x21);
170 assert!(standby_10.is_ok());
171 assert_eq!(standby_10.unwrap(), PowerControlValue::Standby10);
172 }
173
174 #[test]
175 fn unknown() {
176 let unknown = PowerControlValue::try_from(u8::MAX);
177 assert!(unknown.is_err());
178 }
179}
180
181#[derive(Clone, Copy, Debug, PartialEq, IntoPrimitive, TryFromPrimitive)]
186#[repr(u8)]
187pub enum ResetValue {
188 Flag = 0x30,
190
191 Initial = 0x3F,
193}
194
195#[cfg(test)]
196mod reset_value_tests {
197 use super::ResetValue;
198 use core::convert::TryFrom;
199
200 #[test]
201 fn try_flag() {
202 let flag = ResetValue::try_from(0x30);
203 assert!(flag.is_ok());
204 assert_eq!(flag.unwrap(), ResetValue::Flag);
205 }
206
207 #[test]
208 fn try_initial() {
209 let initial = ResetValue::try_from(0x3F);
210 assert!(initial.is_ok());
211 assert_eq!(initial.unwrap(), ResetValue::Initial);
212 }
213
214 #[test]
215 fn try_unknown() {
216 let unknown = ResetValue::try_from(0);
217 assert!(unknown.is_err());
218 }
219}
220
221#[derive(Clone, Copy, Debug, PartialEq, IntoPrimitive, TryFromPrimitive)]
226#[repr(u8)]
227pub enum FrameRateValue {
228 Fps1 = 1,
230
231 #[num_enum(alternatives = [10])]
233 Fps10 = 0,
234}
235
236#[cfg(test)]
237mod frame_rate_tests {
238 use super::FrameRateValue;
239 use core::convert::TryFrom;
240
241 #[test]
242 fn try_1() {
243 let fps = FrameRateValue::try_from(1);
244 assert!(fps.is_ok());
245 assert_eq!(fps.unwrap(), FrameRateValue::Fps1);
246 }
247
248 #[test]
249 fn try_0() {
250 let fps = FrameRateValue::try_from(0);
251 assert!(fps.is_ok());
252 assert_eq!(fps.unwrap(), FrameRateValue::Fps10);
253 }
254
255 #[test]
256 fn try_10() {
257 let fps = FrameRateValue::try_from(10);
258 assert!(fps.is_ok());
259 assert_eq!(fps.unwrap(), FrameRateValue::Fps10);
260 }
261
262 #[test]
263 fn try_unknown() {
264 let unknown = FrameRateValue::try_from(20);
265 assert!(unknown.is_err());
266 }
267}
268
269#[derive(Clone, Copy, Debug, PartialEq, IntoPrimitive)]
271#[repr(u8)]
272pub enum InterruptControlMode {
273 Absolute = 0x2,
275
276 Difference = 0x0,
278}
279
280impl From<u8> for InterruptControlMode {
281 fn from(value: u8) -> Self {
282 match value & 0x2 {
283 0x2 => Self::Absolute,
284 _ => Self::Difference,
285 }
286 }
287}
288
289impl Default for InterruptControlMode {
290 fn default() -> Self {
292 Self::Difference
293 }
294}
295
296#[cfg(test)]
297mod interrupt_control_mode_tests {
298 use super::InterruptControlMode;
299
300 #[test]
301 fn from_int() {
302 assert_eq!(
303 InterruptControlMode::from(0),
304 InterruptControlMode::Difference
305 );
306 assert_eq!(
307 InterruptControlMode::from(1),
308 InterruptControlMode::Difference
309 );
310 assert_eq!(
311 InterruptControlMode::from(2),
312 InterruptControlMode::Absolute
313 );
314 }
315
316 #[test]
317 fn default() {
318 assert_eq!(
319 InterruptControlMode::default(),
320 InterruptControlMode::Difference
321 );
322 }
323}
324
325#[derive(Clone, Copy, Debug, Default, PartialEq)]
327pub struct InterruptControlValue {
328 mode: InterruptControlMode,
330
331 enabled: bool,
334}
335
336impl InterruptControlValue {
337 pub fn mode(&self) -> InterruptControlMode {
339 self.mode
340 }
341
342 pub fn set_mode(&mut self, mode: InterruptControlMode) {
344 self.mode = mode
345 }
346
347 pub fn enabled(&self) -> bool {
349 self.enabled
350 }
351
352 pub fn enable(&mut self) {
354 self.enabled = true
355 }
356
357 pub fn disable(&mut self) {
359 self.enabled = false
360 }
361}
362
363impl From<u8> for InterruptControlValue {
364 fn from(value: u8) -> Self {
365 Self {
370 mode: InterruptControlMode::from(value),
371 enabled: (value & 0x1) == 1,
372 }
373 }
374}
375
376impl From<InterruptControlValue> for bool {
377 fn from(value: InterruptControlValue) -> Self {
378 value.enabled
379 }
380}
381
382impl From<InterruptControlValue> for u8 {
383 fn from(value: InterruptControlValue) -> Self {
384 (value.mode as u8) | (value.enabled as u8)
385 }
386}
387
388#[cfg(test)]
389mod interrupt_control_value_tests {
390 use super::{InterruptControlMode, InterruptControlValue};
391
392 #[test]
393 fn from_byte() {
394 let disabled_difference = InterruptControlValue::from(0x0);
395 assert_eq!(disabled_difference.mode(), InterruptControlMode::Difference);
396 assert!(!disabled_difference.enabled());
397 let enabled_difference = InterruptControlValue::from(0x1);
398 assert_eq!(enabled_difference.mode(), InterruptControlMode::Difference);
399 assert!(enabled_difference.enabled());
400 let disabled_absolute = InterruptControlValue::from(0x2);
401 assert_eq!(disabled_absolute.mode(), InterruptControlMode::Absolute);
402 assert!(!disabled_absolute.enabled());
403 let enabled_absolute = InterruptControlValue::from(0x3);
404 assert_eq!(enabled_absolute.mode(), InterruptControlMode::Absolute);
405 assert!(enabled_absolute.enabled());
406 }
407
408 #[test]
410 fn from_byte_ignore_extra() {
411 let disabled_difference = InterruptControlValue::from(0x10);
412 assert_eq!(disabled_difference.mode(), InterruptControlMode::Difference);
413 assert!(!disabled_difference.enabled());
414 let enabled_difference = InterruptControlValue::from(0x11);
415 assert_eq!(enabled_difference.mode(), InterruptControlMode::Difference);
416 assert!(enabled_difference.enabled());
417 let disabled_absolute = InterruptControlValue::from(0x12);
418 assert_eq!(disabled_absolute.mode(), InterruptControlMode::Absolute);
419 assert!(!disabled_absolute.enabled());
420 let enabled_absolute = InterruptControlValue::from(0x13);
421 assert_eq!(enabled_absolute.mode(), InterruptControlMode::Absolute);
422 assert!(enabled_absolute.enabled());
423 }
424
425 #[test]
426 fn to_bool() {
427 let disabled = InterruptControlValue::from(0x0);
429 assert!(!bool::from(disabled));
430 let enabled = InterruptControlValue::from(0x1);
431 assert!(bool::from(enabled));
432 }
433
434 #[test]
435 fn to_byte() {
436 for byte in 0..4 {
438 let value = InterruptControlValue::from(byte);
439 assert_eq!(byte, u8::from(value));
440 }
441 }
442
443 #[test]
444 fn set_enabled() {
445 let mut value = InterruptControlValue::default();
446 assert!(!value.enabled());
448 value.disable();
450 assert!(!value.enabled());
451 value.enable();
453 assert!(value.enabled());
454 value.enable();
456 assert!(value.enabled());
457 value.disable();
459 assert!(!value.enabled());
460 }
461
462 #[test]
463 fn set_mode() {
464 let mut value = InterruptControlValue::default();
465 assert_eq!(value.mode(), InterruptControlMode::Difference);
467 value.set_mode(InterruptControlMode::Absolute);
469 assert_eq!(value.mode(), InterruptControlMode::Absolute);
470 value.set_mode(InterruptControlMode::Difference);
472 assert_eq!(value.mode(), InterruptControlMode::Difference);
473 }
474}
475
476#[derive(Clone, Copy, Debug, PartialEq)]
477#[repr(u8)]
478enum StatusBits {
479 TemperatureOverflow = 0x4,
480 Interrupt = 0x2,
481}
482
483#[derive(Clone, Copy, Debug, Default, PartialEq)]
486pub struct StatusValue {
487 temperature_overflow: bool,
490
491 interrupt: bool,
493}
494
495impl StatusValue {
496 pub fn new(overflow: bool, interrupt: bool) -> Self {
497 Self {
498 temperature_overflow: overflow,
499 interrupt,
500 }
501 }
502
503 pub fn temperature_overflow(&self) -> bool {
504 self.temperature_overflow
505 }
506 pub fn interrupt(&self) -> bool {
507 self.interrupt
508 }
509}
510
511impl From<u8> for StatusValue {
512 fn from(value: u8) -> Self {
513 let temperature_overflow = (value & StatusBits::TemperatureOverflow as u8)
516 == StatusBits::TemperatureOverflow as u8;
517 let interrupt = (value & StatusBits::Interrupt as u8) == StatusBits::Interrupt as u8;
518 Self {
519 temperature_overflow,
520 interrupt,
521 }
522 }
523}
524
525impl From<StatusValue> for u8 {
526 fn from(value: StatusValue) -> Self {
527 let mut bitfield = 0u8;
528 if value.temperature_overflow {
529 bitfield |= StatusBits::TemperatureOverflow as u8;
530 }
531 if value.interrupt {
532 bitfield |= StatusBits::Interrupt as u8;
533 }
534 bitfield
535 }
536}
537
538#[cfg(test)]
539mod test_status_value {
540 use super::{StatusBits, StatusValue};
541
542 #[test]
543 fn create_and_access() {
544 for overflow in [true, false].iter() {
545 for interrupt in [true, false].iter() {
546 let value = StatusValue::new(*overflow, *interrupt);
547 assert_eq!(value.temperature_overflow(), *overflow);
548 assert_eq!(value.interrupt(), *interrupt);
549 }
550 }
551 }
552
553 #[test]
554 fn byte_no_flags() {
555 let value = StatusValue::from(0x0);
556 assert!(!value.temperature_overflow());
557 assert!(!value.interrupt());
558 assert_eq!(u8::from(value), 0x0);
559 }
560
561 #[test]
562 fn byte_only_overflow() {
563 let value = StatusValue::from(StatusBits::TemperatureOverflow as u8);
564 assert!(value.temperature_overflow());
565 assert!(!value.interrupt());
566 assert_eq!(u8::from(value), StatusBits::TemperatureOverflow as u8);
567 }
568
569 #[test]
570 fn byte_only_interrupt() {
571 let value = StatusValue::from(StatusBits::Interrupt as u8);
572 assert!(!value.temperature_overflow());
573 assert!(value.interrupt());
574 assert_eq!(u8::from(value), StatusBits::Interrupt as u8);
575 }
576
577 #[test]
578 fn byte_both_flags() {
579 let both_bits = StatusBits::Interrupt as u8 | StatusBits::TemperatureOverflow as u8;
580 let value = StatusValue::from(both_bits);
581 assert!(value.temperature_overflow());
582 assert!(value.interrupt());
583 assert_eq!(u8::from(value), both_bits);
584 }
585
586 #[test]
587 fn ignore_undefined() {
588 let all_set = StatusValue::from(0xF);
589 assert!(all_set.temperature_overflow());
590 assert!(all_set.interrupt());
591 assert_eq!(
592 u8::from(all_set),
593 StatusBits::Interrupt as u8 | StatusBits::TemperatureOverflow as u8
594 );
595 let none_set = StatusValue::from(0x9);
596 assert!(!none_set.temperature_overflow());
597 assert!(!none_set.interrupt());
598 assert_eq!(u8::from(none_set), 0x0);
599 }
600}
601
602#[derive(Clone, Copy, Debug, PartialEq, IntoPrimitive)]
607#[repr(u8)]
608pub enum AverageValue {
609 Disabled = 0x00,
610 Enabled = 0x20,
611}
612
613impl From<bool> for AverageValue {
614 fn from(value: bool) -> Self {
615 if value {
616 Self::Enabled
617 } else {
618 Self::Disabled
619 }
620 }
621}
622
623impl From<u8> for AverageValue {
624 fn from(value: u8) -> Self {
625 match value & 0x20 {
626 0x20 => Self::Enabled,
627 _ => Self::Disabled,
628 }
629 }
630}
631
632impl From<AverageValue> for bool {
633 fn from(value: AverageValue) -> Self {
634 value == AverageValue::Enabled
635 }
636}
637
638impl Default for AverageValue {
639 fn default() -> Self {
640 Self::Disabled
641 }
642}
643
644#[cfg(test)]
645mod average_tests {
646 use super::AverageValue;
647
648 #[test]
649 fn from_bool() {
650 assert_eq!(AverageValue::from(false), AverageValue::Disabled);
651 assert_eq!(AverageValue::from(true), AverageValue::Enabled);
652 }
653
654 #[test]
655 fn from_byte() {
656 assert_eq!(AverageValue::from(0x0), AverageValue::Disabled);
658 assert_eq!(AverageValue::from(0x20), AverageValue::Enabled);
659 assert_eq!(AverageValue::from(0xF), AverageValue::Disabled);
661 assert_eq!(AverageValue::from(0xFF), AverageValue::Enabled);
662 }
663
664 #[test]
665 fn to_bool() {
666 assert!(!bool::from(AverageValue::Disabled));
667 assert!(bool::from(AverageValue::Enabled));
668 }
669}