diff --git a/esp-hal/src/spi/master.rs b/esp-hal/src/spi/master.rs index d6caa89dfb8..4b71d41dcad 100644 --- a/esp-hal/src/spi/master.rs +++ b/esp-hal/src/spi/master.rs @@ -64,6 +64,7 @@ use super::{ HalfDuplexMode, IsFullDuplex, IsHalfDuplex, + SpiBitOrder, SpiDataMode, SpiMode, }; @@ -481,6 +482,14 @@ where self } + /// Set the bit order for the SPI instance. + /// + /// The default is MSB first for both read and write. + pub fn with_bit_order(mut self, read_order: SpiBitOrder, write_order: SpiBitOrder) -> Self { + self.spi.set_bit_order(read_order, write_order); + self + } + /// Setup pins for this SPI instance. /// /// All pins are optional. Pass [crate::gpio::NO_PIN] if you don't need the @@ -718,6 +727,14 @@ where pub fn change_bus_frequency(&mut self, frequency: HertzU32, clocks: &Clocks) { self.spi.ch_bus_freq(frequency, clocks); } + + /// Set the bit order for the SPI instance. + /// + /// The default is MSB first for both read and write. + pub fn with_bit_order(mut self, read_order: SpiBitOrder, write_order: SpiBitOrder) -> Self { + self.spi.set_bit_order(read_order, write_order); + self + } } impl HalfDuplexReadWrite for Spi<'_, T, M> @@ -2630,6 +2647,43 @@ pub trait Instance: crate::private::Sealed { }); } + #[cfg(not(any(esp32, esp32s2)))] + fn set_bit_order(&mut self, read_order: SpiBitOrder, write_order: SpiBitOrder) { + let reg_block = self.register_block(); + + let read_value = match read_order { + SpiBitOrder::MSBFirst => 0, + SpiBitOrder::LSBFirst => 1, + }; + let write_value = match write_order { + SpiBitOrder::MSBFirst => 0, + SpiBitOrder::LSBFirst => 1, + }; + reg_block.ctrl().modify(|_, w| unsafe { + w.rd_bit_order().bits(read_value); + w.wr_bit_order().bits(write_value); + w + }); + } + #[cfg(any(esp32, esp32s2))] + fn set_bit_order(&mut self, read_order: SpiBitOrder, write_order: SpiBitOrder) { + let reg_block = self.register_block(); + + let read_value = match read_order { + SpiBitOrder::MSBFirst => false, + SpiBitOrder::LSBFirst => true, + }; + let write_value = match write_order { + SpiBitOrder::MSBFirst => false, + SpiBitOrder::LSBFirst => true, + }; + reg_block.ctrl().modify(|_, w| unsafe { + w.rd_bit_order().bit(read_value); + w.wr_bit_order().bit(write_value); + w + }); + } + fn read_byte(&mut self) -> nb::Result { if self.busy() { return Err(nb::Error::WouldBlock); diff --git a/esp-hal/src/spi/mod.rs b/esp-hal/src/spi/mod.rs index ae9fd6eb47b..1236b6e7510 100644 --- a/esp-hal/src/spi/mod.rs +++ b/esp-hal/src/spi/mod.rs @@ -44,6 +44,14 @@ pub enum SpiMode { Mode3, } +/// SPI Bit Order +#[derive(Debug, Clone, Copy, PartialEq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum SpiBitOrder { + MSBFirst, + LSBFirst, +} + pub trait DuplexMode {} pub trait IsFullDuplex: DuplexMode {} pub trait IsHalfDuplex: DuplexMode {}