embedded_registers/i2c/
mod.rs1pub mod codecs;
2
3use core::{any::TypeId, marker::PhantomData};
4
5use codecs::NoCodec;
6
7use crate::{ReadableRegister, WritableRegister};
8
9#[maybe_async_cfg::maybe(
14 idents(hal(sync = "embedded_hal", async = "embedded_hal_async"), I2cBoundBus),
15 sync(feature = "sync"),
16 async(feature = "async")
17)]
18#[allow(async_fn_in_trait)]
19pub trait Codec: Default + 'static {
20 async fn read_register<R, I, A>(bound_bus: &mut I2cBoundBus<I, A>) -> Result<R, I::Error>
22 where
23 R: ReadableRegister,
24 I: hal::i2c::I2c<A> + hal::i2c::ErrorType,
25 A: hal::i2c::AddressMode + Copy;
26
27 async fn write_register<R, I, A>(
29 bound_bus: &mut I2cBoundBus<I, A>,
30 register: impl AsRef<R>,
31 ) -> Result<(), I::Error>
32 where
33 R: WritableRegister,
34 I: hal::i2c::I2c<A> + hal::i2c::ErrorType,
35 A: hal::i2c::AddressMode + Copy;
36}
37
38#[maybe_async_cfg::maybe(
39 idents(hal(sync = "embedded_hal", async = "embedded_hal_async")),
40 sync(feature = "sync"),
41 async(feature = "async")
42)]
43pub struct I2cBoundBus<I, A>
45where
46 I: hal::i2c::I2c<A> + hal::i2c::ErrorType,
47 A: hal::i2c::AddressMode + Copy,
48{
49 pub interface: I,
51 pub address: A,
53}
54
55#[maybe_async_cfg::maybe(
56 idents(hal(sync = "embedded_hal", async = "embedded_hal_async"), Codec, I2cBoundBus),
57 sync(feature = "sync"),
58 async(feature = "async")
59)]
60pub struct I2cDevice<I, A, C>
63where
64 I: hal::i2c::I2c<A> + hal::i2c::ErrorType,
65 A: hal::i2c::AddressMode + Copy,
66 C: Codec,
67{
68 pub bound_bus: I2cBoundBus<I, A>,
70 pub default_codec: PhantomData<C>,
75}
76
77#[maybe_async_cfg::maybe(
78 idents(hal(sync = "embedded_hal", async = "embedded_hal_async"), Codec, I2cBoundBus),
79 sync(feature = "sync"),
80 async(feature = "async")
81)]
82impl<I, A, C> I2cDevice<I, A, C>
83where
84 I: hal::i2c::I2c<A> + hal::i2c::ErrorType,
85 A: hal::i2c::AddressMode + Copy,
86 C: Codec,
87{
88 pub fn new(interface: I, address: A) -> Self {
90 Self {
91 bound_bus: I2cBoundBus { interface, address },
92 default_codec: Default::default(),
93 }
94 }
95}
96
97#[maybe_async_cfg::maybe(
98 idents(hal(sync = "embedded_hal", async = "embedded_hal_async"), Codec, RegisterInterface),
99 sync(feature = "sync"),
100 async(feature = "async")
101)]
102impl<I, A, C> crate::RegisterInterface for I2cDevice<I, A, C>
103where
104 I: hal::i2c::I2c<A> + hal::i2c::ErrorType,
105 A: hal::i2c::AddressMode + Copy,
106 C: Codec,
107{
108 type Error = I::Error;
109
110 #[inline]
114 async fn read_register<R>(&mut self) -> Result<R, I::Error>
115 where
116 R: ReadableRegister,
117 {
118 if TypeId::of::<R::I2cCodec>() == TypeId::of::<NoCodec>() {
119 C::read_register::<R, _, A>(&mut self.bound_bus).await
120 } else {
121 <R::I2cCodec as Codec>::read_register::<R, _, A>(&mut self.bound_bus).await
122 }
123 }
124
125 #[inline]
129 async fn write_register<R>(&mut self, register: impl AsRef<R>) -> Result<(), I::Error>
130 where
131 R: WritableRegister,
132 {
133 if TypeId::of::<R::I2cCodec>() == TypeId::of::<NoCodec>() {
134 C::write_register(&mut self.bound_bus, register).await
135 } else {
136 <R::I2cCodec as Codec>::write_register(&mut self.bound_bus, register).await
137 }
138 }
139}