Skip to main content

gd32e2_hal/
spi.rs

1//! SPI master.
2//!
3//! Master, full-duplex, with software NSS (chip select is an ordinary GPIO the
4//! caller toggles). Frames are 8 or 16 bits wide, selected by a typestate
5//! parameter.
6//!
7//! Every operation is a simultaneous *exchange* — a word leaves on MOSI while
8//! another arrives on MISO — so [`SpiBus::read`] sends zeros and
9//! [`SpiBus::write`] discards what comes back.
10//!
11//! ```ignore
12//! let sck = parts.pa5.into_alternate::<0>();
13//! let miso = parts.pa6.into_alternate::<0>();
14//! let mosi = parts.pa7.into_alternate::<0>();
15//! let mut spi = Spi::new(&mut rcu, dp.spi0, sck, miso, mosi, SpiConfig::new(SpiPsc::Div8));
16//! ```
17
18use 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
26/// SPI1 `DZ` encodes the frame length as (bits - 1); values below 0b0011 are
27/// forced to 8-bit by hardware.
28const DZ_8BIT: u8 = 0b0111;
29const DZ_16BIT: u8 = 0b1111;
30
31/// Named idle levels for the side of an exchange that carries no data.
32///
33/// Every transfer is simultaneous, so reading `n` words means sending `n` of
34/// them. Which value drives the wire is the target's business, not the bus's:
35/// most accept anything, SD cards want MOSI high. Purely a readability aid —
36/// any value is legal.
37#[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/// SCK prescaler: divides `pclk` down to the serial clock.
46///
47/// The right divider depends on `pclk` and the slave's maximum clock.
48#[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/// Order in which the bits of a word are shifted onto the wire.
63///
64/// Both ends of the link must agree, or every word arrives bit-reversed with no
65/// error reported. Most devices are MSB-first, which is the default.
66#[derive(Clone, Copy, PartialEq, Eq)]
67#[cfg_attr(feature = "defmt", derive(defmt::Format))]
68pub enum BitOrder {
69    /// Most significant bit first.
70    MsbFirst,
71    /// Least significant bit first.
72    LsbFirst,
73}
74
75/// Bus configuration passed to [`Spi::new`] / [`Spi::new_word`].
76///
77/// Built with [`SpiConfig::new`], which requires a prescaler; [`mode`](Self::mode)
78/// and [`bit_order`](Self::bit_order) refine the defaults fluently.
79///
80/// ```ignore
81/// SpiConfig::new(SpiPsc::Div16)
82///     .mode(embedded_hal::spi::MODE_3)
83///     .bit_order(BitOrder::LsbFirst)
84/// ```
85#[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    /// Creates a configuration with the given prescaler, Mode 0 and MSB-first.
96    ///
97    /// The prescaler is a required argument: an SCK divider has no conventional
98    /// value.
99    pub const fn new(psc: SpiPsc) -> Self {
100        Self {
101            psc,
102            mode: MODE_0,
103            bit_order: BitOrder::MsbFirst,
104        }
105    }
106    /// Sets the clock polarity and phase (CPOL/CPHA), per the slave's datasheet.
107    pub const fn mode(mut self, mode: Mode) -> Self {
108        self.mode = mode;
109        self
110    }
111    /// Sets the bit order. Defaults to [`BitOrder::MsbFirst`].
112    pub const fn bit_order(mut self, bit_order: BitOrder) -> Self {
113        self.bit_order = bit_order;
114        self
115    }
116}
117
118/// Marks a pin usable as `SCK` for `SPI`, in the right alternate function.
119pub trait SckPin<SPI> {}
120/// Marks a pin usable as `MISO` for `SPI`, in the right alternate function.
121pub trait MisoPin<SPI> {}
122/// Marks a pin usable as `MOSI` for `SPI`, in the right alternate function.
123pub 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
139// PB13/PB14/PB15 at AF0 belong to a *different* SPI depending on the chip
140// variant (datasheet Table 2-14 footnotes): SPI0 on GD32E230x4, SPI1 on
141// GD32E230x8. They are therefore listed in the gated blocks, not here.
142//
143// The `pads_ge_*` gates say the package bonds the pin at all, and match the ones in
144// `gpio::Parts`.
145spi_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// ---- (1) GD32E230x4 only: PB13/14/15 AF0 are SPI0 ----
153#[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// ---- (3) GD32E230x8 only: SPI1 exists, and PB13/14/15 AF0 belong to it ----
162// NB: below 48 pins this leaves PB1 plus PA13/PA14 — the SWD pair, reachable only
163// through the `activate_into_*` family, at the cost of the debug port.
164#[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
172/// Word-width marker: 8-bit frames ([`Spi::transfer_byte`], `SpiBus<u8>`).
173pub struct Byte;
174/// Word-width marker: 16-bit frames ([`Spi::transfer_word`], `SpiBus<u16>`).
175pub struct Word;
176
177/// An error the peripheral flagged in `STAT`.
178///
179/// [`kind`] gives the portable classification.
180///
181/// [`kind`]: embedded_hal::spi::Error::kind
182#[derive(Clone, Copy, Debug, PartialEq, Eq)]
183#[cfg_attr(feature = "defmt", derive(defmt::Format))]
184#[non_exhaustive]
185pub enum Error {
186    /// A received word was overwritten before it had been read (`RXORERR`).
187    Overrun,
188    /// `NSS` was pulled low while configured as a master (`CONFERR`) — another
189    /// master is driving the bus.
190    ModeFault,
191    /// The received CRC does not match the one computed locally (`CRCERR`).
192    Crc,
193    /// A frame boundary arrived where none was expected (`FERR`), which only
194    /// the TI frame format can report.
195    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            // No CRC variant exists upstream.
204            Self::Crc => ErrorKind::Other,
205            Self::Framing => ErrorKind::FrameFormat,
206        }
207    }
208}
209
210/// A peripheral that [`Spi`] can drive.
211pub trait Instance: Enable + Reset {
212    /// Writes the full master configuration, leaving the peripheral enabled.
213    ///
214    /// `wide` selects the frame width, and the impl handles what follows from it
215    /// (on SPI1 the FIFO access size must match, or reception stalls).
216    fn apply_config(&mut self, config: SpiConfig, wide: bool);
217    /// Transmit buffer empty — ready to accept the next word.
218    fn tbe(&self) -> bool;
219    /// Receive buffer not empty — a word has arrived.
220    fn rbne(&self) -> bool;
221    /// Writes a word to the data register, which starts the clock in master mode.
222    fn write_data(&mut self, word: u16);
223    /// Reads the received word from the data register.
224    fn read_data(&mut self) -> u16;
225    /// Returns the first pending error, if any, clearing it as the manual requires.
226    fn take_error(&mut self) -> Option<Error>;
227    /// Enables or disables the receive interrupt (`RBNEIE`).
228    fn set_rbneie(&mut self, on: bool);
229    /// Reads back `RBNEIE`.
230    fn rbneie(&self) -> bool;
231    /// Enables or disables the transmit interrupt (`TBEIE`).
232    fn set_tbeie(&mut self, on: bool);
233    /// Reads back `TBEIE`.
234    fn tbeie(&self) -> bool;
235    /// Enables or disables the error interrupt (`ERRIE`).
236    fn set_errie(&mut self, on: bool);
237    /// Reads back `ERRIE`.
238    fn errie(&self) -> bool;
239    /// Waits for the last word to leave the wire, clears `SPIEN` and drains the
240    /// receive side, in the order the manual gives for this instance.
241    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            // SAFETY: `SpiPsc` discriminants are the eight `PSC` codes.
266            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        // SAFETY: `DATA` takes any 16-bit word.
280        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            // clear: read DATA (done in transfer_byte) + read STAT (above)
291            Some(Error::Overrun)
292        } else if stat.conferr().bit_is_set() {
293            // clear: read STAT (above) + write CTL0
294            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            // SAFETY: both constants are `DZ` codes, for 8 and 16 bits.
346            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            // SAFETY: `SpiPsc` discriminants are the eight `PSC` codes.
365            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        // SAFETY: `DATA` takes any 16-bit word.
379        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            // clear: read DATA (done in transfer_byte) + read STAT (above)
390            Some(Error::Overrun)
391        } else if stat.conferr().bit_is_set() {
392            // clear: read STAT (above) + write CTL0
393            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/// An SPI event that can raise an interrupt.
440#[derive(Clone, Copy, PartialEq, Eq)]
441#[cfg_attr(feature = "defmt", derive(defmt::Format))]
442pub enum Event {
443    /// A word arrived in `DATA`, cleared by reading it.
444    Rbne,
445    /// The transmit buffer is free — true at idle, so listening for this needs
446    /// `unlisten` from inside the handler once nothing is left to send.
447    Tbe,
448    /// Any of the `STAT` error flags, which share this one enable. Cleared by
449    /// [`take_error`](Spi::take_error), which a handler must call — nothing
450    /// else drains them.
451    Error,
452}
453
454/// A configured SPI master, owning the peripheral and its three pins.
455///
456/// `WORD` is the frame width: [`transfer_byte`](Self::transfer_byte) and
457/// `SpiBus<u8>` live on `Spi<.., Byte>`, [`transfer_word`](Self::transfer_word)
458/// and `SpiBus<u16>` on `Spi<.., Word>`. Defaults to [`Byte`].
459///
460/// Chip select is not handled here — NSS is software-managed, so drive the
461/// slave's CS with an ordinary output pin around each transaction.
462pub 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    /// Enables the peripheral's clock, resets it and configures 8-bit master mode.
478    ///
479    /// The pins must already be in this SPI's alternate function;
480    /// [`release`](Spi::release) hands them back.
481    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    /// Same as [`new`](Spi::new), but configures 16-bit frames.
510    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    /// Returns whether a received word is waiting in `DATA` (`RBNE`).
536    ///
537    /// Only guarantees that the next single read will not block.
538    pub fn read_ready(&self) -> bool {
539        self.spi.rbne()
540    }
541    /// Returns whether `DATA` can accept the next word (`TBE`).
542    ///
543    /// True at idle, the bus having nothing queued; it says nothing about a word
544    /// still on its way back.
545    pub fn write_ready(&self) -> bool {
546        self.spi.tbe()
547    }
548    /// Returns the pending error, if any, and clears it.
549    ///
550    /// The acknowledge for [`Event::Error`]: those flags are what hold the
551    /// interrupt request up, so a handler that skips this re-enters forever.
552    /// One error per call — with two pending, the second survives for the next.
553    /// Overrun also needs `DATA` drained, which the read a handler makes to do
554    /// its work already does.
555    pub fn take_error(&mut self) -> Option<Error> {
556        self.spi.take_error()
557    }
558
559    /// Raises an interrupt on `event`, which still has to be unmasked in the
560    /// NVIC.
561    ///
562    /// [`Event::Tbe`] is true whenever nothing is queued, so a handler that
563    /// listens for it must call `unlisten` once it has nothing left to send.
564    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    /// Stops raising an interrupt on `event`.
572    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    /// Whether `event` is being listened for.
580    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    /// Waits for the last word to leave the wire, then returns the peripheral
589    /// and the three pins, disabled, with its interrupts off and its clock
590    /// stopped. A received word not yet read is discarded.
591    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    /// Hands one byte to `DATA` and returns at once, the clock now running.
606    ///
607    /// Half an exchange: the answer arrives eight clocks later, on
608    /// [`Event::Rbne`]. Check [`write_ready`](Spi::write_ready) first — writing
609    /// over a full transmit buffer loses the byte.
610    pub fn write_byte(&mut self, byte: u8) {
611        self.spi.write_data(byte as u16);
612    }
613    /// Takes the byte that arrived on MISO, clearing `RBNE`.
614    ///
615    /// The other half: meaningful only once [`read_ready`](Spi::read_ready)
616    /// holds, and it reports no error — [`take_error`](Spi::take_error) drains
617    /// those.
618    pub fn read_byte(&mut self) -> u8 {
619        self.spi.read_data() as u8
620    }
621
622    /// Exchanges one byte: sends `byte` on MOSI and returns what arrived on MISO.
623    ///
624    /// Blocks until the exchange has completed, so nothing is left pending on the
625    /// bus when it returns.
626    ///
627    /// # Errors
628    ///
629    /// The error [`take_error`](Spi::take_error) finds once the exchange is
630    /// over; the received byte is then discarded.
631    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    /// Exchanges two buffers: byte `i` of `write` goes out and what comes back
643    /// lands at byte `i` of `read`.
644    ///
645    /// # Errors
646    ///
647    /// The first failed exchange, as in [`transfer_byte`](Spi::transfer_byte);
648    /// the bytes after it are neither sent nor received.
649    ///
650    /// # Panics
651    ///
652    /// If the lengths differ. To read more than is written, pad `write` —
653    /// [`fill`] names the usual levels.
654    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    /// Exchanges `words` against itself: each byte is replaced by what came back.
665    ///
666    /// # Errors
667    ///
668    /// The first failed exchange, as in [`transfer_byte`](Spi::transfer_byte);
669    /// the bytes after it are neither sent nor received.
670    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    /// Hands one 16-bit word to `DATA` and returns at once, the clock now running.
683    ///
684    /// Half an exchange: the answer arrives sixteen clocks later, on
685    /// [`Event::Rbne`]. Check [`write_ready`](Spi::write_ready) first — writing
686    /// over a full transmit buffer loses the word.
687    pub fn write_word(&mut self, word: u16) {
688        self.spi.write_data(word);
689    }
690    /// Takes the word that arrived on MISO, clearing `RBNE`.
691    ///
692    /// The other half: meaningful only once [`read_ready`](Spi::read_ready)
693    /// holds, and it reports no error — [`take_error`](Spi::take_error) drains
694    /// those.
695    pub fn read_word(&mut self) -> u16 {
696        self.spi.read_data()
697    }
698
699    /// Exchanges one 16-bit word: sends `word` on MOSI, returns what arrived on MISO.
700    ///
701    /// Blocks until the exchange has completed, so nothing is left pending on the
702    /// bus when it returns.
703    ///
704    /// # Errors
705    ///
706    /// The error [`take_error`](Spi::take_error) finds once the exchange is
707    /// over; the received word is then discarded.
708    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    /// Exchanges two buffers: word `i` of `write` goes out and what comes back
720    /// lands at word `i` of `read`.
721    ///
722    /// # Errors
723    ///
724    /// The first failed exchange, as in [`transfer_word`](Spi::transfer_word);
725    /// the words after it are neither sent nor received.
726    ///
727    /// # Panics
728    ///
729    /// If the lengths differ. To read more than is written, pad `write` —
730    /// [`fill`] names the usual levels.
731    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    /// Exchanges `words` against itself: each word is replaced by what came back.
742    ///
743    /// # Errors
744    ///
745    /// The first failed exchange, as in [`transfer_word`](Spi::transfer_word);
746    /// the words after it are neither sent nor received.
747    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        // No-op: transfer_byte blocks until RBNE (the byte is fully exchanged),
774        // so nothing is ever pending on the bus when a method returns.
775        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        // No-op: transfer_word blocks until RBNE (the word is fully exchanged),
803        // so nothing is ever pending on the bus when a method returns.
804        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}