embedded_registers/spi/
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")),
15 sync(feature = "sync"),
16 async(feature = "async")
17)]
18#[allow(async_fn_in_trait)]
19pub trait Codec: 'static {
20 async fn read_register<R, I>(interface: &mut I) -> Result<R, I::Error>
22 where
23 R: ReadableRegister,
24 I: hal::spi::r#SpiDevice;
25
26 async fn write_register<R, I>(interface: &mut I, register: impl AsRef<R>) -> Result<(), I::Error>
28 where
29 R: WritableRegister,
30 I: hal::spi::r#SpiDevice;
31}
32
33#[maybe_async_cfg::maybe(
34 idents(hal(sync = "embedded_hal", async = "embedded_hal_async"), Codec),
35 sync(feature = "sync"),
36 async(feature = "async")
37)]
38pub struct SpiDevice<I, C>
40where
41 I: hal::spi::r#SpiDevice,
42 C: Codec,
43{
44 pub interface: I,
46 default_codec: PhantomData<C>,
51}
52
53#[maybe_async_cfg::maybe(
54 idents(hal(sync = "embedded_hal", async = "embedded_hal_async"), Codec),
55 sync(feature = "sync"),
56 async(feature = "async")
57)]
58impl<I, C> SpiDevice<I, C>
59where
60 I: hal::spi::r#SpiDevice,
61 C: Codec,
62{
63 pub fn new(interface: I) -> Self {
65 Self {
66 interface,
67 default_codec: Default::default(),
68 }
69 }
70}
71
72#[maybe_async_cfg::maybe(
73 idents(hal(sync = "embedded_hal", async = "embedded_hal_async"), Codec, RegisterInterface),
74 sync(feature = "sync"),
75 async(feature = "async")
76)]
77impl<I, C> crate::RegisterInterface for SpiDevice<I, C>
78where
79 I: hal::spi::r#SpiDevice,
80 C: Codec,
81{
82 type Error = I::Error;
83
84 #[inline]
88 async fn read_register<R>(&mut self) -> Result<R, I::Error>
89 where
90 R: ReadableRegister,
91 {
92 if TypeId::of::<R::SpiCodec>() == TypeId::of::<NoCodec>() {
93 C::read_register::<R, _>(&mut self.interface).await
94 } else {
95 <R::SpiCodec as Codec>::read_register::<R, _>(&mut self.interface).await
96 }
97 }
98
99 #[inline]
103 async fn write_register<R>(&mut self, register: impl AsRef<R>) -> Result<(), I::Error>
104 where
105 R: WritableRegister,
106 {
107 if TypeId::of::<R::SpiCodec>() == TypeId::of::<NoCodec>() {
108 C::write_register(&mut self.interface, register).await
109 } else {
110 <R::SpiCodec as Codec>::write_register(&mut self.interface, register).await
111 }
112 }
113}