1#[cfg(esp32)]
38use core::cell::Cell;
39use core::{
40 cell::UnsafeCell,
41 future::Future,
42 marker::PhantomData,
43 mem::MaybeUninit,
44 pin::Pin,
45 task::{Context, Poll},
46};
47
48#[cfg(spi_master_supports_dma)]
49mod dma;
50
51#[instability::unstable]
52#[cfg(spi_master_supports_dma)]
53pub use dma::*;
54use embedded_hal::spi::SpiBus;
55use embedded_hal_async::spi::SpiBus as SpiBusAsync;
56use enumset::{EnumSet, EnumSetType, enum_set};
57use procmacros::doc_replace;
58
59use super::{BitOrder, Error, Mode};
60use crate::{
61 Async,
62 Blocking,
63 DriverMode,
64 RegisterToggle,
65 asynch::AtomicWaker,
66 clock::Clocks,
67 gpio::{
68 InputConfig,
69 InputSignal,
70 NoPin,
71 OutputConfig,
72 OutputSignal,
73 PinGuard,
74 interconnect::{self, PeripheralInput, PeripheralOutput},
75 },
76 handler,
77 interrupt::InterruptHandler,
78 pac::spi2::RegisterBlock,
79 private::{self, DropGuard, Sealed},
80 ram,
81 system::PeripheralGuard,
82 time::Rate,
83};
84
85#[derive(Debug, Hash, EnumSetType)]
87#[cfg_attr(feature = "defmt", derive(defmt::Format))]
88#[non_exhaustive]
89#[instability::unstable]
90pub enum SpiInterrupt {
91 TransferDone,
96
97 #[cfg(spi_master_has_dma_segmented_transfer)]
99 DmaSegmentedTransferDone,
100
101 #[cfg(spi_master_has_app_interrupts)]
103 App2,
104
105 #[cfg(spi_master_has_app_interrupts)]
107 App1,
108}
109
110const FIFO_SIZE: usize = if cfg!(esp32s2) { 72 } else { 64 };
112
113const EMPTY_WRITE_PAD: u8 = 0x00;
115
116#[non_exhaustive]
121#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
122#[cfg_attr(feature = "defmt", derive(defmt::Format))]
123#[instability::unstable]
124pub enum Command {
125 None,
127 _1Bit(u16, DataMode),
129 _2Bit(u16, DataMode),
131 _3Bit(u16, DataMode),
133 _4Bit(u16, DataMode),
135 _5Bit(u16, DataMode),
137 _6Bit(u16, DataMode),
139 _7Bit(u16, DataMode),
141 _8Bit(u16, DataMode),
143 _9Bit(u16, DataMode),
145 _10Bit(u16, DataMode),
147 _11Bit(u16, DataMode),
149 _12Bit(u16, DataMode),
151 _13Bit(u16, DataMode),
153 _14Bit(u16, DataMode),
155 _15Bit(u16, DataMode),
157 _16Bit(u16, DataMode),
159}
160
161impl Command {
162 fn width(&self) -> usize {
163 match self {
164 Command::None => 0,
165 Command::_1Bit(_, _) => 1,
166 Command::_2Bit(_, _) => 2,
167 Command::_3Bit(_, _) => 3,
168 Command::_4Bit(_, _) => 4,
169 Command::_5Bit(_, _) => 5,
170 Command::_6Bit(_, _) => 6,
171 Command::_7Bit(_, _) => 7,
172 Command::_8Bit(_, _) => 8,
173 Command::_9Bit(_, _) => 9,
174 Command::_10Bit(_, _) => 10,
175 Command::_11Bit(_, _) => 11,
176 Command::_12Bit(_, _) => 12,
177 Command::_13Bit(_, _) => 13,
178 Command::_14Bit(_, _) => 14,
179 Command::_15Bit(_, _) => 15,
180 Command::_16Bit(_, _) => 16,
181 }
182 }
183
184 fn value(&self) -> u16 {
185 match self {
186 Command::None => 0,
187 Command::_1Bit(value, _)
188 | Command::_2Bit(value, _)
189 | Command::_3Bit(value, _)
190 | Command::_4Bit(value, _)
191 | Command::_5Bit(value, _)
192 | Command::_6Bit(value, _)
193 | Command::_7Bit(value, _)
194 | Command::_8Bit(value, _)
195 | Command::_9Bit(value, _)
196 | Command::_10Bit(value, _)
197 | Command::_11Bit(value, _)
198 | Command::_12Bit(value, _)
199 | Command::_13Bit(value, _)
200 | Command::_14Bit(value, _)
201 | Command::_15Bit(value, _)
202 | Command::_16Bit(value, _) => *value,
203 }
204 }
205
206 fn mode(&self) -> DataMode {
207 match self {
208 Command::None => DataMode::SingleTwoDataLines,
209 Command::_1Bit(_, mode)
210 | Command::_2Bit(_, mode)
211 | Command::_3Bit(_, mode)
212 | Command::_4Bit(_, mode)
213 | Command::_5Bit(_, mode)
214 | Command::_6Bit(_, mode)
215 | Command::_7Bit(_, mode)
216 | Command::_8Bit(_, mode)
217 | Command::_9Bit(_, mode)
218 | Command::_10Bit(_, mode)
219 | Command::_11Bit(_, mode)
220 | Command::_12Bit(_, mode)
221 | Command::_13Bit(_, mode)
222 | Command::_14Bit(_, mode)
223 | Command::_15Bit(_, mode)
224 | Command::_16Bit(_, mode) => *mode,
225 }
226 }
227
228 fn is_none(&self) -> bool {
229 matches!(self, Command::None)
230 }
231}
232
233#[non_exhaustive]
238#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
239#[cfg_attr(feature = "defmt", derive(defmt::Format))]
240#[instability::unstable]
241pub enum Address {
242 None,
244 _1Bit(u32, DataMode),
246 _2Bit(u32, DataMode),
248 _3Bit(u32, DataMode),
250 _4Bit(u32, DataMode),
252 _5Bit(u32, DataMode),
254 _6Bit(u32, DataMode),
256 _7Bit(u32, DataMode),
258 _8Bit(u32, DataMode),
260 _9Bit(u32, DataMode),
262 _10Bit(u32, DataMode),
264 _11Bit(u32, DataMode),
266 _12Bit(u32, DataMode),
268 _13Bit(u32, DataMode),
270 _14Bit(u32, DataMode),
272 _15Bit(u32, DataMode),
274 _16Bit(u32, DataMode),
276 _17Bit(u32, DataMode),
278 _18Bit(u32, DataMode),
280 _19Bit(u32, DataMode),
282 _20Bit(u32, DataMode),
284 _21Bit(u32, DataMode),
286 _22Bit(u32, DataMode),
288 _23Bit(u32, DataMode),
290 _24Bit(u32, DataMode),
292 _25Bit(u32, DataMode),
294 _26Bit(u32, DataMode),
296 _27Bit(u32, DataMode),
298 _28Bit(u32, DataMode),
300 _29Bit(u32, DataMode),
302 _30Bit(u32, DataMode),
304 _31Bit(u32, DataMode),
306 _32Bit(u32, DataMode),
308}
309
310impl Address {
311 fn width(&self) -> usize {
312 match self {
313 Address::None => 0,
314 Address::_1Bit(_, _) => 1,
315 Address::_2Bit(_, _) => 2,
316 Address::_3Bit(_, _) => 3,
317 Address::_4Bit(_, _) => 4,
318 Address::_5Bit(_, _) => 5,
319 Address::_6Bit(_, _) => 6,
320 Address::_7Bit(_, _) => 7,
321 Address::_8Bit(_, _) => 8,
322 Address::_9Bit(_, _) => 9,
323 Address::_10Bit(_, _) => 10,
324 Address::_11Bit(_, _) => 11,
325 Address::_12Bit(_, _) => 12,
326 Address::_13Bit(_, _) => 13,
327 Address::_14Bit(_, _) => 14,
328 Address::_15Bit(_, _) => 15,
329 Address::_16Bit(_, _) => 16,
330 Address::_17Bit(_, _) => 17,
331 Address::_18Bit(_, _) => 18,
332 Address::_19Bit(_, _) => 19,
333 Address::_20Bit(_, _) => 20,
334 Address::_21Bit(_, _) => 21,
335 Address::_22Bit(_, _) => 22,
336 Address::_23Bit(_, _) => 23,
337 Address::_24Bit(_, _) => 24,
338 Address::_25Bit(_, _) => 25,
339 Address::_26Bit(_, _) => 26,
340 Address::_27Bit(_, _) => 27,
341 Address::_28Bit(_, _) => 28,
342 Address::_29Bit(_, _) => 29,
343 Address::_30Bit(_, _) => 30,
344 Address::_31Bit(_, _) => 31,
345 Address::_32Bit(_, _) => 32,
346 }
347 }
348
349 fn value(&self) -> u32 {
350 match self {
351 Address::None => 0,
352 Address::_1Bit(value, _)
353 | Address::_2Bit(value, _)
354 | Address::_3Bit(value, _)
355 | Address::_4Bit(value, _)
356 | Address::_5Bit(value, _)
357 | Address::_6Bit(value, _)
358 | Address::_7Bit(value, _)
359 | Address::_8Bit(value, _)
360 | Address::_9Bit(value, _)
361 | Address::_10Bit(value, _)
362 | Address::_11Bit(value, _)
363 | Address::_12Bit(value, _)
364 | Address::_13Bit(value, _)
365 | Address::_14Bit(value, _)
366 | Address::_15Bit(value, _)
367 | Address::_16Bit(value, _)
368 | Address::_17Bit(value, _)
369 | Address::_18Bit(value, _)
370 | Address::_19Bit(value, _)
371 | Address::_20Bit(value, _)
372 | Address::_21Bit(value, _)
373 | Address::_22Bit(value, _)
374 | Address::_23Bit(value, _)
375 | Address::_24Bit(value, _)
376 | Address::_25Bit(value, _)
377 | Address::_26Bit(value, _)
378 | Address::_27Bit(value, _)
379 | Address::_28Bit(value, _)
380 | Address::_29Bit(value, _)
381 | Address::_30Bit(value, _)
382 | Address::_31Bit(value, _)
383 | Address::_32Bit(value, _) => *value,
384 }
385 }
386
387 fn is_none(&self) -> bool {
388 matches!(self, Address::None)
389 }
390
391 fn mode(&self) -> DataMode {
392 match self {
393 Address::None => DataMode::SingleTwoDataLines,
394 Address::_1Bit(_, mode)
395 | Address::_2Bit(_, mode)
396 | Address::_3Bit(_, mode)
397 | Address::_4Bit(_, mode)
398 | Address::_5Bit(_, mode)
399 | Address::_6Bit(_, mode)
400 | Address::_7Bit(_, mode)
401 | Address::_8Bit(_, mode)
402 | Address::_9Bit(_, mode)
403 | Address::_10Bit(_, mode)
404 | Address::_11Bit(_, mode)
405 | Address::_12Bit(_, mode)
406 | Address::_13Bit(_, mode)
407 | Address::_14Bit(_, mode)
408 | Address::_15Bit(_, mode)
409 | Address::_16Bit(_, mode)
410 | Address::_17Bit(_, mode)
411 | Address::_18Bit(_, mode)
412 | Address::_19Bit(_, mode)
413 | Address::_20Bit(_, mode)
414 | Address::_21Bit(_, mode)
415 | Address::_22Bit(_, mode)
416 | Address::_23Bit(_, mode)
417 | Address::_24Bit(_, mode)
418 | Address::_25Bit(_, mode)
419 | Address::_26Bit(_, mode)
420 | Address::_27Bit(_, mode)
421 | Address::_28Bit(_, mode)
422 | Address::_29Bit(_, mode)
423 | Address::_30Bit(_, mode)
424 | Address::_31Bit(_, mode)
425 | Address::_32Bit(_, mode) => *mode,
426 }
427 }
428}
429
430#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
432#[cfg_attr(feature = "defmt", derive(defmt::Format))]
433#[instability::unstable]
434pub enum ClockSource {
435 Apb,
437 }
440
441#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, procmacros::BuilderLite)]
443#[cfg_attr(feature = "defmt", derive(defmt::Format))]
444#[non_exhaustive]
445pub struct Config {
446 #[builder_lite(skip)]
457 reg: Result<u32, ConfigError>,
458
459 #[builder_lite(skip_setter)]
461 frequency: Rate,
462
463 #[builder_lite(unstable)]
465 #[builder_lite(skip_setter)]
466 clock_source: ClockSource,
467
468 mode: Mode,
470
471 read_bit_order: BitOrder,
473
474 write_bit_order: BitOrder,
476}
477
478impl Default for Config {
479 fn default() -> Self {
480 let mut this = Config {
481 reg: Ok(0),
482 frequency: Rate::from_mhz(1),
483 clock_source: ClockSource::Apb,
484 mode: Mode::_0,
485 read_bit_order: BitOrder::MsbFirst,
486 write_bit_order: BitOrder::MsbFirst,
487 };
488
489 this.reg = this.recalculate();
490
491 this
492 }
493}
494
495impl Config {
496 pub fn with_frequency(mut self, frequency: Rate) -> Self {
498 self.frequency = frequency;
499 self.reg = self.recalculate();
500
501 self
502 }
503
504 #[instability::unstable]
506 pub fn with_clock_source(mut self, clock_source: ClockSource) -> Self {
507 self.clock_source = clock_source;
508 self.reg = self.recalculate();
509
510 self
511 }
512
513 fn clock_source_freq_hz(&self) -> Rate {
514 let clocks = Clocks::get();
515
516 cfg_if::cfg_if! {
518 if #[cfg(esp32h2)] {
519 let _clocks = clocks;
521 Rate::from_mhz(48)
522 } else if #[cfg(any(esp32c5, esp32c61))] {
523 let _clocks = clocks;
526 Rate::from_mhz(80) } else if #[cfg(esp32c6)] {
528 let _clocks = clocks;
531 Rate::from_mhz(80)
532 } else {
533 clocks.apb_clock
534 }
535 }
536 }
537
538 fn recalculate(&self) -> Result<u32, ConfigError> {
539 let source_freq = self.clock_source_freq_hz();
541
542 let reg_val: u32;
543 let duty_cycle = 128;
544
545 if self.frequency > ((source_freq / 4) * 3) {
549 reg_val = 1 << 31;
551 } else {
552 let mut pre: i32;
560 let mut bestn: i32 = -1;
561 let mut bestpre: i32 = -1;
562 let mut besterr: i32 = 0;
563 let mut errval: i32;
564
565 let target_freq_hz = self.frequency.as_hz() as i32;
566 let source_freq_hz = source_freq.as_hz() as i32;
567
568 for n in 2..=64 {
572 pre = ((source_freq_hz / n) + (target_freq_hz / 2)) / target_freq_hz;
576
577 if pre <= 0 {
578 pre = 1;
579 }
580
581 if pre > 16 {
582 pre = 16;
583 }
584
585 errval = (source_freq_hz / (pre * n) - target_freq_hz).abs();
586 if bestn == -1 || errval <= besterr {
587 besterr = errval;
588 bestn = n;
589 bestpre = pre;
590 }
591 }
592
593 let n: i32 = bestn;
594 pre = bestpre;
595 let l: i32 = n;
596
597 let mut h: i32 = (duty_cycle * n + 127) / 256;
601 if h <= 0 {
602 h = 1;
603 }
604
605 reg_val = (l as u32 - 1)
606 | ((h as u32 - 1) << 6)
607 | ((n as u32 - 1) << 12)
608 | ((pre as u32 - 1) << 18);
609 }
610
611 Ok(reg_val)
612 }
613
614 fn raw_clock_reg_value(&self) -> Result<u32, ConfigError> {
615 self.reg
616 }
617
618 fn validate(&self) -> Result<(), ConfigError> {
619 let source_freq = self.clock_source_freq_hz();
620 let min_divider = 1;
621 let max_divider = 16 * 64; if self.frequency < source_freq / max_divider || self.frequency > source_freq / min_divider
626 {
627 return Err(ConfigError::FrequencyOutOfRange);
628 }
629
630 Ok(())
631 }
632}
633
634const SIO_PIN_COUNT: usize = 4 + cfg!(spi_master_has_octal) as usize * 4;
635
636#[derive(Debug)]
637#[cfg_attr(feature = "defmt", derive(defmt::Format))]
638struct SpiPinGuard {
639 sclk_pin: PinGuard,
640 cs_pin: PinGuard,
641 sio_pins: [PinGuard; SIO_PIN_COUNT],
642}
643
644impl SpiPinGuard {
645 const fn new_unconnected() -> Self {
646 Self {
647 sclk_pin: PinGuard::new_unconnected(),
648 cs_pin: PinGuard::new_unconnected(),
649 sio_pins: [const { PinGuard::new_unconnected() }; SIO_PIN_COUNT],
650 }
651 }
652}
653
654#[non_exhaustive]
656#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
657#[cfg_attr(feature = "defmt", derive(defmt::Format))]
658pub enum ConfigError {
659 FrequencyOutOfRange,
661}
662
663impl core::error::Error for ConfigError {}
664
665impl core::fmt::Display for ConfigError {
666 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
667 match self {
668 ConfigError::FrequencyOutOfRange => {
669 write!(f, "The requested frequency is not in the supported range")
670 }
671 }
672 }
673}
674
675#[derive(Debug)]
676#[cfg_attr(feature = "defmt", derive(defmt::Format))]
677struct SpiWrapper<'d> {
678 spi: AnySpi<'d>,
679 _guard: PeripheralGuard,
680}
681
682impl<'d> SpiWrapper<'d> {
683 fn new(spi: impl Instance + 'd) -> Self {
684 let p = spi.info().peripheral;
685 let this = Self {
686 spi: spi.degrade(),
687 _guard: PeripheralGuard::new(p),
688 };
689
690 unsafe {
692 this.state()
693 .pins
694 .get()
695 .write(MaybeUninit::new(SpiPinGuard::new_unconnected()))
696 }
697
698 this
699 }
700
701 fn info(&self) -> &'static Info {
702 self.spi.info()
703 }
704
705 fn state(&self) -> &'static State {
706 self.spi.state()
707 }
708
709 fn disable_peri_interrupt_on_all_cores(&self) {
710 self.spi.disable_peri_interrupt_on_all_cores();
711 }
712
713 fn set_interrupt_handler(&self, handler: InterruptHandler) {
714 self.spi.set_interrupt_handler(handler);
715 }
716
717 fn pins(&mut self) -> &mut SpiPinGuard {
718 unsafe {
719 self.state().pins()
721 }
722 }
723}
724
725impl Drop for SpiWrapper<'_> {
726 fn drop(&mut self) {
727 unsafe {
728 self.spi.state().deinit();
730 }
731 }
732}
733
734#[procmacros::doc_replace]
735#[derive(Debug)]
757#[cfg_attr(feature = "defmt", derive(defmt::Format))]
758pub struct Spi<'d, Dm: DriverMode> {
759 spi: SpiWrapper<'d>,
760 _mode: PhantomData<Dm>,
761}
762
763impl<Dm: DriverMode> Sealed for Spi<'_, Dm> {}
764
765impl<'d> Spi<'d, Blocking> {
766 #[procmacros::doc_replace]
767 pub fn new(spi: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
788 let mut this = Spi {
789 _mode: PhantomData,
790 spi: SpiWrapper::new(spi),
791 };
792
793 this.driver().init();
794 this.apply_config(&config)?;
795
796 let this = this.with_sck(NoPin).with_cs(NoPin);
797
798 for sio in 0..8 {
799 if let Some(signal) = this.driver().info.opt_sio_input(sio) {
800 signal.connect_to(&NoPin);
801 }
802 if let Some(signal) = this.driver().info.opt_sio_output(sio) {
803 signal.connect_to(&NoPin);
804 }
805 }
806
807 Ok(this)
808 }
809
810 pub fn into_async(mut self) -> Spi<'d, Async> {
815 self.set_interrupt_handler(self.spi.info().async_handler);
816 Spi {
817 spi: self.spi,
818 _mode: PhantomData,
819 }
820 }
821
822 #[doc_replace(
823 "peripheral_on" => {
824 cfg(multi_core) => "peripheral on the current core",
825 _ => "peripheral",
826 }
827 )]
828 #[instability::unstable]
841 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
842 self.spi.set_interrupt_handler(handler);
843 }
844}
845
846#[instability::unstable]
847impl crate::interrupt::InterruptConfigurable for Spi<'_, Blocking> {
848 fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
852 self.set_interrupt_handler(handler);
853 }
854}
855
856impl<'d> Spi<'d, Async> {
857 pub fn into_blocking(self) -> Spi<'d, Blocking> {
862 self.spi.disable_peri_interrupt_on_all_cores();
863 Spi {
864 spi: self.spi,
865 _mode: PhantomData,
866 }
867 }
868
869 #[procmacros::doc_replace]
870 pub async fn flush_async(&mut self) -> Result<(), Error> {
893 self.driver().flush_async().await;
894 Ok(())
895 }
896
897 #[procmacros::doc_replace]
898 pub async fn transfer_in_place_async(&mut self, words: &mut [u8]) -> Result<(), Error> {
925 self.driver().flush_async().await;
928 self.driver().setup_full_duplex()?;
929
930 self.driver().transfer_in_place_async(words).await
931 }
932
933 async fn read_async(&mut self, words: &mut [u8]) -> Result<(), Error> {
936 self.driver().flush_async().await;
939 self.driver().setup_full_duplex()?;
940
941 self.driver().read_async(words).await
942 }
943
944 async fn write_async(&mut self, words: &[u8]) -> Result<(), Error> {
945 self.driver().flush_async().await;
948 self.driver().setup_full_duplex()?;
949
950 self.driver().write_async(words).await
951 }
952}
953
954macro_rules! def_with_sio_pin {
955 ($fn:ident, $n:literal) => {
956 #[doc = concat!(" Assign the SIO", stringify!($n), " pin for the SPI instance.")]
957 #[doc = " "]
958 #[doc = " Enables both input and output functionality for the pin, and connects it"]
959 #[doc = concat!(" to the SIO", stringify!($n), " output and input signals.")]
960 #[instability::unstable]
961 pub fn $fn(mut self, sio: impl PeripheralInput<'d> + PeripheralOutput<'d>) -> Self {
962 self.spi.pins().sio_pins[$n] = self.connect_sio_pin(sio.into(), $n);
963
964 self
965 }
966 };
967}
968
969impl<'d, Dm> Spi<'d, Dm>
970where
971 Dm: DriverMode,
972{
973 fn connect_sio_pin(&self, pin: interconnect::OutputSignal<'d>, n: usize) -> PinGuard {
974 let in_signal = self.spi.info().sio_input(n);
975 let out_signal = self.spi.info().sio_output(n);
976
977 pin.apply_input_config(&InputConfig::default());
978 pin.apply_output_config(&OutputConfig::default());
979
980 pin.set_input_enable(true);
981 pin.set_output_enable(false);
982
983 in_signal.connect_to(&pin);
984 pin.connect_with_guard(out_signal)
985 }
986
987 fn connect_sio_output_pin(&self, pin: interconnect::OutputSignal<'d>, n: usize) -> PinGuard {
988 let out_signal = self.spi.info().sio_output(n);
989
990 self.connect_output_pin(pin, out_signal)
991 }
992
993 fn connect_output_pin(
994 &self,
995 pin: interconnect::OutputSignal<'d>,
996 signal: OutputSignal,
997 ) -> PinGuard {
998 pin.apply_output_config(&OutputConfig::default());
999 pin.set_output_enable(true); pin.connect_with_guard(signal)
1002 }
1003
1004 #[procmacros::doc_replace]
1005 pub fn with_sck(mut self, sclk: impl PeripheralOutput<'d>) -> Self {
1025 let info = self.spi.info();
1026 self.spi.pins().sclk_pin = self.connect_output_pin(sclk.into(), info.sclk);
1027
1028 self
1029 }
1030
1031 #[procmacros::doc_replace]
1032 pub fn with_mosi(mut self, mosi: impl PeripheralOutput<'d>) -> Self {
1054 self.spi.pins().sio_pins[0] = self.connect_sio_output_pin(mosi.into(), 0);
1055 self
1056 }
1057
1058 #[procmacros::doc_replace]
1059 pub fn with_miso(self, miso: impl PeripheralInput<'d>) -> Self {
1080 let miso = miso.into();
1081
1082 miso.apply_input_config(&InputConfig::default());
1083 miso.set_input_enable(true);
1084
1085 self.driver().info.sio_input(1).connect_to(&miso);
1086
1087 self
1088 }
1089
1090 #[instability::unstable]
1103 pub fn with_sio0(mut self, mosi: impl PeripheralInput<'d> + PeripheralOutput<'d>) -> Self {
1104 self.spi.pins().sio_pins[0] = self.connect_sio_pin(mosi.into(), 0);
1105
1106 self
1107 }
1108
1109 #[instability::unstable]
1121 pub fn with_sio1(mut self, sio1: impl PeripheralInput<'d> + PeripheralOutput<'d>) -> Self {
1122 self.spi.pins().sio_pins[1] = self.connect_sio_pin(sio1.into(), 1);
1123
1124 self
1125 }
1126
1127 def_with_sio_pin!(with_sio2, 2);
1128 def_with_sio_pin!(with_sio3, 3);
1129
1130 #[cfg(spi_master_has_octal)]
1131 def_with_sio_pin!(with_sio4, 4);
1132
1133 #[cfg(spi_master_has_octal)]
1134 def_with_sio_pin!(with_sio5, 5);
1135
1136 #[cfg(spi_master_has_octal)]
1137 def_with_sio_pin!(with_sio6, 6);
1138
1139 #[cfg(spi_master_has_octal)]
1140 def_with_sio_pin!(with_sio7, 7);
1141
1142 #[instability::unstable]
1154 pub fn with_cs(mut self, cs: impl PeripheralOutput<'d>) -> Self {
1155 let info = self.spi.info();
1156 self.spi.pins().cs_pin = self.connect_output_pin(cs.into(), info.cs(0));
1157
1158 self
1159 }
1160
1161 #[doc_replace(
1162 "max_frequency" => {
1163 cfg(esp32h2) => "48MHz",
1164 _ => "80MHz",
1165 }
1166 )]
1167 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1189 self.driver().apply_config(config)
1190 }
1191
1192 #[procmacros::doc_replace]
1193 pub fn write(&mut self, words: &[u8]) -> Result<(), Error> {
1216 self.driver().flush()?;
1217 self.driver().setup_full_duplex()?;
1218
1219 for chunk in words.chunks(FIFO_SIZE) {
1220 self.driver().write_one(chunk)?;
1221 self.driver().flush()?;
1225 }
1226
1227 Ok(())
1228 }
1229
1230 #[procmacros::doc_replace]
1231 pub fn read(&mut self, words: &mut [u8]) -> Result<(), Error> {
1254 self.driver().flush()?;
1255 self.driver().setup_full_duplex()?;
1256 self.driver().read(words)
1257 }
1258
1259 #[procmacros::doc_replace]
1260 pub fn transfer(&mut self, words: &mut [u8]) -> Result<(), Error> {
1283 self.driver().flush()?;
1284 self.driver().setup_full_duplex()?;
1285 self.driver().transfer_in_place(words)
1286 }
1287
1288 #[instability::unstable]
1297 pub fn half_duplex_read(
1298 &mut self,
1299 data_mode: DataMode,
1300 cmd: Command,
1301 address: Address,
1302 dummy: u8,
1303 buffer: &mut [u8],
1304 ) -> Result<(), Error> {
1305 if buffer.len() > FIFO_SIZE {
1306 return Err(Error::FifoSizeExeeded);
1307 }
1308
1309 if buffer.is_empty() {
1310 error!("Half-duplex mode does not support empty buffer");
1311 return Err(Error::Unsupported);
1312 }
1313
1314 self.flush()?;
1315 self.driver().setup_half_duplex(
1316 false,
1317 cmd,
1318 address,
1319 false,
1320 dummy,
1321 buffer.is_empty(),
1322 data_mode,
1323 )?;
1324
1325 self.driver().configure_datalen(buffer.len(), 0);
1326 self.driver().start_operation();
1327 self.driver().flush()?;
1328 self.driver().read_from_fifo(buffer)
1329 }
1330
1331 #[cfg_attr(
1338 esp32,
1339 doc = "Dummy phase configuration is currently not supported, only value `0` is valid (see issue [#2240](https://github.com/esp-rs/esp-hal/issues/2240))."
1340 )]
1341 #[instability::unstable]
1342 pub fn half_duplex_write(
1343 &mut self,
1344 data_mode: DataMode,
1345 cmd: Command,
1346 address: Address,
1347 dummy: u8,
1348 buffer: &[u8],
1349 ) -> Result<(), Error> {
1350 if buffer.len() > FIFO_SIZE {
1351 return Err(Error::FifoSizeExeeded);
1352 }
1353
1354 self.flush()?;
1355
1356 cfg_if::cfg_if! {
1357 if #[cfg(all(esp32, spi_address_workaround))] {
1358 let mut buffer = buffer;
1359 let mut data_mode = data_mode;
1360 let mut address = address;
1361 let addr_bytes;
1362 if buffer.is_empty() && !address.is_none() {
1363 let bytes_to_write = address.width().div_ceil(8);
1366 addr_bytes = address.value().to_be_bytes();
1369 buffer = &addr_bytes[4 - bytes_to_write..][..bytes_to_write];
1370 data_mode = address.mode();
1371 address = Address::None;
1372 }
1373
1374 if dummy > 0 {
1375 error!("Dummy bits are not supported without data");
1377 return Err(Error::Unsupported);
1378 }
1379 }
1380 }
1381
1382 self.driver().setup_half_duplex(
1383 true,
1384 cmd,
1385 address,
1386 false,
1387 dummy,
1388 buffer.is_empty(),
1389 data_mode,
1390 )?;
1391
1392 if !buffer.is_empty() {
1393 self.driver().configure_datalen(0, buffer.len());
1394 self.driver().fill_fifo(buffer);
1395 }
1396
1397 self.driver().start_operation();
1398
1399 self.driver().flush()
1400 }
1401
1402 fn driver(&self) -> Driver {
1403 Driver {
1404 info: self.spi.info(),
1405 state: self.spi.state(),
1406 }
1407 }
1408}
1409
1410#[instability::unstable]
1411impl<Dm> embassy_embedded_hal::SetConfig for Spi<'_, Dm>
1412where
1413 Dm: DriverMode,
1414{
1415 type Config = Config;
1416 type ConfigError = ConfigError;
1417
1418 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
1419 self.apply_config(config)
1420 }
1421}
1422
1423impl<Dm> embedded_hal::spi::ErrorType for Spi<'_, Dm>
1424where
1425 Dm: DriverMode,
1426{
1427 type Error = Error;
1428}
1429
1430impl<Dm> SpiBus for Spi<'_, Dm>
1431where
1432 Dm: DriverMode,
1433{
1434 fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
1435 self.read(words)
1436 }
1437
1438 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
1439 self.driver().flush()?;
1442 self.driver().setup_full_duplex()?;
1443 for chunk in words.chunks(FIFO_SIZE) {
1444 self.driver().flush()?;
1445 self.driver().write_one(chunk)?;
1446 }
1447 Ok(())
1448 }
1449
1450 fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
1451 self.driver().flush()?;
1452 self.driver().setup_full_duplex()?;
1453
1454 if read.is_empty() {
1455 self.driver().write(write)
1456 } else if write.is_empty() {
1457 self.driver().read(read)
1458 } else {
1459 self.driver().transfer(read, write)
1460 }
1461 }
1462
1463 fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
1464 self.driver().flush()?;
1465 self.driver().setup_full_duplex()?;
1466 self.driver().transfer_in_place(words)
1467 }
1468
1469 fn flush(&mut self) -> Result<(), Self::Error> {
1470 self.driver().flush()
1471 }
1472}
1473
1474impl SpiBusAsync for Spi<'_, Async> {
1475 async fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
1476 self.read_async(words).await
1477 }
1478
1479 async fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
1480 self.write_async(words).await
1481 }
1482
1483 async fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
1484 self.driver().flush_async().await;
1485 self.driver().setup_full_duplex()?;
1486
1487 if read.is_empty() {
1488 self.driver().write_async(write).await
1489 } else if write.is_empty() {
1490 self.driver().read_async(read).await
1491 } else {
1492 self.driver().transfer_async(read, write).await
1493 }
1494 }
1495
1496 async fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
1497 self.transfer_in_place_async(words).await
1498 }
1499
1500 async fn flush(&mut self) -> Result<(), Self::Error> {
1501 self.flush_async().await
1502 }
1503}
1504
1505pub trait Instance: private::Sealed + any::Degrade {
1507 #[doc(hidden)]
1508 fn parts(&self) -> (&'static Info, &'static State);
1510
1511 #[doc(hidden)]
1513 #[inline(always)]
1514 fn info(&self) -> &'static Info {
1515 self.parts().0
1516 }
1517
1518 #[doc(hidden)]
1520 #[inline(always)]
1521 fn state(&self) -> &'static State {
1522 self.parts().1
1523 }
1524}
1525
1526#[doc(hidden)]
1528pub trait QspiInstance: Instance {}
1529
1530#[doc(hidden)]
1532#[non_exhaustive]
1533#[allow(private_interfaces, reason = "Unstable details")]
1534pub struct Info {
1535 pub register_block: *const RegisterBlock,
1539
1540 pub peripheral: crate::system::Peripheral,
1542
1543 pub async_handler: InterruptHandler,
1545
1546 pub sclk: OutputSignal,
1548
1549 pub cs: &'static [OutputSignal],
1551
1552 pub sio_inputs: &'static [InputSignal],
1553 pub sio_outputs: &'static [OutputSignal],
1554}
1555
1556impl Info {
1557 fn cs(&self, n: usize) -> OutputSignal {
1558 *unwrap!(self.cs.get(n), "CS{} is not defined", n)
1559 }
1560
1561 fn opt_sio_input(&self, n: usize) -> Option<InputSignal> {
1562 self.sio_inputs.get(n).copied()
1563 }
1564
1565 fn opt_sio_output(&self, n: usize) -> Option<OutputSignal> {
1566 self.sio_outputs.get(n).copied()
1567 }
1568
1569 fn sio_input(&self, n: usize) -> InputSignal {
1570 unwrap!(self.opt_sio_input(n), "SIO{} is not defined", n)
1571 }
1572
1573 fn sio_output(&self, n: usize) -> OutputSignal {
1574 unwrap!(self.opt_sio_output(n), "SIO{} is not defined", n)
1575 }
1576}
1577
1578struct Driver {
1579 info: &'static Info,
1580 state: &'static State,
1581}
1582
1583impl Driver {
1586 pub fn regs(&self) -> &RegisterBlock {
1588 unsafe { &*self.info.register_block }
1589 }
1590
1591 fn abort_transfer(&self) {
1592 cfg_if::cfg_if! {
1597 if #[cfg(esp32)] {
1598 self.regs().slave().toggle(|w, en| w.mode().bit(en));
1599 } else {
1600 self.configure_datalen(1, 1);
1601 }
1602 }
1603 self.update();
1604 }
1605
1606 fn init(&self) {
1608 self.regs().user().modify(|_, w| {
1609 w.usr_miso_highpart().clear_bit();
1610 w.usr_mosi_highpart().clear_bit();
1611 w.doutdin().set_bit();
1612 w.usr_miso().set_bit();
1613 w.usr_mosi().set_bit();
1614 w.cs_hold().set_bit();
1615 w.usr_dummy_idle().set_bit();
1616 w.usr_addr().clear_bit();
1617 w.usr_command().clear_bit()
1618 });
1619
1620 #[cfg(not(any(esp32, esp32s2)))]
1621 self.regs().clk_gate().modify(|_, w| {
1622 w.clk_en().set_bit();
1623 w.mst_clk_active().set_bit();
1624 w.mst_clk_sel().set_bit()
1625 });
1626
1627 #[cfg(soc_has_pcr)]
1628 unsafe {
1629 crate::peripherals::PCR::regs()
1631 .spi2_clkm_conf()
1632 .modify(|_, w| {
1633 #[cfg(spi_master_has_clk_pre_div)]
1634 w.spi2_clkm_div_num().bits(1);
1635 w.spi2_clkm_sel().bits(1);
1636 w.spi2_clkm_en().set_bit()
1637 });
1638 }
1639
1640 cfg_if::cfg_if! {
1641 if #[cfg(esp32)] {
1642 self.regs().ctrl().modify(|_, w| w.wp().clear_bit());
1643 } else {
1644 self.regs().ctrl().modify(|_, w| {
1645 w.q_pol().clear_bit();
1646 w.d_pol().clear_bit();
1647 #[cfg(esp32s2)]
1648 w.wp().clear_bit();
1649 #[cfg(not(esp32s2))]
1650 w.hold_pol().clear_bit();
1651 w
1652 });
1653 self.regs().misc().write(|w| unsafe { w.bits(0) });
1654 }
1655 }
1656
1657 self.regs().slave().write(|w| unsafe { w.bits(0) });
1658 }
1659
1660 #[cfg(not(esp32))]
1661 fn init_spi_data_mode(
1662 &self,
1663 cmd_mode: DataMode,
1664 address_mode: DataMode,
1665 data_mode: DataMode,
1666 ) -> Result<(), Error> {
1667 self.regs().ctrl().modify(|_, w| {
1668 w.fcmd_dual().bit(cmd_mode == DataMode::Dual);
1669 w.fcmd_quad().bit(cmd_mode == DataMode::Quad);
1670 w.faddr_dual().bit(address_mode == DataMode::Dual);
1671 w.faddr_quad().bit(address_mode == DataMode::Quad);
1672 w.fread_dual().bit(data_mode == DataMode::Dual);
1673 w.fread_quad().bit(data_mode == DataMode::Quad)
1674 });
1675 self.regs().user().modify(|_, w| {
1676 w.fwrite_dual().bit(data_mode == DataMode::Dual);
1677 w.fwrite_quad().bit(data_mode == DataMode::Quad)
1678 });
1679 Ok(())
1680 }
1681
1682 #[cfg(esp32)]
1683 fn init_spi_data_mode(
1684 &self,
1685 cmd_mode: DataMode,
1686 address_mode: DataMode,
1687 data_mode: DataMode,
1688 ) -> Result<(), Error> {
1689 match cmd_mode {
1690 DataMode::Single => (),
1691 DataMode::SingleTwoDataLines => (),
1692 _ => {
1694 error!("Commands must be single bit wide");
1695 return Err(Error::Unsupported);
1696 }
1697 }
1698
1699 match address_mode {
1700 DataMode::Single | DataMode::SingleTwoDataLines => {
1701 self.regs().ctrl().modify(|_, w| {
1702 w.fastrd_mode()
1703 .bit(matches!(data_mode, DataMode::Dual | DataMode::Quad));
1704 w.fread_dio().clear_bit();
1705 w.fread_qio().clear_bit();
1706 w.fread_dual().bit(data_mode == DataMode::Dual);
1707 w.fread_quad().bit(data_mode == DataMode::Quad)
1708 });
1709
1710 self.regs().user().modify(|_, w| {
1711 w.fwrite_dio().clear_bit();
1712 w.fwrite_qio().clear_bit();
1713 w.fwrite_dual().bit(data_mode == DataMode::Dual);
1714 w.fwrite_quad().bit(data_mode == DataMode::Quad)
1715 });
1716 }
1717 address_mode if address_mode == data_mode => {
1718 self.regs().ctrl().modify(|_, w| {
1719 w.fastrd_mode()
1720 .bit(matches!(data_mode, DataMode::Dual | DataMode::Quad));
1721 w.fread_dio().bit(address_mode == DataMode::Dual);
1722 w.fread_qio().bit(address_mode == DataMode::Quad);
1723 w.fread_dual().clear_bit();
1724 w.fread_quad().clear_bit()
1725 });
1726
1727 self.regs().user().modify(|_, w| {
1728 w.fwrite_dio().bit(address_mode == DataMode::Dual);
1729 w.fwrite_qio().bit(address_mode == DataMode::Quad);
1730 w.fwrite_dual().clear_bit();
1731 w.fwrite_quad().clear_bit()
1732 });
1733 }
1734 _ => {
1735 error!("Address mode must be single bit wide or equal to the data mode");
1737 return Err(Error::Unsupported);
1738 }
1739 }
1740
1741 Ok(())
1742 }
1743
1744 #[cfg_attr(not(feature = "unstable"), allow(dead_code))]
1746 fn enable_listen(&self, interrupts: EnumSet<SpiInterrupt>, enable: bool) {
1747 cfg_if::cfg_if! {
1748 if #[cfg(esp32)] {
1749 self.regs().slave().modify(|_, w| {
1750 for interrupt in interrupts {
1751 match interrupt {
1752 SpiInterrupt::TransferDone => w.trans_inten().bit(enable),
1753 };
1754 }
1755 w
1756 });
1757 } else if #[cfg(esp32s2)] {
1758 self.regs().slave().modify(|_, w| {
1759 for interrupt in interrupts {
1760 match interrupt {
1761 SpiInterrupt::TransferDone => w.int_trans_done_en().bit(enable),
1762 SpiInterrupt::DmaSegmentedTransferDone => w.int_dma_seg_trans_en().bit(enable),
1763 };
1764 }
1765 w
1766 });
1767 } else {
1768 self.regs().dma_int_ena().modify(|_, w| {
1769 for interrupt in interrupts {
1770 match interrupt {
1771 SpiInterrupt::TransferDone => w.trans_done().bit(enable),
1772 #[cfg(spi_master_has_dma_segmented_transfer)]
1773 SpiInterrupt::DmaSegmentedTransferDone => w.dma_seg_trans_done().bit(enable),
1774 #[cfg(spi_master_has_app_interrupts)]
1775 SpiInterrupt::App2 => w.app2().bit(enable),
1776 #[cfg(spi_master_has_app_interrupts)]
1777 SpiInterrupt::App1 => w.app1().bit(enable),
1778 };
1779 }
1780 w
1781 });
1782 }
1783 }
1784 }
1785
1786 #[cfg_attr(not(feature = "unstable"), allow(dead_code))]
1788 fn interrupts(&self) -> EnumSet<SpiInterrupt> {
1789 let mut res = EnumSet::new();
1790
1791 cfg_if::cfg_if! {
1792 if #[cfg(esp32)] {
1793 if self.regs().slave().read().trans_done().bit() {
1794 res.insert(SpiInterrupt::TransferDone);
1795 }
1796 } else if #[cfg(esp32s2)] {
1797 if self.regs().slave().read().trans_done().bit() {
1798 res.insert(SpiInterrupt::TransferDone);
1799 }
1800 if self.regs().hold().read().dma_seg_trans_done().bit() {
1801 res.insert(SpiInterrupt::DmaSegmentedTransferDone);
1802 }
1803 } else {
1804 let ints = self.regs().dma_int_raw().read();
1805
1806 if ints.trans_done().bit() {
1807 res.insert(SpiInterrupt::TransferDone);
1808 }
1809 #[cfg(spi_master_has_dma_segmented_transfer)]
1810 if ints.dma_seg_trans_done().bit() {
1811 res.insert(SpiInterrupt::DmaSegmentedTransferDone);
1812 }
1813 #[cfg(spi_master_has_app_interrupts)]
1814 if ints.app2().bit() {
1815 res.insert(SpiInterrupt::App2);
1816 }
1817 #[cfg(spi_master_has_app_interrupts)]
1818 if ints.app1().bit() {
1819 res.insert(SpiInterrupt::App1);
1820 }
1821 }
1822 }
1823
1824 res
1825 }
1826
1827 fn clear_interrupts(&self, interrupts: EnumSet<SpiInterrupt>) {
1829 cfg_if::cfg_if! {
1830 if #[cfg(esp32)] {
1831 for interrupt in interrupts {
1832 match interrupt {
1833 SpiInterrupt::TransferDone => {
1834 self.regs().slave().modify(|_, w| w.trans_done().clear_bit());
1835 }
1836 }
1837 }
1838 } else if #[cfg(esp32s2)] {
1839 for interrupt in interrupts {
1840 match interrupt {
1841 SpiInterrupt::TransferDone => {
1842 self.regs().slave().modify(|_, w| w.trans_done().clear_bit());
1843 }
1844
1845 SpiInterrupt::DmaSegmentedTransferDone => {
1846 self.regs()
1847 .hold()
1848 .modify(|_, w| w.dma_seg_trans_done().clear_bit());
1849 }
1850 }
1851 }
1852 } else {
1853 self.regs().dma_int_clr().write(|w| {
1854 for interrupt in interrupts {
1855 match interrupt {
1856 SpiInterrupt::TransferDone => w.trans_done().clear_bit_by_one(),
1857 #[cfg(spi_master_has_dma_segmented_transfer)]
1858 SpiInterrupt::DmaSegmentedTransferDone => w.dma_seg_trans_done().clear_bit_by_one(),
1859 #[cfg(spi_master_has_app_interrupts)]
1860 SpiInterrupt::App2 => w.app2().clear_bit_by_one(),
1861 #[cfg(spi_master_has_app_interrupts)]
1862 SpiInterrupt::App1 => w.app1().clear_bit_by_one(),
1863 };
1864 }
1865 w
1866 });
1867 }
1868 }
1869 }
1870
1871 fn apply_config(&self, config: &Config) -> Result<(), ConfigError> {
1872 config.validate()?;
1873 self.ch_bus_freq(config)?;
1874 self.set_bit_order(config.read_bit_order, config.write_bit_order);
1875 self.set_data_mode(config.mode);
1876
1877 #[cfg(esp32)]
1878 self.calculate_half_duplex_values(config);
1879
1880 Ok(())
1881 }
1882
1883 #[cfg(esp32)]
1884 fn calculate_half_duplex_values(&self, config: &Config) {
1885 let f_apb = 80_000_000;
1886 let source_freq_hz = match config.clock_source {
1887 ClockSource::Apb => f_apb,
1888 };
1889
1890 let clock_reg = self.regs().clock().read();
1891 let eff_clk = if clock_reg.clk_equ_sysclk().bit_is_set() {
1892 f_apb
1893 } else {
1894 let pre = clock_reg.clkdiv_pre().bits() as i32 + 1;
1895 let n = clock_reg.clkcnt_n().bits() as i32 + 1;
1896 f_apb / (pre * n)
1897 };
1898
1899 let apbclk_khz = source_freq_hz / 1000;
1900 let spiclk_apb_n = source_freq_hz / eff_clk;
1902
1903 let input_delay_ns = 25; let delay_apb_n = (1 + input_delay_ns) * apbclk_khz / 1000 / 1000;
1908
1909 let dummy_required = delay_apb_n / spiclk_apb_n;
1910 let timing_miso_delay = if dummy_required > 0 {
1911 Some(((dummy_required + 1) * spiclk_apb_n - delay_apb_n - 1) as u8)
1915 } else if delay_apb_n * 4 <= spiclk_apb_n {
1916 None
1919 } else {
1920 Some(0)
1921 };
1922
1923 self.state.esp32_hack.extra_dummy.set(dummy_required as u8);
1924 self.state
1925 .esp32_hack
1926 .timing_miso_delay
1927 .set(timing_miso_delay);
1928 }
1929
1930 fn set_data_mode(&self, data_mode: Mode) {
1931 cfg_if::cfg_if! {
1932 if #[cfg(esp32)] {
1933 let pin_reg = self.regs().pin();
1934 } else {
1935 let pin_reg = self.regs().misc();
1936 }
1937 };
1938
1939 pin_reg.modify(|_, w| {
1940 w.ck_idle_edge()
1941 .bit(matches!(data_mode, Mode::_2 | Mode::_3))
1942 });
1943 self.regs().user().modify(|_, w| {
1944 w.ck_out_edge()
1945 .bit(matches!(data_mode, Mode::_1 | Mode::_2))
1946 });
1947 }
1948
1949 fn ch_bus_freq(&self, bus_clock_config: &Config) -> Result<(), ConfigError> {
1950 fn enable_clocks(_reg_block: &RegisterBlock, _enable: bool) {
1951 #[cfg(not(any(esp32, esp32s2)))]
1952 _reg_block.clk_gate().modify(|_, w| {
1953 w.clk_en().bit(_enable);
1954 w.mst_clk_active().bit(_enable);
1955 w.mst_clk_sel().bit(true) });
1957 }
1958
1959 let raw = bus_clock_config.raw_clock_reg_value()?;
1961
1962 enable_clocks(self.regs(), false);
1963 self.regs().clock().write(|w| unsafe { w.bits(raw) });
1964 enable_clocks(self.regs(), true);
1965
1966 Ok(())
1967 }
1968
1969 #[cfg(not(any(esp32, esp32c3, esp32s2)))]
1970 fn set_bit_order(&self, read_order: BitOrder, write_order: BitOrder) {
1971 let read_value = match read_order {
1972 BitOrder::MsbFirst => 0,
1973 BitOrder::LsbFirst => 1,
1974 };
1975 let write_value = match write_order {
1976 BitOrder::MsbFirst => 0,
1977 BitOrder::LsbFirst => 1,
1978 };
1979 self.regs().ctrl().modify(|_, w| unsafe {
1980 w.rd_bit_order().bits(read_value);
1981 w.wr_bit_order().bits(write_value);
1982 w
1983 });
1984 }
1985
1986 #[cfg(any(esp32, esp32c3, esp32s2))]
1987 fn set_bit_order(&self, read_order: BitOrder, write_order: BitOrder) {
1988 let read_value = match read_order {
1989 BitOrder::MsbFirst => false,
1990 BitOrder::LsbFirst => true,
1991 };
1992 let write_value = match write_order {
1993 BitOrder::MsbFirst => false,
1994 BitOrder::LsbFirst => true,
1995 };
1996 self.regs().ctrl().modify(|_, w| {
1997 w.rd_bit_order().bit(read_value);
1998 w.wr_bit_order().bit(write_value);
1999 w
2000 });
2001 }
2002
2003 #[cfg_attr(place_spi_master_driver_in_ram, ram)]
2004 fn fill_fifo(&self, chunk: &[u8]) {
2005 let mut c_iter = chunk.chunks_exact(4);
2007 let mut w_iter = self.regs().w_iter();
2008 for c in c_iter.by_ref() {
2009 if let Some(w_reg) = w_iter.next() {
2010 let word = (c[0] as u32)
2011 | ((c[1] as u32) << 8)
2012 | ((c[2] as u32) << 16)
2013 | ((c[3] as u32) << 24);
2014 w_reg.write(|w| w.buf().set(word));
2015 }
2016 }
2017 let rem = c_iter.remainder();
2018 if !rem.is_empty()
2019 && let Some(w_reg) = w_iter.next()
2020 {
2021 let word = match rem.len() {
2022 3 => (rem[0] as u32) | ((rem[1] as u32) << 8) | ((rem[2] as u32) << 16),
2023 2 => (rem[0] as u32) | ((rem[1] as u32) << 8),
2024 1 => rem[0] as u32,
2025 _ => unreachable!(),
2026 };
2027 w_reg.write(|w| w.buf().set(word));
2028 }
2029 }
2030
2031 #[cfg_attr(place_spi_master_driver_in_ram, ram)]
2033 fn write_one(&self, words: &[u8]) -> Result<(), Error> {
2034 if words.len() > FIFO_SIZE {
2035 return Err(Error::FifoSizeExeeded);
2036 }
2037 self.configure_datalen(0, words.len());
2038 self.fill_fifo(words);
2039 self.start_operation();
2040 Ok(())
2041 }
2042
2043 #[cfg_attr(place_spi_master_driver_in_ram, ram)]
2049 fn write(&self, words: &[u8]) -> Result<(), Error> {
2050 for chunk in words.chunks(FIFO_SIZE) {
2051 self.flush()?;
2052 self.write_one(chunk)?;
2053 }
2054 Ok(())
2055 }
2056
2057 #[cfg_attr(place_spi_master_driver_in_ram, ram)]
2059 async fn write_async(&self, words: &[u8]) -> Result<(), Error> {
2060 for chunk in words.chunks(FIFO_SIZE) {
2061 self.write_one(chunk)?;
2062 self.flush_async().await;
2063 }
2064 Ok(())
2065 }
2066
2067 #[cfg_attr(place_spi_master_driver_in_ram, ram)]
2073 fn read(&self, words: &mut [u8]) -> Result<(), Error> {
2074 let empty_array = [EMPTY_WRITE_PAD; FIFO_SIZE];
2075
2076 for chunk in words.chunks_mut(FIFO_SIZE) {
2077 self.write_one(&empty_array[0..chunk.len()])?;
2078 self.flush()?;
2079 self.read_from_fifo(chunk)?;
2080 }
2081 Ok(())
2082 }
2083
2084 #[cfg_attr(place_spi_master_driver_in_ram, ram)]
2090 async fn read_async(&self, words: &mut [u8]) -> Result<(), Error> {
2091 let empty_array = [EMPTY_WRITE_PAD; FIFO_SIZE];
2092
2093 for chunk in words.chunks_mut(FIFO_SIZE) {
2094 self.write_one(&empty_array[0..chunk.len()])?;
2095 self.flush_async().await;
2096 self.read_from_fifo(chunk)?;
2097 }
2098 Ok(())
2099 }
2100
2101 #[cfg_attr(place_spi_master_driver_in_ram, ram)]
2108 fn read_from_fifo(&self, words: &mut [u8]) -> Result<(), Error> {
2109 if words.len() > FIFO_SIZE {
2110 return Err(Error::FifoSizeExeeded);
2111 }
2112
2113 for (chunk, w_reg) in words.chunks_mut(4).zip(self.regs().w_iter()) {
2114 let reg_val = w_reg.read().bits();
2115 let bytes = reg_val.to_le_bytes();
2116
2117 let len = chunk.len();
2118 chunk.copy_from_slice(&bytes[..len]);
2119 }
2120
2121 Ok(())
2122 }
2123
2124 fn busy(&self) -> bool {
2125 self.regs().cmd().read().usr().bit_is_set()
2126 }
2127
2128 #[cfg_attr(place_spi_master_driver_in_ram, ram)]
2130 fn flush_async(&self) -> impl Future<Output = ()> {
2131 SpiFuture { driver: self }
2132 }
2133
2134 #[cfg_attr(place_spi_master_driver_in_ram, ram)]
2136 fn flush(&self) -> Result<(), Error> {
2137 while self.busy() {
2138 }
2140 Ok(())
2141 }
2142
2143 #[cfg_attr(place_spi_master_driver_in_ram, ram)]
2144 fn transfer_in_place(&self, words: &mut [u8]) -> Result<(), Error> {
2145 for chunk in words.chunks_mut(FIFO_SIZE) {
2146 self.write_one(chunk)?;
2147 self.flush()?;
2148 self.read_from_fifo(chunk)?;
2149 }
2150
2151 Ok(())
2152 }
2153
2154 #[cfg_attr(place_spi_master_driver_in_ram, ram)]
2155 fn transfer(&self, read: &mut [u8], write: &[u8]) -> Result<(), Error> {
2156 let mut write_from = 0;
2157 let mut read_from = 0;
2158
2159 loop {
2160 let write_inc = core::cmp::min(FIFO_SIZE, write.len() - write_from);
2162 let read_inc = core::cmp::min(FIFO_SIZE, read.len() - read_from);
2164
2165 if (write_inc == 0) && (read_inc == 0) {
2166 break;
2167 }
2168
2169 self.flush()?;
2170
2171 if write_inc < read_inc {
2172 let mut empty = [EMPTY_WRITE_PAD; FIFO_SIZE];
2174 empty[0..write_inc].copy_from_slice(&write[write_from..][..write_inc]);
2175 self.write_one(&empty[..read_inc])?;
2176 } else {
2177 self.write_one(&write[write_from..][..write_inc])?;
2178 }
2179
2180 if read_inc > 0 {
2181 self.flush()?;
2182 self.read_from_fifo(&mut read[read_from..][..read_inc])?;
2183 }
2184
2185 write_from += write_inc;
2186 read_from += read_inc;
2187 }
2188 Ok(())
2189 }
2190
2191 #[cfg_attr(place_spi_master_driver_in_ram, ram)]
2192 async fn transfer_in_place_async(&self, words: &mut [u8]) -> Result<(), Error> {
2193 for chunk in words.chunks_mut(FIFO_SIZE) {
2194 let cancel_on_drop = DropGuard::new((), |_| {
2197 self.abort_transfer();
2198 while self.busy() {}
2199 });
2200 let res = self.write_one(chunk);
2201 self.flush_async().await;
2202 cancel_on_drop.defuse();
2203 res?;
2204
2205 self.read_from_fifo(chunk)?;
2206 }
2207
2208 Ok(())
2209 }
2210
2211 #[cfg_attr(place_spi_master_driver_in_ram, ram)]
2212 async fn transfer_async(&self, read: &mut [u8], write: &[u8]) -> Result<(), Error> {
2213 let mut write_from = 0;
2214 let mut read_from = 0;
2215
2216 loop {
2217 let write_inc = core::cmp::min(FIFO_SIZE, write.len() - write_from);
2219 let read_inc = core::cmp::min(FIFO_SIZE, read.len() - read_from);
2221
2222 if (write_inc == 0) && (read_inc == 0) {
2223 break;
2224 }
2225
2226 self.flush_async().await;
2227
2228 if write_inc < read_inc {
2229 let mut empty = [EMPTY_WRITE_PAD; FIFO_SIZE];
2231 empty[0..write_inc].copy_from_slice(&write[write_from..][..write_inc]);
2232 self.write_one(&empty[..read_inc])?;
2233 } else {
2234 self.write_one(&write[write_from..][..write_inc])?;
2235 }
2236
2237 self.flush_async().await;
2239 if read_inc > 0 {
2240 self.read_from_fifo(&mut read[read_from..][..read_inc])?;
2241 }
2242
2243 write_from += write_inc;
2244 read_from += read_inc;
2245 }
2246 Ok(())
2247 }
2248
2249 #[cfg_attr(place_spi_master_driver_in_ram, ram)]
2250 fn start_operation(&self) {
2251 self.update();
2252 self.clear_interrupts(SpiInterrupt::TransferDone.into());
2253 self.regs().cmd().modify(|_, w| w.usr().set_bit());
2254 }
2255
2256 fn setup_full_duplex(&self) -> Result<(), Error> {
2257 self.regs().user().modify(|_, w| {
2258 w.usr_miso().set_bit();
2259 w.usr_mosi().set_bit();
2260 w.doutdin().set_bit();
2261 w.usr_dummy().clear_bit();
2262 w.sio().clear_bit()
2263 });
2264
2265 self.init_spi_data_mode(
2266 DataMode::SingleTwoDataLines,
2267 DataMode::SingleTwoDataLines,
2268 DataMode::SingleTwoDataLines,
2269 )?;
2270
2271 #[cfg(esp32)]
2273 self.regs().ctrl2().modify(|_, w| unsafe {
2274 w.miso_delay_mode().bits(0);
2275 w.miso_delay_num().bits(0)
2276 });
2277
2278 Ok(())
2279 }
2280
2281 #[expect(clippy::too_many_arguments)]
2282 fn setup_half_duplex(
2283 &self,
2284 is_write: bool,
2285 cmd: Command,
2286 address: Address,
2287 dummy_idle: bool,
2288 dummy: u8,
2289 no_mosi_miso: bool,
2290 data_mode: DataMode,
2291 ) -> Result<(), Error> {
2292 self.init_spi_data_mode(cmd.mode(), address.mode(), data_mode)?;
2293
2294 #[cfg(esp32)]
2295 let mut dummy = dummy;
2296
2297 #[cfg(esp32)]
2298 self.regs().ctrl2().modify(|_, w| {
2299 let mut delay_mode = 0;
2300 let mut delay_num = 0;
2301
2302 if !is_write {
2303 let timing_miso_delay = self.state.esp32_hack.timing_miso_delay.get();
2305 let extra_dummy = self.state.esp32_hack.extra_dummy.get();
2306 dummy += extra_dummy;
2307
2308 if let Some(delay) = timing_miso_delay {
2309 delay_num = if extra_dummy > 0 { delay } else { 0 };
2310 } else {
2311 let out_edge = self.regs().user().read().ck_out_edge().bit_is_set();
2312 delay_mode = if out_edge { 1 } else { 2 };
2314 }
2315 }
2316
2317 unsafe {
2318 w.miso_delay_mode().bits(delay_mode);
2319 w.miso_delay_num().bits(delay_num)
2320 }
2321 });
2322
2323 let reg_block = self.regs();
2324 reg_block.user().modify(|_, w| {
2325 w.usr_miso_highpart().clear_bit();
2326 w.usr_mosi_highpart().clear_bit();
2327 w.sio().bit(data_mode == DataMode::Single);
2329 w.doutdin().clear_bit();
2330 w.usr_miso().bit(!is_write && !no_mosi_miso);
2331 w.usr_mosi().bit(is_write && !no_mosi_miso);
2332 w.cs_hold().set_bit();
2333 w.usr_dummy_idle().bit(dummy_idle);
2334 w.usr_dummy().bit(dummy != 0);
2335 w.usr_addr().bit(!address.is_none());
2336 w.usr_command().bit(!cmd.is_none())
2337 });
2338
2339 #[cfg(not(any(esp32, esp32s2)))]
2341 reg_block.clk_gate().modify(|_, w| {
2342 w.clk_en().set_bit();
2343 w.mst_clk_active().set_bit();
2344 w.mst_clk_sel().set_bit()
2345 });
2346
2347 #[cfg(soc_has_pcr)]
2348 crate::peripherals::PCR::regs()
2350 .spi2_clkm_conf()
2351 .modify(|_, w| unsafe { w.spi2_clkm_sel().bits(1) });
2352
2353 #[cfg(not(esp32))]
2354 reg_block.misc().write(|w| unsafe { w.bits(0) });
2355
2356 reg_block.slave().write(|w| unsafe { w.bits(0) });
2357
2358 self.update();
2359
2360 self.set_up_common_phases(cmd, address, dummy);
2362
2363 Ok(())
2364 }
2365
2366 fn set_up_common_phases(&self, cmd: Command, address: Address, dummy: u8) {
2367 let reg_block = self.regs();
2368 if !cmd.is_none() {
2369 reg_block.user2().modify(|_, w| unsafe {
2370 w.usr_command_bitlen().bits((cmd.width() - 1) as u8);
2371 w.usr_command_value().bits(cmd.value())
2372 });
2373 }
2374
2375 if !address.is_none() {
2376 reg_block
2377 .user1()
2378 .modify(|_, w| unsafe { w.usr_addr_bitlen().bits((address.width() - 1) as u8) });
2379
2380 let addr = address.value() << (32 - address.width());
2381 #[cfg(not(esp32))]
2382 reg_block
2383 .addr()
2384 .write(|w| unsafe { w.usr_addr_value().bits(addr) });
2385 #[cfg(esp32)]
2386 reg_block.addr().write(|w| unsafe { w.bits(addr) });
2387 }
2388
2389 if dummy > 0 {
2390 reg_block
2391 .user1()
2392 .modify(|_, w| unsafe { w.usr_dummy_cyclelen().bits(dummy - 1) });
2393 }
2394 }
2395
2396 fn update(&self) {
2397 cfg_if::cfg_if! {
2398 if #[cfg(not(any(esp32, esp32s2)))] {
2399 let reg_block = self.regs();
2400
2401 reg_block.cmd().modify(|_, w| w.update().set_bit());
2402
2403 while reg_block.cmd().read().update().bit_is_set() {
2404 }
2406 } else {
2407 }
2409 }
2410 }
2411
2412 fn configure_datalen(&self, rx_len_bytes: usize, tx_len_bytes: usize) {
2413 let reg_block = self.regs();
2414
2415 let rx_len = rx_len_bytes as u32 * 8;
2416 let tx_len = tx_len_bytes as u32 * 8;
2417
2418 let rx_len = rx_len.saturating_sub(1);
2419 let tx_len = tx_len.saturating_sub(1);
2420
2421 cfg_if::cfg_if! {
2422 if #[cfg(esp32)] {
2423 let len = rx_len.max(tx_len);
2424 reg_block
2425 .mosi_dlen()
2426 .write(|w| unsafe { w.usr_mosi_dbitlen().bits(len) });
2427
2428 reg_block
2429 .miso_dlen()
2430 .write(|w| unsafe { w.usr_miso_dbitlen().bits(len) });
2431 } else if #[cfg(esp32s2)] {
2432 reg_block
2433 .mosi_dlen()
2434 .write(|w| unsafe { w.usr_mosi_dbitlen().bits(tx_len) });
2435
2436 reg_block
2437 .miso_dlen()
2438 .write(|w| unsafe { w.usr_miso_dbitlen().bits(rx_len) });
2439 } else {
2440 reg_block
2441 .ms_dlen()
2442 .write(|w| unsafe { w.ms_data_bitlen().bits(rx_len.max(tx_len)) });
2443 }
2444
2445 }
2446 }
2447}
2448
2449impl PartialEq for Info {
2450 fn eq(&self, other: &Self) -> bool {
2451 core::ptr::eq(self.register_block, other.register_block)
2452 }
2453}
2454
2455unsafe impl Sync for Info {}
2456
2457for_each_spi_master! {
2458 ($peri:ident, $sys:ident, $sclk:ident [$($cs:ident),+] [$($sio:ident),*] $(, $is_qspi:tt)?) => {
2459 impl Instance for crate::peripherals::$peri<'_> {
2460 #[inline(always)]
2461 fn parts(&self) -> (&'static Info, &'static State) {
2462 #[handler]
2463 #[ram]
2464 fn irq_handler() {
2465 handle_async(&INFO, &STATE)
2466 }
2467
2468 static INFO: Info = Info {
2469 register_block: crate::peripherals::$peri::regs(),
2470 peripheral: crate::system::Peripheral::$sys,
2471 async_handler: irq_handler,
2472 sclk: OutputSignal::$sclk,
2473 cs: &[$(OutputSignal::$cs),+],
2474 sio_inputs: &[$(InputSignal::$sio),*],
2475 sio_outputs: &[$(OutputSignal::$sio),*],
2476 };
2477
2478 static STATE: State = State {
2479 waker: AtomicWaker::new(),
2480 pins: UnsafeCell::new(MaybeUninit::uninit()),
2481
2482 #[cfg(esp32)]
2483 esp32_hack: Esp32Hack {
2484 timing_miso_delay: Cell::new(None),
2485 extra_dummy: Cell::new(0),
2486 },
2487 };
2488
2489 (&INFO, &STATE)
2490 }
2491 }
2492
2493 $(
2494 $crate::ignore!($is_qspi);
2496 impl QspiInstance for crate::peripherals::$peri<'_> {}
2497 )?
2498 };
2499}
2500
2501impl QspiInstance for AnySpi<'_> {}
2502
2503#[doc(hidden)]
2504pub struct State {
2505 waker: AtomicWaker,
2506 pins: UnsafeCell<MaybeUninit<SpiPinGuard>>,
2507
2508 #[cfg(esp32)]
2509 esp32_hack: Esp32Hack,
2510}
2511
2512impl State {
2513 #[allow(
2521 clippy::mut_from_ref,
2522 reason = "Safety requirements ensure this is okay"
2523 )]
2524 unsafe fn pins(&self) -> &mut SpiPinGuard {
2525 unsafe { (&mut *self.pins.get()).assume_init_mut() }
2526 }
2527
2528 unsafe fn deinit(&self) {
2529 unsafe {
2530 let mut old = self.pins.get().replace(MaybeUninit::uninit());
2531 old.assume_init_drop();
2532 }
2533 }
2534}
2535
2536#[cfg(esp32)]
2537struct Esp32Hack {
2538 timing_miso_delay: Cell<Option<u8>>,
2539 extra_dummy: Cell<u8>,
2540}
2541
2542unsafe impl Sync for State {}
2543
2544#[ram]
2545fn handle_async(info: &'static Info, state: &'static State) {
2546 let driver = Driver { info, state };
2547 if driver.interrupts().contains(SpiInterrupt::TransferDone) {
2548 driver.enable_listen(SpiInterrupt::TransferDone.into(), false);
2549 state.waker.wake();
2550 }
2551}
2552
2553#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2555#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2556#[instability::unstable]
2557pub enum DataMode {
2558 SingleTwoDataLines,
2560 Single,
2562 Dual,
2564 Quad,
2566 #[cfg(spi_master_has_octal)]
2567 Octal,
2569}
2570
2571crate::any_peripheral! {
2572 pub peripheral AnySpi<'d> {
2574 #[cfg(spi_master_spi2)]
2575 Spi2(crate::peripherals::SPI2<'d>),
2576 #[cfg(spi_master_spi3)]
2577 Spi3(crate::peripherals::SPI3<'d>),
2578 }
2579}
2580
2581impl Instance for AnySpi<'_> {
2582 #[inline]
2583 fn parts(&self) -> (&'static Info, &'static State) {
2584 any::delegate!(self, spi => { spi.parts() })
2585 }
2586}
2587
2588impl AnySpi<'_> {
2589 fn bind_peri_interrupt(&self, handler: InterruptHandler) {
2590 any::delegate!(self, spi => { spi.bind_peri_interrupt(handler) })
2591 }
2592
2593 fn disable_peri_interrupt_on_all_cores(&self) {
2594 any::delegate!(self, spi => { spi.disable_peri_interrupt_on_all_cores() })
2595 }
2596
2597 fn set_interrupt_handler(&self, handler: InterruptHandler) {
2598 self.disable_peri_interrupt_on_all_cores();
2599 self.bind_peri_interrupt(handler);
2600 }
2601}
2602
2603struct SpiFuture<'a> {
2604 driver: &'a Driver,
2605}
2606
2607impl SpiFuture<'_> {
2608 const EVENTS: EnumSet<SpiInterrupt> = enum_set!(SpiInterrupt::TransferDone);
2609}
2610
2611impl Future for SpiFuture<'_> {
2612 type Output = ();
2613
2614 #[cfg_attr(place_spi_master_driver_in_ram, ram)]
2615 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
2616 if self.driver.busy() {
2617 self.driver.state.waker.register(cx.waker());
2618 self.driver.enable_listen(Self::EVENTS, true);
2619
2620 Poll::Pending
2621 } else {
2622 self.driver.clear_interrupts(Self::EVENTS);
2623 Poll::Ready(())
2624 }
2625 }
2626}
2627
2628impl Drop for SpiFuture<'_> {
2629 fn drop(&mut self) {
2630 self.driver.enable_listen(Self::EVENTS, false);
2631 }
2632}