esp_hal/rom/
regi2c.rs

1use crate::soc::regi2c::{regi2c_read, regi2c_write};
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq)]
4#[cfg_attr(feature = "defmt", derive(defmt::Format))]
5pub(crate) struct RegI2cMaster {
6    pub master: u8,
7    pub host_id: u8,
8}
9
10impl RegI2cMaster {
11    pub const fn new(master: u8, host_id: u8) -> Self {
12        Self { master, host_id }
13    }
14
15    #[allow(unused)]
16    pub fn write(&self, reg: u8, data: u8) {
17        regi2c_write(self.master, self.host_id, reg, data);
18    }
19
20    #[allow(unused)]
21    pub fn read(&self, reg: u8) -> u8 {
22        regi2c_read(self.master, self.host_id, reg)
23    }
24}
25
26#[derive(Clone, Copy, Debug, PartialEq, Eq)]
27#[cfg_attr(feature = "defmt", derive(defmt::Format))]
28pub(crate) struct RegI2cRegister {
29    master: RegI2cMaster,
30    reg_add: u8,
31}
32
33impl RegI2cRegister {
34    pub const fn new(master: RegI2cMaster, reg_add: u8) -> Self {
35        Self { master, reg_add }
36    }
37
38    #[allow(unused)]
39    pub fn write_reg(&self, data: u8) {
40        self.master.write(self.reg_add, data);
41    }
42
43    #[allow(unused)]
44    pub fn read(&self) -> u8 {
45        self.master.read(self.reg_add)
46    }
47}
48
49#[derive(Clone, Copy, Debug, PartialEq, Eq)]
50#[cfg_attr(feature = "defmt", derive(defmt::Format))]
51pub(crate) struct RawRegI2cField {
52    register: RegI2cRegister,
53    msb: u8,
54    lsb: u8,
55}
56
57impl RawRegI2cField {
58    #[allow(unused)]
59    pub const fn new(register: RegI2cRegister, msb: u8, lsb: u8) -> Self {
60        ::core::assert!(msb < 8 + lsb);
61        Self { register, msb, lsb }
62    }
63
64    #[allow(unused)]
65    pub fn read(&self) -> u8 {
66        let reg_raw = self.register.read();
67        (reg_raw >> self.lsb) & !(u8::MAX << (self.msb - self.lsb + 1))
68    }
69
70    #[allow(unused)]
71    pub fn write_field(&self, data: u8) {
72        let bits = self.register.read();
73
74        let unwritten_bits = (!(u32::MAX << self.lsb) | (u32::MAX << (self.msb + 1))) as u8;
75        let data_mask = !(u32::MAX << (self.msb - self.lsb + 1)) as u8;
76        let data_bits = (data & data_mask) << self.lsb;
77
78        self.register.write_reg((bits & unwritten_bits) | data_bits);
79    }
80}
81
82macro_rules! define_regi2c {
83    ($(master: $master_name:ident($master:literal, $hostid:literal) {
84        $(reg: $register_name:ident($register:literal) {
85            $(field: $field_name:ident ( $msb:literal .. $lsb:literal )),*
86        })*
87    })+) => {
88        $(
89            #[allow(unused)]
90            pub(crate) const $master_name: RegI2cMaster = RegI2cMaster::new($master, $hostid);
91
92            $(
93                #[allow(unused)]
94                pub(crate) const $register_name: RegI2cRegister = RegI2cRegister::new($master_name, $register);
95
96                $(
97                    #[allow(unused)]
98                    pub(crate) const $field_name: RawRegI2cField = RawRegI2cField::new($register_name, $msb, $lsb);
99                )*
100            )*
101        )+
102    };
103}
104pub(crate) use define_regi2c;