1
use crate::soc::regi2c::{regi2c_read, regi2c_write};
2

            
3
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
4
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
5
pub(crate) struct RegI2cMaster {
6
    pub master: u8,
7
    pub host_id: u8,
8
}
9

            
10
impl 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))]
28
pub(crate) struct RegI2cRegister {
29
    master: RegI2cMaster,
30
    reg_add: u8,
31
}
32

            
33
impl 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
9619
        self.master.read(self.reg_add)
46
    }
47
}
48

            
49
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
50
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
51
pub(crate) struct RawRegI2cField {
52
    register: RegI2cRegister,
53
    msb: u8,
54
    lsb: u8,
55
}
56

            
57
impl 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
9619
    pub fn write_field(&self, data: u8) {
72
        let bits = self.register.read();
73

            
74
9619
        let unwritten_bits = (!(u32::MAX << self.lsb) | (u32::MAX << (self.msb + 1))) as u8;
75
9619
        let data_mask = !(u32::MAX << (self.msb - self.lsb + 1)) as u8;
76
9619
        let data_bits = (data & data_mask) << self.lsb;
77

            
78
9619
        self.register.write_reg((bits & unwritten_bits) | data_bits);
79
    }
80
}
81

            
82
macro_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
}
104
pub(crate) use define_regi2c;