1use core::marker::PhantomData;
19
20use embedded_hal::spi::{ErrorKind, ErrorType, MODE_0, Mode, Phase, Polarity, SpiBus};
21
22use crate::gpio::{Alternate, Pin};
23use crate::pac;
24use crate::rcu::{Enable, Rcu, Reset};
25
26const DZ_8BIT: u8 = 0b0111;
29const DZ_16BIT: u8 = 0b1111;
30
31#[allow(missing_docs)]
38pub mod fill {
39 pub const LOW: u8 = 0x00;
40 pub const HIGH: u8 = 0xFF;
41 pub const LOW_WORD: u16 = 0x0000;
42 pub const HIGH_WORD: u16 = 0xFFFF;
43}
44
45#[derive(Clone, Copy, PartialEq, Eq)]
49#[cfg_attr(feature = "defmt", derive(defmt::Format))]
50#[allow(missing_docs)]
51pub enum SpiPsc {
52 Div2 = 0b000,
53 Div4 = 0b001,
54 Div8 = 0b010,
55 Div16 = 0b011,
56 Div32 = 0b100,
57 Div64 = 0b101,
58 Div128 = 0b110,
59 Div256 = 0b111,
60}
61
62#[derive(Clone, Copy, PartialEq, Eq)]
67#[cfg_attr(feature = "defmt", derive(defmt::Format))]
68pub enum BitOrder {
69 MsbFirst,
71 LsbFirst,
73}
74
75#[derive(Clone, Copy, PartialEq, Eq)]
86#[cfg_attr(feature = "defmt", derive(defmt::Format))]
87#[must_use]
88pub struct SpiConfig {
89 psc: SpiPsc,
90 mode: Mode,
91 bit_order: BitOrder,
92}
93
94impl SpiConfig {
95 pub const fn new(psc: SpiPsc) -> Self {
100 Self {
101 psc,
102 mode: MODE_0,
103 bit_order: BitOrder::MsbFirst,
104 }
105 }
106 pub const fn mode(mut self, mode: Mode) -> Self {
108 self.mode = mode;
109 self
110 }
111 pub const fn bit_order(mut self, bit_order: BitOrder) -> Self {
113 self.bit_order = bit_order;
114 self
115 }
116}
117
118pub trait SckPin<SPI> {}
120pub trait MisoPin<SPI> {}
122pub trait MosiPin<SPI> {}
124
125macro_rules! spi_pins {
126 ( $( $SPI:ty:
127 SCK: [ $($(#[$sck_cfg:meta])? $sck_p:literal $sck_n:literal : $sck_af:literal),* $(,)? ]
128 MISO: [ $($(#[$miso_cfg:meta])? $miso_p:literal $miso_n:literal : $miso_af:literal),* $(,)? ]
129 MOSI: [ $($(#[$mosi_cfg:meta])? $mosi_p:literal $mosi_n:literal : $mosi_af:literal),* $(,)? ]
130 ),* $(,)? ) => {
131 $(
132 $( $(#[$sck_cfg])? impl SckPin<$SPI> for Pin<$sck_p, $sck_n, Alternate<$sck_af>> {} )*
133 $( $(#[$miso_cfg])? impl MisoPin<$SPI> for Pin<$miso_p, $miso_n, Alternate<$miso_af>> {} )*
134 $( $(#[$mosi_cfg])? impl MosiPin<$SPI> for Pin<$mosi_p, $mosi_n, Alternate<$mosi_af>> {} )*
135 )*
136 };
137}
138
139spi_pins!(
146 pac::Spi0:
147 SCK: ['A' 5 : 0, #[cfg(pads_ge_28)] 'B' 3 : 0]
148 MISO: ['A' 6 : 0, #[cfg(pads_ge_28)] 'B' 4 : 0]
149 MOSI: ['A' 7 : 0, #[cfg(pads_ge_28)] 'B' 5 : 0]
150);
151
152#[cfg(chip_x4)]
154spi_pins!(
155 pac::Spi0:
156 SCK: [#[cfg(pads_ge_48)] 'B' 13 : 0]
157 MISO: [#[cfg(pads_ge_48)] 'B' 14 : 0]
158 MOSI: [#[cfg(pads_ge_48)] 'B' 15 : 0]
159);
160
161#[cfg(chip_x8)]
165spi_pins!(
166 pac::Spi1:
167 SCK: ['B' 1 : 6, #[cfg(pads_ge_48)] 'B' 10 : 7, #[cfg(pads_ge_48)] 'B' 13 : 0]
168 MISO: ['A' 13 : 6, #[cfg(pads_ge_48)] 'B' 14 : 0]
169 MOSI: ['A' 14 : 6, #[cfg(pads_ge_48)] 'B' 15 : 0]
170);
171
172pub struct Byte;
174pub struct Word;
176
177#[derive(Clone, Copy, Debug, PartialEq, Eq)]
183#[cfg_attr(feature = "defmt", derive(defmt::Format))]
184#[non_exhaustive]
185pub enum Error {
186 Overrun,
188 ModeFault,
191 Crc,
193 Framing,
196}
197
198impl embedded_hal::spi::Error for Error {
199 fn kind(&self) -> ErrorKind {
200 match self {
201 Self::Overrun => ErrorKind::Overrun,
202 Self::ModeFault => ErrorKind::ModeFault,
203 Self::Crc => ErrorKind::Other,
205 Self::Framing => ErrorKind::FrameFormat,
206 }
207 }
208}
209
210pub trait Instance: Enable + Reset {
212 fn apply_config(&mut self, config: SpiConfig, wide: bool);
217 fn tbe(&self) -> bool;
219 fn rbne(&self) -> bool;
221 fn write_data(&mut self, word: u16);
223 fn read_data(&mut self) -> u16;
225 fn take_error(&mut self) -> Option<Error>;
227 fn set_rbneie(&mut self, on: bool);
229 fn rbneie(&self) -> bool;
231 fn set_tbeie(&mut self, on: bool);
233 fn tbeie(&self) -> bool;
235 fn set_errie(&mut self, on: bool);
237 fn errie(&self) -> bool;
239 fn shut_down(&mut self);
242}
243
244impl Instance for pac::Spi0 {
245 #[inline]
246 fn apply_config(&mut self, config: SpiConfig, wide: bool) {
247 self.ctl0().modify(|_, w| {
248 let w = w
249 .mstmod()
250 .set_bit()
251 .swnssen()
252 .set_bit()
253 .swnss()
254 .set_bit()
255 .lf()
256 .bit(config.bit_order == BitOrder::LsbFirst)
257 .ff16()
258 .bit(wide)
259 .spien()
260 .set_bit()
261 .ckpl()
262 .bit(config.mode.polarity == Polarity::IdleHigh)
263 .ckph()
264 .bit(config.mode.phase == Phase::CaptureOnSecondTransition);
265 unsafe { w.psc().bits(config.psc as u8) }
267 });
268 }
269 #[inline]
270 fn tbe(&self) -> bool {
271 self.stat().read().tbe().bit_is_set()
272 }
273 #[inline]
274 fn rbne(&self) -> bool {
275 self.stat().read().rbne().bit_is_set()
276 }
277 #[inline]
278 fn write_data(&mut self, word: u16) {
279 self.data().write(|w| unsafe { w.data().bits(word) });
281 }
282 #[inline]
283 fn read_data(&mut self) -> u16 {
284 self.data().read().data().bits()
285 }
286 #[inline]
287 fn take_error(&mut self) -> Option<Error> {
288 let stat = self.stat().read();
289 if stat.rxorerr().bit_is_set() {
290 Some(Error::Overrun)
292 } else if stat.conferr().bit_is_set() {
293 self.ctl0().modify(|_, w| w);
295 Some(Error::ModeFault)
296 } else if stat.crcerr().bit_is_set() {
297 self.stat().modify(|_, w| w.crcerr().clear_bit());
298 Some(Error::Crc)
299 } else if stat.ferr().bit_is_set() {
300 self.stat().modify(|_, w| w.ferr().clear_bit());
301 Some(Error::Framing)
302 } else {
303 None
304 }
305 }
306 #[inline]
307 fn set_rbneie(&mut self, on: bool) {
308 self.ctl1().modify(|_, w| w.rbneie().bit(on));
309 }
310 #[inline]
311 fn rbneie(&self) -> bool {
312 self.ctl1().read().rbneie().bit_is_set()
313 }
314 #[inline]
315 fn set_tbeie(&mut self, on: bool) {
316 self.ctl1().modify(|_, w| w.tbeie().bit(on));
317 }
318 #[inline]
319 fn tbeie(&self) -> bool {
320 self.ctl1().read().tbeie().bit_is_set()
321 }
322 #[inline]
323 fn set_errie(&mut self, on: bool) {
324 self.ctl1().modify(|_, w| w.errie().bit(on));
325 }
326 #[inline]
327 fn errie(&self) -> bool {
328 self.ctl1().read().errie().bit_is_set()
329 }
330 #[inline]
331 fn shut_down(&mut self) {
332 while !self.tbe() || self.stat().read().trans().bit_is_set() {}
333 self.ctl0().modify(|_, w| w.spien().clear_bit());
334 if self.rbne() {
335 self.read_data();
336 }
337 }
338}
339
340impl Instance for pac::Spi1 {
341 #[inline]
342 fn apply_config(&mut self, config: SpiConfig, wide: bool) {
343 self.ctl1().modify(|_, w| {
344 let w = w.byten().bit(!wide);
345 unsafe { w.dz().bits(if wide { DZ_16BIT } else { DZ_8BIT }) }
347 });
348 self.ctl0().modify(|_, w| {
349 let w = w
350 .mstmod()
351 .set_bit()
352 .swnssen()
353 .set_bit()
354 .swnss()
355 .set_bit()
356 .lf()
357 .bit(config.bit_order == BitOrder::LsbFirst)
358 .spien()
359 .set_bit()
360 .ckpl()
361 .bit(config.mode.polarity == Polarity::IdleHigh)
362 .ckph()
363 .bit(config.mode.phase == Phase::CaptureOnSecondTransition);
364 unsafe { w.psc().bits(config.psc as u8) }
366 });
367 }
368 #[inline]
369 fn tbe(&self) -> bool {
370 self.stat().read().tbe().bit_is_set()
371 }
372 #[inline]
373 fn rbne(&self) -> bool {
374 self.stat().read().rbne().bit_is_set()
375 }
376 #[inline]
377 fn write_data(&mut self, word: u16) {
378 self.data().write(|w| unsafe { w.data().bits(word) });
380 }
381 #[inline]
382 fn read_data(&mut self) -> u16 {
383 self.data().read().data().bits()
384 }
385 #[inline]
386 fn take_error(&mut self) -> Option<Error> {
387 let stat = self.stat().read();
388 if stat.rxorerr().bit_is_set() {
389 Some(Error::Overrun)
391 } else if stat.conferr().bit_is_set() {
392 self.ctl0().modify(|_, w| w);
394 Some(Error::ModeFault)
395 } else if stat.crcerr().bit_is_set() {
396 self.stat().modify(|_, w| w.crcerr().clear_bit());
397 Some(Error::Crc)
398 } else if stat.ferr().bit_is_set() {
399 self.stat().modify(|_, w| w.ferr().clear_bit());
400 Some(Error::Framing)
401 } else {
402 None
403 }
404 }
405 #[inline]
406 fn set_rbneie(&mut self, on: bool) {
407 self.ctl1().modify(|_, w| w.rbneie().bit(on));
408 }
409 #[inline]
410 fn rbneie(&self) -> bool {
411 self.ctl1().read().rbneie().bit_is_set()
412 }
413 #[inline]
414 fn set_tbeie(&mut self, on: bool) {
415 self.ctl1().modify(|_, w| w.tbeie().bit(on));
416 }
417 #[inline]
418 fn tbeie(&self) -> bool {
419 self.ctl1().read().tbeie().bit_is_set()
420 }
421 #[inline]
422 fn set_errie(&mut self, on: bool) {
423 self.ctl1().modify(|_, w| w.errie().bit(on));
424 }
425 #[inline]
426 fn errie(&self) -> bool {
427 self.ctl1().read().errie().bit_is_set()
428 }
429 #[inline]
430 fn shut_down(&mut self) {
431 while self.stat().read().txlvl().bits() != 0 || self.stat().read().trans().bit_is_set() {}
432 self.ctl0().modify(|_, w| w.spien().clear_bit());
433 while self.stat().read().rxlvl().bits() != 0 {
434 self.read_data();
435 }
436 }
437}
438
439#[derive(Clone, Copy, PartialEq, Eq)]
441#[cfg_attr(feature = "defmt", derive(defmt::Format))]
442pub enum Event {
443 Rbne,
445 Tbe,
448 Error,
452}
453
454pub struct Spi<SPIX, SCK, MISO, MOSI, WORD = Byte> {
463 spi: SPIX,
464 sck_pin: SCK,
465 miso_pin: MISO,
466 mosi_pin: MOSI,
467 _word: PhantomData<WORD>,
468}
469
470impl<SPIX, SCK, MISO, MOSI> Spi<SPIX, SCK, MISO, MOSI, Byte>
471where
472 SPIX: Instance,
473 SCK: SckPin<SPIX>,
474 MISO: MisoPin<SPIX>,
475 MOSI: MosiPin<SPIX>,
476{
477 pub fn new(
482 rcu: &mut Rcu,
483 mut spi: SPIX,
484 sck_pin: SCK,
485 miso_pin: MISO,
486 mosi_pin: MOSI,
487 config: SpiConfig,
488 ) -> Self {
489 SPIX::enable(rcu);
490 SPIX::reset(rcu);
491 spi.apply_config(config, false);
492 Self {
493 spi,
494 sck_pin,
495 miso_pin,
496 mosi_pin,
497 _word: PhantomData,
498 }
499 }
500}
501
502impl<SPIX, SCK, MISO, MOSI> Spi<SPIX, SCK, MISO, MOSI, Word>
503where
504 SPIX: Instance,
505 SCK: SckPin<SPIX>,
506 MISO: MisoPin<SPIX>,
507 MOSI: MosiPin<SPIX>,
508{
509 pub fn new_word(
511 rcu: &mut Rcu,
512 mut spi: SPIX,
513 sck_pin: SCK,
514 miso_pin: MISO,
515 mosi_pin: MOSI,
516 config: SpiConfig,
517 ) -> Self {
518 SPIX::enable(rcu);
519 SPIX::reset(rcu);
520 spi.apply_config(config, true);
521 Self {
522 spi,
523 sck_pin,
524 miso_pin,
525 mosi_pin,
526 _word: PhantomData,
527 }
528 }
529}
530
531impl<SPIX, SCK, MISO, MOSI, WORD> Spi<SPIX, SCK, MISO, MOSI, WORD>
532where
533 SPIX: Instance,
534{
535 pub fn read_ready(&self) -> bool {
539 self.spi.rbne()
540 }
541 pub fn write_ready(&self) -> bool {
546 self.spi.tbe()
547 }
548 pub fn take_error(&mut self) -> Option<Error> {
556 self.spi.take_error()
557 }
558
559 pub fn listen(&mut self, event: Event) {
565 match event {
566 Event::Rbne => self.spi.set_rbneie(true),
567 Event::Tbe => self.spi.set_tbeie(true),
568 Event::Error => self.spi.set_errie(true),
569 }
570 }
571 pub fn unlisten(&mut self, event: Event) {
573 match event {
574 Event::Rbne => self.spi.set_rbneie(false),
575 Event::Tbe => self.spi.set_tbeie(false),
576 Event::Error => self.spi.set_errie(false),
577 }
578 }
579 pub fn is_listening(&self, event: Event) -> bool {
581 match event {
582 Event::Rbne => self.spi.rbneie(),
583 Event::Tbe => self.spi.tbeie(),
584 Event::Error => self.spi.errie(),
585 }
586 }
587
588 pub fn release(mut self, rcu: &mut Rcu) -> (SPIX, SCK, MISO, MOSI) {
592 self.spi.shut_down();
593 self.unlisten(Event::Rbne);
594 self.unlisten(Event::Tbe);
595 self.unlisten(Event::Error);
596 SPIX::disable(rcu);
597 (self.spi, self.sck_pin, self.miso_pin, self.mosi_pin)
598 }
599}
600
601impl<SPIX, SCK, MISO, MOSI> Spi<SPIX, SCK, MISO, MOSI, Byte>
602where
603 SPIX: Instance,
604{
605 pub fn write_byte(&mut self, byte: u8) {
611 self.spi.write_data(byte as u16);
612 }
613 pub fn read_byte(&mut self) -> u8 {
619 self.spi.read_data() as u8
620 }
621
622 pub fn transfer_byte(&mut self, byte: u8) -> Result<u8, Error> {
632 while !self.write_ready() {}
633 self.write_byte(byte);
634 while !self.read_ready() {}
635 let received = self.read_byte();
636 match self.take_error() {
637 Some(e) => Err(e),
638 None => Ok(received),
639 }
640 }
641
642 pub fn transfer_bytes(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> {
655 assert!(
656 read.len() == write.len(),
657 "SPI transfer buffers must be the same length"
658 );
659 for (slot, &byte) in read.iter_mut().zip(write) {
660 *slot = self.transfer_byte(byte)?;
661 }
662 Ok(())
663 }
664 pub fn transfer_bytes_in_place(&mut self, words: &mut [u8]) -> Result<(), Error> {
671 for word in words {
672 *word = self.transfer_byte(*word)?;
673 }
674 Ok(())
675 }
676}
677
678impl<SPIX, SCK, MISO, MOSI> Spi<SPIX, SCK, MISO, MOSI, Word>
679where
680 SPIX: Instance,
681{
682 pub fn write_word(&mut self, word: u16) {
688 self.spi.write_data(word);
689 }
690 pub fn read_word(&mut self) -> u16 {
696 self.spi.read_data()
697 }
698
699 pub fn transfer_word(&mut self, word: u16) -> Result<u16, Error> {
709 while !self.write_ready() {}
710 self.write_word(word);
711 while !self.read_ready() {}
712 let received = self.read_word();
713 match self.take_error() {
714 Some(e) => Err(e),
715 None => Ok(received),
716 }
717 }
718
719 pub fn transfer_words(&mut self, read: &mut [u16], write: &[u16]) -> Result<(), Error> {
732 assert!(
733 read.len() == write.len(),
734 "SPI transfer buffers must be the same length"
735 );
736 for (slot, &word) in read.iter_mut().zip(write) {
737 *slot = self.transfer_word(word)?;
738 }
739 Ok(())
740 }
741 pub fn transfer_words_in_place(&mut self, words: &mut [u16]) -> Result<(), Error> {
748 for word in words {
749 *word = self.transfer_word(*word)?;
750 }
751 Ok(())
752 }
753}
754
755impl<SPIX, SCK, MISO, MOSI, WORD> ErrorType for Spi<SPIX, SCK, MISO, MOSI, WORD>
756where
757 SPIX: Instance,
758{
759 type Error = Error;
760}
761
762impl<SPIX, SCK, MISO, MOSI> SpiBus<u8> for Spi<SPIX, SCK, MISO, MOSI, Byte>
763where
764 SPIX: Instance,
765{
766 fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
767 self.transfer_bytes(read, write)
768 }
769 fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
770 self.transfer_bytes_in_place(words)
771 }
772 fn flush(&mut self) -> Result<(), Self::Error> {
773 Ok(())
776 }
777 fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
778 for slot in words {
779 *slot = self.transfer_byte(fill::LOW)?;
780 }
781 Ok(())
782 }
783 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
784 for &byte in words {
785 self.transfer_byte(byte)?;
786 }
787 Ok(())
788 }
789}
790
791impl<SPIX, SCK, MISO, MOSI> SpiBus<u16> for Spi<SPIX, SCK, MISO, MOSI, Word>
792where
793 SPIX: Instance,
794{
795 fn transfer(&mut self, read: &mut [u16], write: &[u16]) -> Result<(), Self::Error> {
796 self.transfer_words(read, write)
797 }
798 fn transfer_in_place(&mut self, words: &mut [u16]) -> Result<(), Self::Error> {
799 self.transfer_words_in_place(words)
800 }
801 fn flush(&mut self) -> Result<(), Self::Error> {
802 Ok(())
805 }
806 fn read(&mut self, words: &mut [u16]) -> Result<(), Self::Error> {
807 for slot in words {
808 *slot = self.transfer_word(fill::LOW_WORD)?;
809 }
810 Ok(())
811 }
812 fn write(&mut self, words: &[u16]) -> Result<(), Self::Error> {
813 for &word in words {
814 self.transfer_word(word)?;
815 }
816 Ok(())
817 }
818}