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;