1use super::bus::{Interface, InterfaceError};
27use core::fmt::{self, Debug};
28
29use core::marker::PhantomData;
30use core::usize;
31
32pub enum BitByteStructError<E> {
41 TooManyBits,
42 TooBigShift,
43 InputToBig,
44 InterfaceError(InterfaceError<E>),
45 BusError(E),
46}
47
48impl<E> From<E> for BitByteStructError<E> {
49 fn from(err: E) -> Self {
50 BitByteStructError::BusError(err)
51 }
52}
53
54impl<E> Debug for BitByteStructError<E>
55{
58 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
59 match self {
60 Self::BusError(_) => f.write_str("BitByteStructError Bus error")?,
63 Self::InterfaceError(_) => f.write_str("BitByteStructError Interface error")?,
64 Self::TooManyBits => f.write_str("BitByteStructError too many bits error")?,
65 Self::TooBigShift => f.write_str("BitByteStructError too big shift error")?,
66 Self::InputToBig => f.write_str("BitByteStructError input too big error")?,
67 }
68
69 Ok(())
70 }
71}
72
73pub struct BitStruct<Interface: ?Sized, const ADDRESS: u8, const BITS: u8, const SHIFT: u8> {
75 phantom: PhantomData<Interface>,
76}
77
78impl<I, const ADDRESS: u8, const BITS: u8, const SHIFT: u8> BitStruct<I, ADDRESS, BITS, SHIFT>
79where
80 I: Interface,
81 I: ?Sized,
82{
83 pub fn new() -> Result<BitStruct<I, ADDRESS, BITS, SHIFT>, BitByteStructError<I::Error>> {
91 if BITS > 8 {
92 return Err(BitByteStructError::TooManyBits);
93 }
94 if SHIFT + BITS > 8 {
95 return Err(BitByteStructError::TooBigShift);
96 }
97 Ok(BitStruct {
98 phantom: PhantomData,
99 })
100 }
101
102 fn mask_size(&self) -> u8 {
103 (2_u16.pow(BITS as u32) - 1) as u8
104 }
105
106 pub fn read(
112 &self,
113 bus: &mut dyn Interface<Error = I::Error>,
114 ) -> Result<u8, BitByteStructError<I::Error>> {
115 let mut active_buffer: [u8; 1] = [0];
116 bus.read_register(ADDRESS, &mut active_buffer)?;
117 Ok((active_buffer[0] & (self.mask_size() << SHIFT)) >> SHIFT)
118 }
119
120 pub fn write(
131 &self,
132 bus: &mut dyn Interface<Error = I::Error>,
133 new_value: u8,
134 ) -> Result<(), BitByteStructError<I::Error>> {
135 let mask = self.mask_size() << SHIFT;
137 if new_value != new_value & self.mask_size() {
138 return Err(BitByteStructError::InputToBig);
139 }
140 let mut active_buffer: [u8; 1] = [0];
141 bus.read_register(ADDRESS, &mut active_buffer)?;
142 active_buffer[0] = (active_buffer[0] & !mask) | new_value << SHIFT;
143 bus.write_register(ADDRESS, &active_buffer)?;
144 Ok(())
145 }
146}
147
148pub struct CrossByteBitStructI16<Interface: ?Sized> {
152 phantom: PhantomData<Interface>,
153 register_address: u8,
154 bits: u8,
155 big_endian: bool,
157}
158
159impl<I> CrossByteBitStructI16<I>
160where
161 I: Interface,
162 I: ?Sized,
163{
164 pub fn new(
165 register_address: u8,
166 bits: u8,
167 big_endian: bool,
168 ) -> Result<CrossByteBitStructI16<I>, BitByteStructError<I::Error>> {
169 Ok(Self {
170 phantom: PhantomData,
171 register_address,
172 bits,
173 big_endian,
174 })
175 }
176
177 fn mask_size_full(&self) -> u16 {
178 (2_u32.pow(self.bits as u32) - 1) as u16
179 }
180
181 fn mask_size_byte(&self) -> u8 {
182 (2_u32.pow((self.bits - 8) as u32) - 1) as u8
183 }
184
185 pub fn read(
187 &self,
188 bus: &mut dyn Interface<Error = I::Error>,
189 ) -> Result<u16, BitByteStructError<I::Error>> {
190 let mut active_buffer: [u8; 2] = [0; 2];
191 bus.read_register(self.register_address, &mut active_buffer)?;
192 if self.big_endian {
193 Ok(u16::from_be_bytes([
194 active_buffer[0] & self.mask_size_byte(),
195 active_buffer[1],
196 ]))
197 } else {
198 Ok(u16::from_le_bytes([
199 active_buffer[0],
200 active_buffer[1] & self.mask_size_byte(),
201 ]))
202 }
203 }
204
205 pub fn write(
207 &self,
208 bus: &mut dyn Interface<Error = I::Error>,
209 new_value: u16,
210 ) -> Result<(), BitByteStructError<I::Error>> {
211 if new_value != new_value & self.mask_size_full() {
213 return Err(BitByteStructError::InputToBig);
214 }
215 let active_buffer: [u8; 2] = if self.big_endian {
216 [((new_value & 0xFF00) >> 8) as u8, (new_value & 0xFF) as u8]
217 } else {
218 [(new_value & 0xFF) as u8, ((new_value & 0xFF00) >> 8) as u8]
219 };
220 bus.write_register(self.register_address, &active_buffer)?;
221 Ok(())
222 }
223}
224
225pub struct ByteStructI16<Interface: ?Sized, const COUNT: usize> {
233 phantom_i: PhantomData<Interface>,
234 register_address: u8,
235 big_endian: bool,
237}
238
239impl<I, const COUNT: usize> ByteStructI16<I, COUNT>
240where
241 I: Interface,
242 I: ?Sized,
243{
244 pub fn new(
245 register_address: u8,
246 big_endian: bool,
247 ) -> Result<ByteStructI16<I, COUNT>, BitByteStructError<I::Error>> {
248 Ok(ByteStructI16 {
249 phantom_i: PhantomData,
250 register_address,
251 big_endian,
252 })
253 }
254
255 pub fn read(
259 &self,
260 bus: &mut dyn Interface<Error = I::Error>,
261 ) -> Result<[i16; COUNT], BitByteStructError<I::Error>> {
262 let mut result_slice: [i16; COUNT] = [0; COUNT];
263 let mut raw_slice: [u8; 20] = [0; 20];
265
266 bus.read_register(self.register_address, &mut raw_slice[0..(COUNT * 2)])?;
267 for iii in 0..COUNT {
268 if self.big_endian {
269 result_slice[iii] =
270 i16::from_be_bytes([raw_slice[iii * 2], raw_slice[iii * 2 + 1]]);
271 } else {
272 result_slice[iii] =
273 i16::from_le_bytes([raw_slice[iii * 2], raw_slice[iii * 2 + 1]]);
274 }
275 }
276 Ok(result_slice)
277 }
278}