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}