Skip to content

Commit

Permalink
feat(embedded-hal-bus): Spi - Add support for cs to clock delay
Browse files Browse the repository at this point in the history
  • Loading branch information
vchapuis committed May 31, 2024
1 parent a0ccb65 commit e7fe105
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 15 deletions.
25 changes: 22 additions & 3 deletions embedded-hal-bus/src/spi/atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ pub struct AtomicDevice<'a, BUS, CS, D> {
bus: &'a AtomicCell<BUS>,
cs: CS,
delay: D,
/// Implementation of <https://docs.rs/embedded-hal/latest/embedded_hal/spi/index.html#cs-to-clock-delays>
cs_to_clock_delay_ns: u32,
}

#[derive(Debug, Copy, Clone)]
Expand All @@ -50,12 +52,22 @@ impl<'a, BUS, CS, D> AtomicDevice<'a, BUS, CS, D> {
/// This sets the `cs` pin high, and returns an error if that fails. It is recommended
/// to set the pin high the moment it's configured as an output, to avoid glitches.
#[inline]
pub fn new(bus: &'a AtomicCell<BUS>, mut cs: CS, delay: D) -> Result<Self, CS::Error>
pub fn new(
bus: &'a AtomicCell<BUS>,
mut cs: CS,
delay: D,
cs_to_clock_delay_ns: u32,
) -> Result<Self, CS::Error>
where
CS: OutputPin,
{
cs.set_high()?;
Ok(Self { bus, cs, delay })
Ok(Self {
bus,
cs,
delay,
cs_to_clock_delay_ns,
})
}
}

Expand Down Expand Up @@ -93,6 +105,7 @@ where
bus,
cs,
delay: super::NoDelay,
cs_to_clock_delay_ns: 0,
})
}
}
Expand Down Expand Up @@ -134,7 +147,13 @@ where

let bus = unsafe { &mut *self.bus.bus.get() };

let result = transaction(operations, bus, &mut self.delay, &mut self.cs);
let result = transaction(
operations,
bus,
&mut self.delay,
&mut self.cs,
self.cs_to_clock_delay_ns,
);

self.bus
.busy
Expand Down
25 changes: 22 additions & 3 deletions embedded-hal-bus/src/spi/critical_section.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ pub struct CriticalSectionDevice<'a, BUS, CS, D> {
bus: &'a Mutex<RefCell<BUS>>,
cs: CS,
delay: D,
/// Implementation of <https://docs.rs/embedded-hal/latest/embedded_hal/spi/index.html#cs-to-clock-delays>
cs_to_clock_delay_ns: u32,
}

impl<'a, BUS, CS, D> CriticalSectionDevice<'a, BUS, CS, D> {
Expand All @@ -29,12 +31,22 @@ impl<'a, BUS, CS, D> CriticalSectionDevice<'a, BUS, CS, D> {
/// This sets the `cs` pin high, and returns an error if that fails. It is recommended
/// to set the pin high the moment it's configured as an output, to avoid glitches.
#[inline]
pub fn new(bus: &'a Mutex<RefCell<BUS>>, mut cs: CS, delay: D) -> Result<Self, CS::Error>
pub fn new(
bus: &'a Mutex<RefCell<BUS>>,
mut cs: CS,
delay: D,
cs_to_clock_delay_ns: u32,
) -> Result<Self, CS::Error>
where
CS: OutputPin,
{
cs.set_high()?;
Ok(Self { bus, cs, delay })
Ok(Self {
bus,
cs,
delay,
cs_to_clock_delay_ns,
})
}
}

Expand Down Expand Up @@ -68,6 +80,7 @@ impl<'a, BUS, CS> CriticalSectionDevice<'a, BUS, CS, super::NoDelay> {
bus,
cs,
delay: super::NoDelay,
cs_to_clock_delay_ns: 0,
})
}
}
Expand All @@ -91,7 +104,13 @@ where
critical_section::with(|cs| {
let bus = &mut *self.bus.borrow_ref_mut(cs);

transaction(operations, bus, &mut self.delay, &mut self.cs)
transaction(
operations,
bus,
&mut self.delay,
&mut self.cs,
self.cs_to_clock_delay_ns,
)
})
}
}
20 changes: 17 additions & 3 deletions embedded-hal-bus/src/spi/exclusive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ pub struct ExclusiveDevice<BUS, CS, D> {
bus: BUS,
cs: CS,
delay: D,
/// Implementation of <https://docs.rs/embedded-hal/latest/embedded_hal/spi/index.html#cs-to-clock-delays>
cs_to_clock_delay_ns: u32,
}

impl<BUS, CS, D> ExclusiveDevice<BUS, CS, D> {
Expand All @@ -28,12 +30,17 @@ impl<BUS, CS, D> ExclusiveDevice<BUS, CS, D> {
/// This sets the `cs` pin high, and returns an error if that fails. It is recommended
/// to set the pin high the moment it's configured as an output, to avoid glitches.
#[inline]
pub fn new(bus: BUS, mut cs: CS, delay: D) -> Result<Self, CS::Error>
pub fn new(bus: BUS, mut cs: CS, delay: D, cs_to_clock_delay_ns: u32) -> Result<Self, CS::Error>
where
CS: OutputPin,
{
cs.set_high()?;
Ok(Self { bus, cs, delay })
Ok(Self {
bus,
cs,
delay,
cs_to_clock_delay_ns,
})
}

/// Returns a reference to the underlying bus object.
Expand Down Expand Up @@ -79,6 +86,7 @@ impl<BUS, CS> ExclusiveDevice<BUS, CS, super::NoDelay> {
bus,
cs,
delay: super::NoDelay,
cs_to_clock_delay_ns: 0,
})
}
}
Expand All @@ -99,7 +107,13 @@ where
{
#[inline]
fn transaction(&mut self, operations: &mut [Operation<'_, Word>]) -> Result<(), Self::Error> {
transaction(operations, &mut self.bus, &mut self.delay, &mut self.cs)
transaction(
operations,
&mut self.bus,
&mut self.delay,
&mut self.cs,
self.cs_to_clock_delay_ns,
)
}
}

Expand Down
25 changes: 22 additions & 3 deletions embedded-hal-bus/src/spi/mutex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ pub struct MutexDevice<'a, BUS, CS, D> {
bus: &'a Mutex<BUS>,
cs: CS,
delay: D,
/// Implementation of <https://docs.rs/embedded-hal/latest/embedded_hal/spi/index.html#cs-to-clock-delays>
cs_to_clock_delay_ns: u32,
}

impl<'a, BUS, CS, D> MutexDevice<'a, BUS, CS, D> {
Expand All @@ -27,12 +29,22 @@ impl<'a, BUS, CS, D> MutexDevice<'a, BUS, CS, D> {
/// This sets the `cs` pin high, and returns an error if that fails. It is recommended
/// to set the pin high the moment it's configured as an output, to avoid glitches.
#[inline]
pub fn new(bus: &'a Mutex<BUS>, mut cs: CS, delay: D) -> Result<Self, CS::Error>
pub fn new(
bus: &'a Mutex<BUS>,
mut cs: CS,
delay: D,
cs_to_clock_delay_ns: u32,
) -> Result<Self, CS::Error>
where
CS: OutputPin,
{
cs.set_high()?;
Ok(Self { bus, cs, delay })
Ok(Self {
bus,
cs,
delay,
cs_to_clock_delay_ns,
})
}
}

Expand Down Expand Up @@ -66,6 +78,7 @@ impl<'a, BUS, CS> MutexDevice<'a, BUS, CS, super::NoDelay> {
bus,
cs,
delay: super::NoDelay,
cs_to_clock_delay_ns: 0,
})
}
}
Expand All @@ -88,6 +101,12 @@ where
fn transaction(&mut self, operations: &mut [Operation<'_, Word>]) -> Result<(), Self::Error> {
let bus = &mut *self.bus.lock().unwrap();

transaction(operations, bus, &mut self.delay, &mut self.cs)
transaction(
operations,
bus,
&mut self.delay,
&mut self.cs,
self.cs_to_clock_delay_ns,
)
}
}
25 changes: 22 additions & 3 deletions embedded-hal-bus/src/spi/refcell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ pub struct RefCellDevice<'a, BUS, CS, D> {
bus: &'a RefCell<BUS>,
cs: CS,
delay: D,
/// Implementation of <https://docs.rs/embedded-hal/latest/embedded_hal/spi/index.html#cs-to-clock-delays>
cs_to_clock_delay_ns: u32,
}

impl<'a, BUS, CS, D> RefCellDevice<'a, BUS, CS, D> {
Expand All @@ -26,12 +28,22 @@ impl<'a, BUS, CS, D> RefCellDevice<'a, BUS, CS, D> {
/// This sets the `cs` pin high, and returns an error if that fails. It is recommended
/// to set the pin high the moment it's configured as an output, to avoid glitches.
#[inline]
pub fn new(bus: &'a RefCell<BUS>, mut cs: CS, delay: D) -> Result<Self, CS::Error>
pub fn new(
bus: &'a RefCell<BUS>,
mut cs: CS,
delay: D,
cs_to_clock_delay_ns: u32,
) -> Result<Self, CS::Error>
where
CS: OutputPin,
{
cs.set_high()?;
Ok(Self { bus, cs, delay })
Ok(Self {
bus,
cs,
delay,
cs_to_clock_delay_ns,
})
}
}

Expand Down Expand Up @@ -65,6 +77,7 @@ impl<'a, BUS, CS> RefCellDevice<'a, BUS, CS, super::NoDelay> {
bus,
cs,
delay: super::NoDelay,
cs_to_clock_delay_ns: 0,
})
}
}
Expand All @@ -87,6 +100,12 @@ where
fn transaction(&mut self, operations: &mut [Operation<'_, Word>]) -> Result<(), Self::Error> {
let bus = &mut *self.bus.borrow_mut();

transaction(operations, bus, &mut self.delay, &mut self.cs)
transaction(
operations,
bus,
&mut self.delay,
&mut self.cs,
self.cs_to_clock_delay_ns,
)
}
}
4 changes: 4 additions & 0 deletions embedded-hal-bus/src/spi/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub fn transaction<Word, BUS, CS, D>(
bus: &mut BUS,
delay: &mut D,
cs: &mut CS,
cs_to_clock_delay_ns: u32,
) -> Result<(), DeviceError<BUS::Error, CS::Error>>
where
BUS: SpiBus<Word> + ErrorType,
Expand All @@ -19,6 +20,9 @@ where
Word: Copy,
{
cs.set_low().map_err(DeviceError::Cs)?;
if cs_to_clock_delay_ns > 0 {
delay.delay_ns(cs_to_clock_delay_ns);
}

let op_res = operations.iter_mut().try_for_each(|op| match op {
Operation::Read(buf) => bus.read(buf),
Expand Down

0 comments on commit e7fe105

Please sign in to comment.