embedded_interfaces/registers/i2c/codecs/
standard_codec.rs1use crate::TransportError;
2use crate::registers::{ReadableRegister, Register, RegisterCodec, WritableRegister};
3
4use bytemuck::Zeroable;
5
6#[derive(Default)]
26pub struct StandardCodec<const HEADER_SIZE: usize> {}
27
28impl<const HEADER_SIZE: usize> RegisterCodec for StandardCodec<HEADER_SIZE> {
29 type Error = ();
30}
31
32#[maybe_async_cfg::maybe(
33 idents(hal(sync = "embedded_hal", async = "embedded_hal_async"), Codec, I2cBoundBus),
34 sync(feature = "sync"),
35 async(feature = "async"),
36 keep_self
37)]
38impl<const HEADER_SIZE: usize> crate::registers::i2c::Codec for StandardCodec<HEADER_SIZE> {
39 #[inline]
40 async fn read_register<R, I, A>(
41 bound_bus: &mut crate::i2c::I2cBoundBus<I, A>,
42 ) -> Result<R, TransportError<Self::Error, I::Error>>
43 where
44 R: Register<CodecError = Self::Error> + ReadableRegister,
45 I: hal::i2c::I2c<A> + hal::i2c::ErrorType,
46 A: hal::i2c::AddressMode + Copy + core::fmt::Debug,
47 {
48 let header = &R::ADDRESS.to_be_bytes()[core::mem::size_of_val(&R::ADDRESS) - HEADER_SIZE..];
49 let mut register = R::zeroed();
50 let data = bytemuck::bytes_of_mut(&mut register);
51 bound_bus.interface.write_read(bound_bus.address, header, data).await?;
52
53 #[cfg(feature = "trace-communication")]
54 log::trace!(
55 "I2C [32mread[m i2c_addr={:?} register_addr={:08x}:\n{}",
56 bound_bus.address,
57 R::ADDRESS,
58 register.bitdump()
59 );
60
61 Ok(register)
62 }
63
64 #[inline]
65 async fn write_register<R, I, A>(
66 bound_bus: &mut crate::i2c::I2cBoundBus<I, A>,
67 register: impl AsRef<R>,
68 ) -> Result<(), TransportError<Self::Error, I::Error>>
69 where
70 R: Register<CodecError = Self::Error> + WritableRegister,
71 I: hal::i2c::I2c<A> + hal::i2c::ErrorType,
72 A: hal::i2c::AddressMode + Copy + core::fmt::Debug,
73 {
74 #[cfg(feature = "trace-communication")]
75 log::trace!(
76 "I2C [31mwrite[m i2c_addr={:?} register_addr={:08x}:\n{}",
77 bound_bus.address,
78 R::ADDRESS,
79 register.as_ref().bitdump()
80 );
81
82 #[repr(C, packed(1))]
83 #[derive(Copy, Clone, bytemuck::Pod, Zeroable)]
84 struct Buffer<const HEADER_SIZE: usize, R> {
85 header: [u8; HEADER_SIZE],
86 register: R,
87 }
88
89 let mut buffer = Buffer::<{ HEADER_SIZE }, R> {
90 header: R::ADDRESS.to_be_bytes()[core::mem::size_of_val(&R::ADDRESS) - HEADER_SIZE..]
91 .try_into()
92 .map_err(|_| TransportError::Unexpected("wrong register address size - should not be able to occur"))?,
93 register: *register.as_ref(),
94 };
95
96 let data = bytemuck::bytes_of_mut(&mut buffer);
97 Ok(bound_bus.interface.write(bound_bus.address, data).await?)
98 }
99}