adafruit_seesaw/modules/
status.rs1use super::{Modules, Reg};
2use crate::{devices::SeesawDevice, driver::Driver, DriverExt, SeesawError};
3
4const STATUS_HW_ID: &Reg = &[Modules::Status.into_u8(), 0x01];
5const STATUS_VERSION: &Reg = &[Modules::Status.into_u8(), 0x02];
6const STATUS_OPTIONS: &Reg = &[Modules::Status.into_u8(), 0x03];
7const STATUS_TEMP: &Reg = &[Modules::Status.into_u8(), 0x04];
8const STATUS_SWRST: &Reg = &[Modules::Status.into_u8(), 0x7F];
9
10pub trait StatusModule<D: Driver>: SeesawDevice<Driver = D> {
11 fn capabilities(&mut self) -> Result<DeviceCapabilities, SeesawError<D::Error>> {
13 let addr = self.addr();
14
15 self.driver()
16 .read_u32(addr, STATUS_OPTIONS)
17 .map(|opts| opts.into())
18 .map_err(SeesawError::I2c)
19 }
20
21 fn hardware_id(&mut self) -> Result<u8, SeesawError<D::Error>> {
22 let addr = self.addr();
23 self.driver()
24 .read_u8(addr, STATUS_HW_ID)
25 .map_err(SeesawError::I2c)
26 }
27
28 fn product_info(&mut self) -> Result<ProductDateCode, SeesawError<D::Error>> {
30 let addr = self.addr();
31
32 self.driver()
33 .read_u32(addr, STATUS_VERSION)
34 .map(|version| version.into())
35 .map_err(SeesawError::I2c)
36 }
37
38 fn reset(&mut self) -> Result<(), SeesawError<D::Error>> {
41 let addr = self.addr();
42
43 self.driver()
44 .write_u8(addr, STATUS_SWRST, 0xFF)
45 .map(|_| self.driver().delay_us(125_000))
46 .map_err(SeesawError::I2c)
47 }
48
49 fn reset_and_verify_seesaw(&mut self) -> Result<(), SeesawError<D::Error>> {
50 let hw_id = Self::HARDWARE_ID;
51 self.reset().and_then(|_| match self.hardware_id() {
52 Ok(id) if id == hw_id.into() => Ok(()),
53 Ok(id) => Err(SeesawError::InvalidHardwareId(id)),
54 Err(e) => Err(e),
55 })
56 }
57
58 fn temp(&mut self) -> Result<f32, SeesawError<D::Error>> {
59 let addr = self.addr();
60
61 self.driver()
62 .read_u32(addr, STATUS_TEMP)
63 .map(|buf| buf as f32 / (1u32 << 16) as f32)
64 .map_err(SeesawError::I2c)
65 }
66}
67
68#[derive(Copy, Clone, Debug)]
70#[cfg_attr(feature = "defmt", derive(defmt::Format))]
71pub struct DeviceCapabilities {
72 pub adc: bool,
73 pub dac: bool,
74 pub dap: bool,
75 pub eeprom: bool,
76 pub encoder: bool,
77 pub gpio: bool,
78 pub interrupt: bool,
79 pub keypad: bool,
80 pub neopixel: bool,
81 pub sercom0: bool,
82 pub spectrum: bool,
83 pub status: bool,
84 pub timer: bool,
85 pub touch: bool,
86}
87
88impl From<u32> for DeviceCapabilities {
89 fn from(value: u32) -> Self {
90 DeviceCapabilities {
91 adc: (value >> Modules::Adc as u8) & 1 == 1,
92 dac: (value >> Modules::Dac as u8) & 1 == 1,
93 dap: (value >> Modules::Dap as u8) & 1 == 1,
94 eeprom: (value >> Modules::Eeprom as u8) & 1 == 1,
95 encoder: (value >> Modules::Encoder as u8) & 1 == 1,
96 gpio: (value >> Modules::Gpio as u8) & 1 == 1,
97 interrupt: (value >> Modules::Interrupt as u8) & 1 == 1,
98 keypad: (value >> Modules::Keypad as u8) & 1 == 1,
99 neopixel: (value >> Modules::Neopixel as u8) & 1 == 1,
100 sercom0: (value >> Modules::Sercom0 as u8) & 1 == 1,
101 spectrum: (value >> Modules::Spectrum as u8) & 1 == 1,
102 status: (value >> Modules::Status as u8) & 1 == 1,
103 timer: (value >> Modules::Timer as u8) & 1 == 1,
104 touch: (value >> Modules::Touch as u8) & 1 == 1,
105 }
106 }
107}
108
109#[derive(Debug)]
111#[cfg_attr(feature = "defmt", derive(defmt::Format))]
112pub struct ProductDateCode {
113 pub id: u16,
114 pub year: u16,
115 pub month: u8,
116 pub day: u8,
117}
118
119impl From<u32> for ProductDateCode {
120 fn from(vers: u32) -> Self {
121 Self {
122 id: (vers >> 16) as u16,
123 year: ((vers & 0x3F) + 2000) as u16,
124 month: ((vers >> 7) & 0xF) as u8,
125 day: ((vers >> 11) & 0x1F) as u8,
126 }
127 }
128}