Skip to main content

sam4l/
spi.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Implementation of DMA-based SPI master and slave communication for the
6//! SAM4L.
7//!
8//! Driver for the SPI hardware (separate from the USARTS), described in chapter
9//! 26 of the datasheet.
10//!
11//! - Authors: Sam Crow <samcrow@uw.edu>, Philip Levis <pal@cs.stanford.edu>
12
13use crate::dma::DMAChannel;
14use crate::dma::DMAClient;
15use crate::dma::DMAPeripheral;
16use crate::pm;
17use core::cell::Cell;
18use core::cmp;
19use kernel::ErrorCode;
20use kernel::hil::spi;
21use kernel::hil::spi::ClockPhase;
22use kernel::hil::spi::ClockPolarity;
23use kernel::hil::spi::SpiMasterClient;
24use kernel::hil::spi::SpiSlaveClient;
25use kernel::platform::chip::ClockInterface;
26use kernel::utilities::StaticRef;
27use kernel::utilities::cells::OptionalCell;
28use kernel::utilities::leasable_buffer::SubSliceMut;
29use kernel::utilities::peripheral_management::{PeripheralManagement, PeripheralManager};
30use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
31use kernel::utilities::registers::{
32    self, ReadOnly, ReadWrite, WriteOnly, register_bitfields, register_structs,
33};
34
35register_structs! {
36    pub SpiRegisters {
37        (0x000 => cr: WriteOnly<u32, Control::Register>),
38        (0x004 => mr: ReadWrite<u32, Mode::Register>),
39        (0x008 => rdr: ReadOnly<u32>),
40        (0x00C => tdr: WriteOnly<u32, TransmitData::Register>),
41        (0x010 => sr: ReadOnly<u32, Status::Register>),
42        (0x014 => ier: WriteOnly<u32, InterruptFlags::Register>),
43        (0x018 => idr: WriteOnly<u32, InterruptFlags::Register>),
44        (0x01C => imr: ReadOnly<u32, InterruptFlags::Register>),
45        (0x020 => _reserved0: [ReadOnly<u32>; 4]),
46        (0x030 => csr: [ReadWrite<u32, ChipSelectParams::Register>; 4]),
47        (0x040 => _reserved1: [ReadOnly<u32>; 41]),
48        (0x0E4 => wpcr: ReadWrite<u32, WriteProtectionControl::Register>),
49        (0x0E8 => wpsr: ReadOnly<u32>),
50        (0x0EC => _reserved2: [ReadOnly<u32>; 3]),
51        (0x0F8 => features: ReadOnly<u32>),
52        (0x0FC => version: ReadOnly<u32>),
53        (0x100 => @END),
54    }
55}
56
57register_bitfields![u32,
58    Control [
59        LASTXFER 24,
60        FLUSHFIFO 8,
61        SWRST 7,
62        SPIDIS 1,
63        SPIEN 0
64    ],
65
66    /// Mode of the SPI peripheral.
67    Mode [
68        /// Delay between chip selects
69        DLYBCS   OFFSET(24)  NUMBITS(8) [],
70        /// Peripheral chip select
71        PCS      OFFSET(16)  NUMBITS(4) [
72            /// One-hot encoding
73            PCS0 = 0b1110,
74            PCS1 = 0b1101,
75            PCS2 = 0b1011,
76            PCS3 = 0b0111
77        ],
78        /// Local loopback enable
79        LLB      OFFSET( 7)  NUMBITS(1) [],
80        /// FIFO in reception enable
81        RXFIFOEN OFFSET( 6)  NUMBITS(1) [],
82        /// Mode fault detection
83        MODFDIS  OFFSET( 4)  NUMBITS(1) [],
84        /// Chip select decode
85        PCSDEC   OFFSET( 2)  NUMBITS(1) [],
86        /// Peripheral select
87        PS       OFFSET( 1)  NUMBITS(1) [],
88        /// Master/slave mode
89        MSTR     OFFSET( 0)  NUMBITS(1) []
90    ],
91
92    TransmitData [
93        LASTXFER OFFSET(24)  NUMBITS(1),
94        PCS      OFFSET(16)  NUMBITS(4),
95        TD       OFFSET(0)   NUMBITS(16)
96    ],
97
98    Status [
99        SPIENS  OFFSET(16),
100        UNDES   OFFSET(10),
101        TXEMPTY OFFSET(9),
102        NSSR    OFFSET(8),
103        OVRES   OFFSET(3),
104        MODF    OFFSET(2),
105        TDRE    OFFSET(1),
106        RDRF    OFFSET(0)
107    ],
108
109    InterruptFlags [
110        UNDES 10,
111        TXEMPTY 9,
112        NSSR 8,
113        OVRES 3,
114        MODF 2,
115        TDRE 1,
116        RDRF 0
117    ],
118
119    ChipSelectParams [
120        DLYBCT OFFSET(24)  NUMBITS(8) [],
121        DLYBS  OFFSET(16)  NUMBITS(8) [],
122        SCBR   OFFSET(8)   NUMBITS(8) [],
123        BITS   OFFSET(4)   NUMBITS(8) [
124            Eight = 0,
125            Nine = 1,
126            Ten = 2,
127            Eleven = 3,
128            Twelve = 4,
129            Thirteen = 5,
130            Fourteen = 6,
131            Fifteen = 7,
132            Sixteen = 8,
133            Four = 9,
134            Five = 10,
135            Six = 11,
136            Seven = 12
137        ],
138        CSAAT OFFSET(3)  NUMBITS(1) [
139            ActiveAfterTransfer = 1,
140            InactiveAfterTransfer = 0
141        ],
142        CSNAAT OFFSET(2)  NUMBITS(1) [
143            DoNotRiseBetweenTransfers = 0,
144            RiseBetweenTransfers = 1
145        ],
146        NCPHA OFFSET(1)  NUMBITS(1) [
147            CaptureLeading = 1,
148            CaptureTrailing = 0
149        ],
150        CPOL OFFSET(0)  NUMBITS(1) [
151            InactiveHigh = 1,
152            InactiveLow = 0
153        ]
154    ],
155
156    WriteProtectionControl [
157        SPIWPKEY OFFSET(8) NUMBITS(24) [
158            Key = 0x535049
159        ],
160        SPIWPEN OFFSET(0) NUMBITS(1) []
161    ]
162];
163
164#[allow(unused_variables, dead_code)]
165// Per-register masks defined in the SPI manual in chapter 26.8
166mod spi_consts {
167    pub mod rdr {
168        pub const RD: u32 = 0xFFFF;
169    }
170
171    pub mod tdr {
172        pub const TD: u32 = 0xFFFF;
173        // PCSx masks from MR also apply here
174        // LASTXFER from CR also applies here
175    }
176}
177
178/// Values for selected peripherals
179#[derive(Copy, Clone)]
180pub enum Peripheral {
181    Peripheral0,
182    Peripheral1,
183    Peripheral2,
184    Peripheral3,
185}
186
187impl spi::cs::IntoChipSelect<Peripheral, spi::cs::ActiveLow> for Peripheral {
188    fn into_cs(self) -> Peripheral {
189        self
190    }
191}
192
193#[derive(Copy, Clone, PartialEq)]
194pub enum SpiRole {
195    SpiMaster,
196    SpiSlave,
197}
198
199/// Abstraction of the SPI Hardware
200pub struct SpiHw<'a> {
201    client: OptionalCell<&'a dyn SpiMasterClient>,
202    dma_read: OptionalCell<&'static DMAChannel>,
203    dma_write: OptionalCell<&'static DMAChannel>,
204    // keep track of which how many DMA transfers are pending to correctly
205    // issue completion event only after both complete.
206    transfers_in_progress: Cell<u8>,
207    dma_length: Cell<usize>,
208
209    // Slave client is distinct from master client
210    slave_client: OptionalCell<&'a dyn SpiSlaveClient>,
211    role: Cell<SpiRole>,
212    pm: &'a pm::PowerManager,
213}
214
215const SPI_BASE: StaticRef<SpiRegisters> =
216    unsafe { StaticRef::new(0x40008000 as *const SpiRegisters) };
217
218impl PeripheralManagement<pm::Clock> for SpiHw<'_> {
219    type RegisterType = SpiRegisters;
220
221    fn get_registers(&self) -> &SpiRegisters {
222        &SPI_BASE
223    }
224
225    fn get_clock(&self) -> &pm::Clock {
226        &pm::Clock::PBA(pm::PBAClock::SPI)
227    }
228
229    fn before_peripheral_access(&self, clock: &pm::Clock, _: &SpiRegisters) {
230        clock.enable();
231    }
232
233    fn after_peripheral_access(&self, clock: &pm::Clock, registers: &SpiRegisters) {
234        if !registers.sr.is_set(Status::SPIENS) {
235            clock.disable();
236        }
237    }
238}
239
240type SpiRegisterManager<'a, 'm> = PeripheralManager<'m, SpiHw<'a>, pm::Clock>;
241
242impl<'a> SpiHw<'a> {
243    /// Creates a new SPI object, with peripheral 0 selected
244    pub const fn new(pm: &'a pm::PowerManager) -> SpiHw<'a> {
245        SpiHw {
246            client: OptionalCell::empty(),
247            dma_read: OptionalCell::empty(),
248            dma_write: OptionalCell::empty(),
249            transfers_in_progress: Cell::new(0),
250            dma_length: Cell::new(0),
251
252            slave_client: OptionalCell::empty(),
253            role: Cell::new(SpiRole::SpiMaster),
254            pm,
255        }
256    }
257
258    fn init_as_role(&self, spi: &SpiRegisterManager<'a, '_>, role: SpiRole) {
259        self.role.set(role);
260
261        if role == SpiRole::SpiMaster {
262            // Only need to set LASTXFER if we are master
263            spi.registers.cr.write(Control::LASTXFER::SET);
264        }
265
266        // Sets bits per transfer to 8
267        let csr = self.get_active_csr(spi);
268        csr.modify(ChipSelectParams::BITS::Eight);
269
270        // Set mode to master or slave
271        let mode = match self.role.get() {
272            SpiRole::SpiMaster => Mode::MSTR::SET,
273            SpiRole::SpiSlave => Mode::MSTR::CLEAR,
274        };
275
276        // Disable mode fault detection (open drain outputs not supported)
277        spi.registers.mr.modify(mode + Mode::MODFDIS::SET);
278    }
279
280    fn enable(&self) {
281        let spi = &SpiRegisterManager::new(self);
282
283        spi.registers.cr.write(Control::SPIEN::SET);
284
285        if self.role.get() == SpiRole::SpiSlave {
286            spi.registers.ier.write(InterruptFlags::NSSR::SET); // Enable NSSR
287        }
288    }
289
290    fn disable(&self) {
291        let spi = &SpiRegisterManager::new(self);
292
293        // TODO(alevy): we actually probably want to do this asynchrounously but
294        // because we're using DMA, a transfer may have completed with a byte
295        // still in the TX buffer.
296        while !spi.registers.sr.is_set(Status::TXEMPTY) {}
297
298        self.dma_read.map(|read| read.disable());
299        self.dma_write.map(|write| write.disable());
300        spi.registers.cr.write(Control::SPIDIS::SET);
301
302        if self.role.get() == SpiRole::SpiSlave {
303            spi.registers.idr.write(InterruptFlags::NSSR::SET); // Disable NSSR
304        }
305    }
306
307    /// Sets the approximate baud rate for the active peripheral,
308    /// and return the actual baud rate set.
309    ///
310    /// Since the only supported baud rates are (system clock / n) where n
311    /// is an integer from 1 to 255, the exact baud rate may not
312    /// be available. In that case, the next lower baud rate will
313    /// be selected.
314    ///
315    /// The lowest available baud rate is 188235 baud. If the
316    /// requested rate is lower, 188235 baud will be selected.
317    pub fn set_baud_rate(&self, rate: u32) -> u32 {
318        // Main clock frequency
319        let mut real_rate = rate;
320        let clock = self.pm.get_system_frequency();
321
322        if real_rate < 188235 {
323            real_rate = 188235;
324        }
325        if real_rate > clock {
326            real_rate = clock;
327        }
328
329        // Divide and truncate, resulting in a n value that might be too low
330        let mut scbr = clock / real_rate;
331        // If the division was not exact, increase the n to get a slower baud
332        // rate, but only if we are not at the slowest rate. Since scbr is the
333        // clock rate divisor, the highest divisor 0xFF corresponds to the
334        // lowest rate.
335        if !clock.is_multiple_of(real_rate) && scbr != 0xFF {
336            scbr += 1;
337        }
338        let spi = &SpiRegisterManager::new(self);
339        let csr = self.get_active_csr(spi);
340        csr.modify(ChipSelectParams::SCBR.val(scbr));
341        clock / scbr
342    }
343
344    fn get_baud_rate(&self) -> u32 {
345        let spi = &SpiRegisterManager::new(self);
346        let clock = 48000000;
347        let scbr = self.get_active_csr(spi).read(ChipSelectParams::SCBR);
348        clock / scbr
349    }
350
351    fn set_polarity(&self, polarity: ClockPolarity) {
352        let spi = &SpiRegisterManager::new(self);
353        let csr = self.get_active_csr(spi);
354        match polarity {
355            ClockPolarity::IdleHigh => csr.modify(ChipSelectParams::CPOL::InactiveHigh),
356            ClockPolarity::IdleLow => csr.modify(ChipSelectParams::CPOL::InactiveLow),
357        }
358    }
359
360    fn get_polarity(&self) -> ClockPolarity {
361        let spi = &SpiRegisterManager::new(self);
362        let csr = self.get_active_csr(spi);
363        if csr.matches_all(ChipSelectParams::CPOL::InactiveLow) {
364            ClockPolarity::IdleLow
365        } else {
366            ClockPolarity::IdleHigh
367        }
368    }
369
370    fn set_phase(&self, phase: ClockPhase) {
371        let spi = &SpiRegisterManager::new(self);
372        let csr = self.get_active_csr(spi);
373        match phase {
374            ClockPhase::SampleLeading => csr.modify(ChipSelectParams::NCPHA::CaptureLeading),
375            ClockPhase::SampleTrailing => csr.modify(ChipSelectParams::NCPHA::CaptureTrailing),
376        }
377    }
378
379    fn get_phase(&self) -> ClockPhase {
380        let spi = &SpiRegisterManager::new(self);
381        let csr = self.get_active_csr(spi);
382        if csr.matches_all(ChipSelectParams::NCPHA::CaptureTrailing) {
383            ClockPhase::SampleTrailing
384        } else {
385            ClockPhase::SampleLeading
386        }
387    }
388
389    /// Returns the currently active peripheral
390    fn get_active_peripheral(&self, spi: &SpiRegisterManager<'a, '_>) -> Peripheral {
391        if self.role.get() == SpiRole::SpiMaster {
392            if spi.registers.mr.matches_all(Mode::PCS::PCS3) {
393                Peripheral::Peripheral3
394            } else if spi.registers.mr.matches_all(Mode::PCS::PCS2) {
395                Peripheral::Peripheral2
396            } else if spi.registers.mr.matches_all(Mode::PCS::PCS1) {
397                Peripheral::Peripheral1
398            } else {
399                // default
400                Peripheral::Peripheral0
401            }
402        } else {
403            // The active peripheral is always 0 in slave mode
404            Peripheral::Peripheral0
405        }
406    }
407
408    /// Returns the value of CSR0, CSR1, CSR2, or CSR3,
409    /// whichever corresponds to the active peripheral
410    fn get_active_csr<'s>(
411        &'s self,
412        spi: &SpiRegisterManager<'a, 's>,
413    ) -> &'s registers::ReadWrite<u32, ChipSelectParams::Register> {
414        match self.get_active_peripheral(spi) {
415            Peripheral::Peripheral0 => &spi.registers.csr[0],
416            Peripheral::Peripheral1 => &spi.registers.csr[1],
417            Peripheral::Peripheral2 => &spi.registers.csr[2],
418            Peripheral::Peripheral3 => &spi.registers.csr[3],
419        }
420    }
421
422    /// Set the DMA channels used for reading and writing.
423    pub fn set_dma(&self, read: &'static DMAChannel, write: &'static DMAChannel) {
424        self.dma_read.set(read);
425        self.dma_write.set(write);
426    }
427
428    pub fn handle_interrupt(&self) {
429        let spi = &SpiRegisterManager::new(self);
430
431        self.slave_client.map(|client| {
432            if spi.registers.sr.is_set(Status::NSSR) {
433                // NSSR
434                client.chip_selected()
435            }
436            // TODO: Do we want to support byte-level interrupts too?
437            // They currently conflict with DMA.
438        });
439    }
440
441    /// Asynchronous buffer read/write of SPI.
442    ///
443    /// Returns:
444    /// - `Ok(())` if operation starts (will receive callback through
445    ///   SpiMasterClient)
446    /// - `INVAL` if no buffers were passed in
447    // The write buffer has to be mutable because it's passed back to
448    // the caller, and the caller may want to be able write into it.
449    fn read_write_bytes(
450        &self,
451        write_buffer: Option<SubSliceMut<'static, u8>>,
452        read_buffer: Option<SubSliceMut<'static, u8>>,
453    ) -> Result<
454        (),
455        (
456            ErrorCode,
457            Option<SubSliceMut<'static, u8>>,
458            Option<SubSliceMut<'static, u8>>,
459        ),
460    > {
461        let count = match (&write_buffer, &read_buffer) {
462            (Some(ref wb), Some(ref rb)) => cmp::min(wb.len(), rb.len()),
463            (Some(ref wb), None) => wb.len(),
464            (None, Some(ref rb)) => rb.len(),
465            (None, None) => return Err((ErrorCode::INVAL, write_buffer, read_buffer)),
466        };
467
468        // Start by enabling the SPI driver.
469        self.enable();
470
471        // Configure DMA to transfer that many bytes.
472        self.dma_length.set(count);
473
474        // Reset the number of transfers in progress. This is incremented
475        // depending on the presence of the read/write below
476        self.transfers_in_progress.set(0);
477
478        // Only setup the RX channel if we were passed a read_buffer inside
479        // of the option. `map()` checks this for us.
480        // The read DMA transfer has to be set up before the write because
481        // otherwise when the CPU speed is not significantly faster than the
482        // SPI's baud rate, transfer_done does not capture the interrupt
483        // signaling the RX is done - may be due to missing the first read
484        // byte when you start read after write.
485        read_buffer.map(|rbuf| {
486            self.transfers_in_progress
487                .set(self.transfers_in_progress.get() + 1);
488            self.dma_read.map(move |read| {
489                read.enable();
490                read.do_transfer(DMAPeripheral::SPI_RX, rbuf.take(), count);
491            });
492        });
493
494        // The ordering of these operations matters.
495        // For transfers 4 bytes or longer, this will work as expected.
496        // For shorter transfers, the first byte will be missing.
497        write_buffer.map(|buf| {
498            self.transfers_in_progress
499                .set(self.transfers_in_progress.get() + 1);
500            self.dma_write.map(move |write| {
501                write.enable();
502                write.do_transfer(DMAPeripheral::SPI_TX, buf.take(), count);
503            });
504        });
505
506        Ok(())
507    }
508}
509
510impl<'a> spi::SpiMaster<'a> for SpiHw<'a> {
511    type ChipSelect = Peripheral;
512
513    fn set_client(&self, client: &'a dyn SpiMasterClient) {
514        self.client.set(client);
515    }
516
517    /// By default, initialize SPI to operate at 40KHz, clock is
518    /// idle on low, and sample on the leading edge.
519    fn init(&self) -> Result<(), ErrorCode> {
520        let spi = &SpiRegisterManager::new(self);
521        self.init_as_role(spi, SpiRole::SpiMaster);
522        Ok(())
523    }
524
525    fn is_busy(&self) -> bool {
526        self.transfers_in_progress.get() != 0
527    }
528
529    /// Asynchronous buffer read/write of SPI. `write_buffer` must be present;
530    /// `read_buffer` may be `None`. If read_buffer is present, then the length
531    /// of the read/write is the minimum of two buffer lengths.
532    ///
533    /// Returns:
534    /// - `Ok(())` if operation starts (will receive callback through
535    ///   SpiMasterClient)
536    /// - `BUSY` if the operation does not start
537    // The write buffer has to be mutable because it's passed back to
538    // the caller, and the caller may want to be able write into it.
539    fn read_write_bytes(
540        &self,
541        write_buffer: SubSliceMut<'static, u8>,
542        read_buffer: Option<SubSliceMut<'static, u8>>,
543    ) -> Result<
544        (),
545        (
546            ErrorCode,
547            SubSliceMut<'static, u8>,
548            Option<SubSliceMut<'static, u8>>,
549        ),
550    > {
551        // If busy, don't start.
552        if self.is_busy() {
553            return Err((ErrorCode::BUSY, write_buffer, read_buffer));
554        }
555
556        if let Err((err, write_buffer, read_buffer)) =
557            self.read_write_bytes(Some(write_buffer), read_buffer)
558        {
559            Err((
560                err,
561                write_buffer.unwrap_or((&mut [] as &mut [u8]).into()),
562                read_buffer,
563            ))
564        } else {
565            Ok(())
566        }
567    }
568
569    fn set_rate(&self, rate: u32) -> Result<u32, ErrorCode> {
570        Ok(self.set_baud_rate(rate))
571    }
572
573    fn get_rate(&self) -> u32 {
574        self.get_baud_rate()
575    }
576
577    fn set_polarity(&self, polarity: ClockPolarity) -> Result<(), ErrorCode> {
578        self.set_polarity(polarity);
579        Ok(())
580    }
581
582    fn get_polarity(&self) -> ClockPolarity {
583        self.get_polarity()
584    }
585
586    fn set_phase(&self, phase: ClockPhase) -> Result<(), ErrorCode> {
587        self.set_phase(phase);
588        Ok(())
589    }
590
591    fn get_phase(&self) -> ClockPhase {
592        self.get_phase()
593    }
594
595    fn hold_low(&self) {
596        let spi = &SpiRegisterManager::new(self);
597        let csr = self.get_active_csr(spi);
598        csr.modify(ChipSelectParams::CSAAT::ActiveAfterTransfer);
599    }
600
601    fn release_low(&self) {
602        let spi = &SpiRegisterManager::new(self);
603        let csr = self.get_active_csr(spi);
604        csr.modify(ChipSelectParams::CSAAT::InactiveAfterTransfer);
605    }
606
607    fn specify_chip_select(&self, cs: Self::ChipSelect) -> Result<(), ErrorCode> {
608        // Slave cannot set active peripheral
609        if self.role.get() == SpiRole::SpiMaster {
610            let spi = &SpiRegisterManager::new(self);
611            let mr = match cs {
612                Peripheral::Peripheral0 => Mode::PCS::PCS0,
613                Peripheral::Peripheral1 => Mode::PCS::PCS1,
614                Peripheral::Peripheral2 => Mode::PCS::PCS2,
615                Peripheral::Peripheral3 => Mode::PCS::PCS3,
616            };
617            spi.registers.mr.modify(mr);
618            Ok(())
619        } else {
620            Err(ErrorCode::INVAL)
621        }
622    }
623}
624
625impl<'a> spi::SpiSlave<'a> for SpiHw<'a> {
626    // Set to None to disable the whole thing
627    fn set_client(&self, client: Option<&'a dyn SpiSlaveClient>) {
628        self.slave_client.insert(client);
629    }
630
631    fn has_client(&self) -> bool {
632        self.slave_client.is_some()
633    }
634
635    fn init(&self) -> Result<(), ErrorCode> {
636        let spi = &SpiRegisterManager::new(self);
637        self.init_as_role(spi, SpiRole::SpiSlave);
638        Ok(())
639    }
640
641    /// This sets the value in the TDR register, to be sent as soon as the
642    /// chip select pin is low.
643    fn set_write_byte(&self, write_byte: u8) {
644        let spi = SpiRegisterManager::new(self);
645        spi.registers.tdr.set(write_byte as u32);
646    }
647
648    /// Setup buffers for a SPI transaction initiated by the master device.
649    ///
650    /// Returns:
651    /// - `Ok(())` if the operation starts. A callback will be generated.
652    /// - `INVAL` if neither the read or write buffer is provided.
653    fn read_write_bytes(
654        &self,
655        write_buffer: Option<&'static mut [u8]>,
656        read_buffer: Option<&'static mut [u8]>,
657        len: usize,
658    ) -> Result<
659        (),
660        (
661            ErrorCode,
662            Option<&'static mut [u8]>,
663            Option<&'static mut [u8]>,
664        ),
665    > {
666        let write_buffer = write_buffer.map(|b| {
667            let mut buf: SubSliceMut<u8> = b.into();
668            if buf.len() > len {
669                buf.slice(..len);
670            }
671            buf
672        });
673        let read_buffer = read_buffer.map(|b| {
674            let mut buf: SubSliceMut<u8> = b.into();
675            if buf.len() > len {
676                buf.slice(..len);
677            }
678            buf
679        });
680
681        if let Err((e, mwb, mrb)) = self.read_write_bytes(write_buffer, read_buffer) {
682            Err((e, mwb.map(|b| b.take()), mrb.map(|b| b.take())))
683        } else {
684            Ok(())
685        }
686    }
687
688    fn set_polarity(&self, polarity: ClockPolarity) -> Result<(), ErrorCode> {
689        self.set_polarity(polarity);
690        Ok(())
691    }
692
693    fn get_polarity(&self) -> ClockPolarity {
694        self.get_polarity()
695    }
696
697    fn set_phase(&self, phase: ClockPhase) -> Result<(), ErrorCode> {
698        self.set_phase(phase);
699        Ok(())
700    }
701
702    fn get_phase(&self) -> ClockPhase {
703        self.get_phase()
704    }
705}
706
707impl DMAClient for SpiHw<'_> {
708    fn transfer_done(&self, _pid: DMAPeripheral) {
709        // Only callback that the transfer is done if either:
710        // 1) The transfer was TX only and TX finished
711        // 2) The transfer was TX and RX, in that case wait for both of them to complete. Although
712        //    both transactions happen simultaneously over the wire, the DMA may not finish copying
713        //    data over to/from the controller at the same time, so we don't want to abort
714        //    prematurely.
715
716        self.transfers_in_progress
717            .set(self.transfers_in_progress.get() - 1);
718
719        if self.transfers_in_progress.get() == 0 {
720            let txbuf = self.dma_write.map_or(None, |dma| {
721                let buf = dma.abort_transfer();
722                dma.disable();
723                buf
724            });
725
726            let rxbuf = self.dma_read.map_or(None, |dma| {
727                let buf = dma.abort_transfer();
728                dma.disable();
729                buf
730            });
731
732            let len = self.dma_length.get();
733            self.dma_length.set(0);
734
735            match self.role.get() {
736                SpiRole::SpiMaster => {
737                    self.client.map(|cb| {
738                        txbuf.map(|txbuf| {
739                            cb.read_write_done(txbuf.into(), rxbuf.map(|b| b.into()), Ok(len));
740                        });
741                    });
742                }
743                SpiRole::SpiSlave => {
744                    self.slave_client.map(|cb| {
745                        cb.read_write_done(txbuf, rxbuf, len, Ok(()));
746                    });
747                }
748            }
749            if self.transfers_in_progress.get() == 0 {
750                self.disable();
751            }
752        }
753    }
754}