pub mod codecs;
use core::{any::TypeId, marker::PhantomData};
use codecs::NoCodec;
use crate::{ReadableRegister, WritableRegister};
#[maybe_async_cfg::maybe(
idents(hal(sync = "embedded_hal", async = "embedded_hal_async")),
sync(feature = "sync"),
async(feature = "async")
)]
#[allow(async_fn_in_trait)]
pub trait Codec: 'static {
async fn read_register<R, I>(interface: &mut I) -> Result<R, I::Error>
where
R: ReadableRegister,
I: hal::spi::r#SpiDevice;
async fn write_register<R, I>(interface: &mut I, register: impl AsRef<R>) -> Result<(), I::Error>
where
R: WritableRegister,
I: hal::spi::r#SpiDevice;
}
#[maybe_async_cfg::maybe(
idents(hal(sync = "embedded_hal", async = "embedded_hal_async"), Codec),
sync(feature = "sync"),
async(feature = "async")
)]
pub struct SpiDevice<I, C>
where
I: hal::spi::r#SpiDevice,
C: Codec,
{
pub interface: I,
default_codec: PhantomData<C>,
}
#[maybe_async_cfg::maybe(
idents(hal(sync = "embedded_hal", async = "embedded_hal_async"), Codec),
sync(feature = "sync"),
async(feature = "async")
)]
impl<I, C> SpiDevice<I, C>
where
I: hal::spi::r#SpiDevice,
C: Codec,
{
pub fn new(interface: I) -> Self {
Self {
interface,
default_codec: Default::default(),
}
}
}
#[maybe_async_cfg::maybe(
idents(hal(sync = "embedded_hal", async = "embedded_hal_async"), Codec, RegisterInterface),
sync(feature = "sync"),
async(feature = "async")
)]
impl<I, C> crate::RegisterInterface for SpiDevice<I, C>
where
I: hal::spi::r#SpiDevice,
C: Codec,
{
type Error = I::Error;
#[inline]
async fn read_register<R>(&mut self) -> Result<R, I::Error>
where
R: ReadableRegister,
{
if TypeId::of::<R::SpiCodec>() == TypeId::of::<NoCodec>() {
C::read_register::<R, _>(&mut self.interface).await
} else {
<R::SpiCodec as Codec>::read_register::<R, _>(&mut self.interface).await
}
}
#[inline]
async fn write_register<R>(&mut self, register: impl AsRef<R>) -> Result<(), I::Error>
where
R: WritableRegister,
{
if TypeId::of::<R::SpiCodec>() == TypeId::of::<NoCodec>() {
C::write_register(&mut self.interface, register).await
} else {
<R::SpiCodec as Codec>::write_register(&mut self.interface, register).await
}
}
}