#![allow(async_fn_in_trait)]
#![cfg_attr(not(test), no_std)]
#![warn(missing_docs)]
#![doc = include_str!(concat!("../", env!("CARGO_PKG_README")))]
use core::fmt::{Debug, Display};
use core::marker::PhantomData;
mod buffer;
mod command;
mod fieldset;
mod register;
mod repeats;
pub use buffer::*;
pub use command::*;
pub use fieldset::*;
pub use register::*;
pub use repeats::*;
#[doc(hidden)]
pub mod ops;
#[cfg(feature = "macros")]
pub use device_driver_macros::*;
pub trait Block: Sized {
type Interface;
type RegisterAddressType: Address;
type CommandAddressType: Address;
type BufferAddressType: Address;
type RegisterAddressMode;
fn interface(&mut self) -> &mut Self::Interface;
fn bulk_read(
&mut self,
) -> register::BulkRegisterOperation<
'_,
Self,
<Self::Interface as RegisterInterfaceBase>::AddressType,
(),
RO,
>
where
Self::Interface: RegisterInterfaceBase,
Self::RegisterAddressMode: AddressMode,
{
register::BulkRegisterOperation {
block: self,
start_address: None,
next_address: None,
field_sets: (),
_phantom: PhantomData,
}
}
fn bulk_write(
&mut self,
) -> register::BulkRegisterOperation<
'_,
Self,
<Self::Interface as RegisterInterfaceBase>::AddressType,
(),
WO,
>
where
Self::Interface: RegisterInterfaceBase,
Self::RegisterAddressMode: AddressMode,
{
register::BulkRegisterOperation {
block: self,
start_address: None,
next_address: None,
field_sets: (),
_phantom: PhantomData,
}
}
fn bulk_modify(
&mut self,
) -> register::BulkRegisterOperation<
'_,
Self,
<Self::Interface as RegisterInterfaceBase>::AddressType,
(),
RW,
>
where
Self::Interface: RegisterInterfaceBase,
Self::RegisterAddressMode: AddressMode,
{
register::BulkRegisterOperation {
block: self,
start_address: None,
next_address: None,
field_sets: (),
_phantom: PhantomData,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum ByteOrder {
LE,
BE,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct ConversionError<T> {
pub source: T,
pub target: &'static str,
}
impl<T: Display> Display for ConversionError<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"Could not convert value from `{}` to type `{}`",
self.source, self.target
)
}
}
impl<T: Display + Debug> core::error::Error for ConversionError<T> {}
#[doc(hidden)]
pub struct WO;
#[doc(hidden)]
pub struct RO;
#[doc(hidden)]
pub struct RW;
#[doc(hidden)]
pub trait ReadCapability {}
#[doc(hidden)]
pub trait WriteCapability {}
impl WriteCapability for WO {}
impl ReadCapability for RO {}
impl WriteCapability for RW {}
impl ReadCapability for RW {}
trait SealedAddress {}
#[expect(private_bounds, reason = "sealed on purpose")]
#[cfg(feature = "defmt")]
pub trait Address: Copy + Eq + Display + Debug + defmt::Format + SealedAddress {
#[doc(hidden)]
const ZERO: Self;
#[doc(hidden)]
fn add(self, val: i32) -> Self;
}
#[expect(private_bounds, reason = "sealed on purpose")]
#[cfg(not(feature = "defmt"))]
pub trait Address: Copy + Eq + Display + Debug + SealedAddress {
#[doc(hidden)]
const ZERO: Self;
#[doc(hidden)]
fn add(self, val: i32) -> Self;
}
impl SealedAddress for u8 {}
impl Address for u8 {
const ZERO: Self = 0;
fn add(self, val: i32) -> Self {
(self as i32 + val).try_into().unwrap()
}
}
impl SealedAddress for u16 {}
impl Address for u16 {
const ZERO: Self = 0;
fn add(self, val: i32) -> Self {
(self as i32 + val).try_into().unwrap()
}
}
impl SealedAddress for u32 {}
impl Address for u32 {
const ZERO: Self = 0;
fn add(self, val: i32) -> Self {
self.checked_add_signed(val).unwrap()
}
}
impl SealedAddress for u64 {}
impl Address for u64 {
const ZERO: Self = 0;
fn add(self, val: i32) -> Self {
self.checked_add_signed(val as i64).unwrap()
}
}
impl SealedAddress for i8 {}
impl Address for i8 {
const ZERO: Self = 0;
fn add(self, val: i32) -> Self {
(self as i32 + val).try_into().unwrap()
}
}
impl SealedAddress for i16 {}
impl Address for i16 {
const ZERO: Self = 0;
fn add(self, val: i32) -> Self {
(self as i32 + val).try_into().unwrap()
}
}
impl SealedAddress for i32 {}
impl Address for i32 {
const ZERO: Self = 0;
fn add(self, val: i32) -> Self {
self + val
}
}
impl SealedAddress for i64 {}
impl Address for i64 {
const ZERO: Self = 0;
fn add(self, val: i32) -> Self {
self + val as i64
}
}
#[diagnostic::on_unimplemented(
message = "no `register-address-mode` is specified in the driver, so bulk register operations are not possible",
label = "not supported for this driver",
note = "if you are the author of the driver, specify `register-address-mode` in the device config to enable this feature if the device supports it",
note = "not all devices support this feature"
)]
#[doc(hidden)]
pub trait AddressMode {
#[doc(hidden)]
fn next_address<A: Address>(current_address: A, current_size: usize) -> A;
}
#[doc(hidden)]
pub struct MappedAddressMode;
impl AddressMode for MappedAddressMode {
#[inline]
fn next_address<A: Address>(current_address: A, current_size: usize) -> A {
current_address.add(current_size as i32)
}
}
#[doc(hidden)]
pub struct IndexedAddressMode;
impl AddressMode for IndexedAddressMode {
#[inline]
fn next_address<A: Address>(current_address: A, _current_size: usize) -> A {
current_address.add(1)
}
}