Skip to content

Commit

Permalink
optimized Spi::write
Browse files Browse the repository at this point in the history
  • Loading branch information
burrbull committed Aug 28, 2022
1 parent df01d0d commit 0f5cdc8
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Changed

- Optimized version of blocking SPI write
- Support `u16` read/write for SPI
- Use `bool` for BIDI mode type
- `PwmHz::get_period`: fix computation of return value, prevent division by zero
Expand Down
34 changes: 34 additions & 0 deletions src/spi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,40 @@ impl<SPI: Instance, PINS, const BIDI: bool, W: FrameSize, OPERATION>
nb::Error::WouldBlock
})
}

// Implement write as per the "Transmit only procedure"
// RM SPI::3.5. This is more than twice as fast as the
// default Write<> implementation (which reads and drops each
// received value)
fn spi_write<WI>(&mut self, words: WI) -> Result<(), Error>
where
WI: IntoIterator<Item = W>,
{
if BIDI {
self.spi.cr1.modify(|_, w| w.bidioe().set_bit());
}
// Write each word when the tx buffer is empty
for word in words {
loop {
let sr = self.spi.sr.read();
if sr.txe().bit_is_set() {
self.write_data_reg(word);
if sr.modf().bit_is_set() {
return Err(Error::ModeFault);
}
break;
}
}
}
// Wait for final TXE
while !self.is_tx_empty() {}
// Wait for final !BSY
while self.is_busy() {}
// Clear OVR set due to dropped received values
let _ = self.read_data_reg();
let _ = self.spi.sr.read();
Ok(())
}
}

// Spi DMA
Expand Down
11 changes: 2 additions & 9 deletions src/spi/hal_02.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ mod blocking {
type Error = Error;

fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
self.write_iter(words.iter().copied())
self.spi_write(words.iter().copied())
}
}

Expand All @@ -111,14 +111,7 @@ mod blocking {
where
WI: IntoIterator<Item = u8>,
{
for word in words.into_iter() {
nb::block!(self.send(word))?;
if !BIDI {
nb::block!(self.read())?;
}
}

Ok(())
self.spi_write(words)
}
}

Expand Down
9 changes: 1 addition & 8 deletions src/spi/hal_1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,7 @@ mod blocking {
SPI: Instance,
{
fn write(&mut self, words: &[W]) -> Result<(), Self::Error> {
for word in words {
nb::block!(<Self as FullDuplex<W>>::write(self, *word))?;
if !BIDI {
nb::block!(<Self as FullDuplex<W>>::read(self))?;
}
}

Ok(())
self.spi_write(words.iter().copied())
}
}

Expand Down

0 comments on commit 0f5cdc8

Please sign in to comment.