Skip to main content

embedded_sdmmc/sdcard/
spi.rs

1//! # SD card access via SPI
2//!
3//! Implements the BlockDevice trait for an SD/MMC Protocol over SPI.
4use core::cell::RefCell;
5
6use crate::{Block, BlockCount, BlockDevice, BlockIdx};
7use embedded_sdmmc_types::sdcard::*;
8
9// ****************************************************************************
10// Types and Implementations
11// ****************************************************************************
12
13/// Driver for an SD Card on an SPI bus.
14///
15/// Built from an [`SpiDevice`] implementation and a Chip Select pin.
16///
17/// Before talking to the SD Card, the caller needs to send 74 clocks cycles on
18/// the SPI Clock line, at 400 kHz, with no chip-select asserted (or at least,
19/// not the chip-select of the SD Card).
20///
21/// This kind of breaks the embedded-hal model, so how to do this is left to
22/// the caller. You could drive the SpiBus directly, or use an SpiDevice with
23/// a dummy chip-select pin. Or you could try just not doing the 74 clocks and
24/// see if your card works anyway - some do, some don't.
25///
26/// All the APIs take `&self` - mutability is handled using an inner `RefCell`.
27///
28/// [`SpiDevice`]: embedded_hal::spi::SpiDevice
29pub struct SdCard<SPI, DELAYER>
30where
31    SPI: embedded_hal::spi::SpiDevice<u8>,
32    DELAYER: embedded_hal::delay::DelayNs,
33{
34    inner: RefCell<SdCardInner<SPI, DELAYER>>,
35}
36
37impl<SPI, DELAYER> SdCard<SPI, DELAYER>
38where
39    SPI: embedded_hal::spi::SpiDevice<u8>,
40    DELAYER: embedded_hal::delay::DelayNs,
41{
42    /// Create a new SD/MMC Card driver using a raw SPI interface.
43    ///
44    /// The card will not be initialised at this time. Initialisation is
45    /// deferred until a method is called on the object.
46    ///
47    /// Uses the default options.
48    pub fn new(spi: SPI, delayer: DELAYER) -> Self {
49        Self::new_with_options(spi, delayer, AcquireOpts::default())
50    }
51
52    /// Construct a new SD/MMC Card driver, using a raw SPI interface and the given options.
53    ///
54    /// See the docs of the [`SdCard`] struct for more information about
55    /// how to construct the needed `SPI` and `CS` types.
56    ///
57    /// The card will not be initialised at this time. Initialisation is
58    /// deferred until a method is called on the object.
59    pub fn new_with_options(spi: SPI, delayer: DELAYER, options: AcquireOpts) -> Self {
60        SdCard {
61            inner: RefCell::new(SdCardInner {
62                spi,
63                delayer,
64                card_type: None,
65                options,
66            }),
67        }
68    }
69
70    /// Get a temporary borrow on the underlying SPI device.
71    ///
72    /// The given closure will be called exactly once, and will be passed a
73    /// mutable reference to the underlying SPI object.
74    ///
75    /// Useful if you need to re-clock the SPI, but does not perform card
76    /// initialisation.
77    pub fn spi<T, F>(&self, func: F) -> T
78    where
79        F: FnOnce(&mut SPI) -> T,
80    {
81        let mut inner = self.inner.borrow_mut();
82        func(&mut inner.spi)
83    }
84
85    /// Return the usable size of this SD card in bytes.
86    ///
87    /// This will trigger card (re-)initialisation.
88    pub fn num_bytes(&self) -> Result<u64, Error> {
89        let mut inner = self.inner.borrow_mut();
90        inner.check_init()?;
91        inner.num_bytes()
92    }
93
94    /// Can this card erase single blocks?
95    ///
96    /// This will trigger card (re-)initialisation.
97    pub fn erase_single_block_enabled(&self) -> Result<bool, Error> {
98        let mut inner = self.inner.borrow_mut();
99        inner.check_init()?;
100        inner.erase_single_block_enabled()
101    }
102
103    /// Mark the card as requiring a reset.
104    ///
105    /// The next operation will assume the card has been freshly inserted.
106    pub fn mark_card_uninit(&self) {
107        let mut inner = self.inner.borrow_mut();
108        inner.card_type = None;
109    }
110
111    /// Get the card type.
112    ///
113    /// This will trigger card (re-)initialisation.
114    pub fn get_card_type(&self) -> Option<CardType> {
115        let mut inner = self.inner.borrow_mut();
116        inner.check_init().ok()?;
117        inner.card_type
118    }
119
120    /// Tell the driver the card has been initialised.
121    ///
122    /// This is here in case you were previously using the SD Card, and then a
123    /// previous instance of this object got destroyed but you know for certain
124    /// the SD Card remained powered up and initialised, and you'd just like to
125    /// read/write to/from the card again without going through the
126    /// initialisation sequence again.
127    ///
128    /// # Safety
129    ///
130    /// Only do this if the SD Card has actually been initialised. That is, if
131    /// you have been through the card initialisation sequence as specified in
132    /// the SD Card Specification by sending each appropriate command in turn,
133    /// either manually or using another variable of this [`SdCard`]. The card
134    /// must also be of the indicated type. Failure to uphold this will cause
135    /// data corruption.
136    pub unsafe fn mark_card_as_init(&self, card_type: CardType) {
137        let mut inner = self.inner.borrow_mut();
138        inner.card_type = Some(card_type);
139    }
140}
141
142impl<SPI, DELAYER> BlockDevice for SdCard<SPI, DELAYER>
143where
144    SPI: embedded_hal::spi::SpiDevice<u8>,
145    DELAYER: embedded_hal::delay::DelayNs,
146{
147    type Error = Error;
148
149    /// Read one or more blocks, starting at the given block index.
150    ///
151    /// This will trigger card (re-)initialisation.
152    fn read(&self, blocks: &mut [Block], start_block_idx: BlockIdx) -> Result<(), Self::Error> {
153        let mut inner = self.inner.borrow_mut();
154        crate::debug!("Read {} blocks @ {}", blocks.len(), start_block_idx.0,);
155        inner.check_init()?;
156        inner.read(blocks, start_block_idx)
157    }
158
159    /// Write one or more blocks, starting at the given block index.
160    ///
161    /// This will trigger card (re-)initialisation.
162    fn write(&self, blocks: &[Block], start_block_idx: BlockIdx) -> Result<(), Self::Error> {
163        let mut inner = self.inner.borrow_mut();
164        crate::debug!("Writing {} blocks @ {}", blocks.len(), start_block_idx.0);
165        inner.check_init()?;
166        inner.write(blocks, start_block_idx)
167    }
168
169    /// Determine how many blocks this device can hold.
170    ///
171    /// This will trigger card (re-)initialisation.
172    fn num_blocks(&self) -> Result<BlockCount, Self::Error> {
173        let mut inner = self.inner.borrow_mut();
174        inner.check_init()?;
175        inner.num_blocks()
176    }
177}
178
179/// Inner details for the SD Card driver.
180///
181/// All the APIs required `&mut self`.
182struct SdCardInner<SPI, DELAYER>
183where
184    SPI: embedded_hal::spi::SpiDevice<u8>,
185    DELAYER: embedded_hal::delay::DelayNs,
186{
187    spi: SPI,
188    delayer: DELAYER,
189    card_type: Option<CardType>,
190    options: AcquireOpts,
191}
192
193impl<SPI, DELAYER> SdCardInner<SPI, DELAYER>
194where
195    SPI: embedded_hal::spi::SpiDevice<u8>,
196    DELAYER: embedded_hal::delay::DelayNs,
197{
198    /// Read one or more blocks, starting at the given block index.
199    fn read(&mut self, blocks: &mut [Block], start_block_idx: BlockIdx) -> Result<(), Error> {
200        let start_idx = match self.card_type {
201            Some(CardType::SD1 | CardType::SD2) => start_block_idx.0 * 512,
202            Some(CardType::SdhcSdxc) => start_block_idx.0,
203            None => return Err(Error::CardNotFound),
204        };
205
206        if blocks.len() == 1 {
207            // Start a single-block read
208            self.card_command(CmdId::CMD17_ReadSingleBlock, start_idx)?;
209            self.read_data(&mut blocks[0].contents)?;
210        } else {
211            // Start a multi-block read
212            self.card_command(CmdId::CMD18_ReadMultipleBlock, start_idx)?;
213            for block in blocks.iter_mut() {
214                self.read_data(&mut block.contents)?;
215            }
216            // Stop the read
217            self.card_command(CmdId::CMD12_StopTransmission, 0)?;
218        }
219        Ok(())
220    }
221
222    /// Write one or more blocks, starting at the given block index.
223    fn write(&mut self, blocks: &[Block], start_block_idx: BlockIdx) -> Result<(), Error> {
224        let start_idx = match self.card_type {
225            Some(CardType::SD1 | CardType::SD2) => start_block_idx.0 * 512,
226            Some(CardType::SdhcSdxc) => start_block_idx.0,
227            None => return Err(Error::CardNotFound),
228        };
229        if blocks.len() == 1 {
230            // Start a single-block write
231            self.card_command(CmdId::CMD24_WriteBlock, start_idx)?;
232            self.write_data(DATA_START_BLOCK, &blocks[0].contents)?;
233            self.wait_not_busy(Delay::new_write())?;
234            if self.card_command(CmdId::CMD13_SendStatus, 0)? != 0x00 {
235                return Err(Error::WriteError);
236            }
237            if self.read_byte()? != 0x00 {
238                return Err(Error::WriteError);
239            }
240        } else {
241            // > It is recommended using this command preceding CMD25, some of the cards will be faster for Multiple
242            // > Write Blocks operation. Note that the host should send ACMD23 just before WRITE command if the host
243            // > wants to use the pre-erased feature
244            self.card_acmd(AcmdId::ACMD23_PreErase, blocks.len() as u32)?;
245            // wait for card to be ready before sending the next command
246            self.wait_not_busy(Delay::new_write())?;
247
248            // Start a multi-block write
249            self.card_command(CmdId::CMD25_WriteMultipleBlock, start_idx)?;
250            for block in blocks.iter() {
251                self.wait_not_busy(Delay::new_write())?;
252                self.write_data(WRITE_MULTIPLE_TOKEN, &block.contents)?;
253            }
254            // Stop the write
255            self.wait_not_busy(Delay::new_write())?;
256            self.write_byte(STOP_TRAN_TOKEN)?;
257        }
258        Ok(())
259    }
260
261    /// Determine how many blocks this device can hold.
262    fn num_blocks(&mut self) -> Result<BlockCount, Error> {
263        let csd = self.read_csd()?;
264        crate::debug!("CSD: {:?}", csd);
265        Ok(BlockCount(csd.card_capacity_blocks()))
266    }
267
268    /// Return the usable size of this SD card in bytes.
269    fn num_bytes(&mut self) -> Result<u64, Error> {
270        let csd = self.read_csd()?;
271        crate::debug!("CSD: {:?}", csd);
272        Ok(csd.card_capacity_bytes())
273    }
274
275    /// Can this card erase single blocks?
276    pub fn erase_single_block_enabled(&mut self) -> Result<bool, Error> {
277        let csd = self.read_csd()?;
278        Ok(csd.erase_single_block_enabled())
279    }
280
281    /// Read the 'card specific data' block.
282    fn read_csd(&mut self) -> Result<csd::Csd, Error> {
283        if self.card_type.is_none() {
284            return Err(Error::CardNotFound);
285        }
286
287        if self.card_command(CmdId::CMD9_SendCsd, 0)? != 0 {
288            return Err(Error::RegisterReadError);
289        }
290        let mut csd_raw: [u8; 16] = [0; 16];
291        self.read_data(&mut csd_raw)?;
292
293        // Select the CSD layout from the CSD_STRUCTURE field (bits 127:126);
294        // note that it is independent from the Physical Layer v2.00+ (`card_type`).
295        csd::Csd::new(&csd_raw).map_err(|_| Error::RegisterReadError)
296    }
297
298    /// Read an arbitrary number of bytes from the card using the SD Card
299    /// protocol and an optional CRC. Always fills the given buffer, so make
300    /// sure it's the right size.
301    fn read_data(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
302        // Get first non-FF byte.
303        let mut delay = Delay::new_read();
304        let status = loop {
305            let s = self.read_byte()?;
306            if s != 0xFF {
307                break s;
308            }
309            delay.delay(&mut self.delayer, Error::TimeoutReadBuffer)?;
310        };
311        if status != DATA_START_BLOCK {
312            return Err(Error::ReadError);
313        }
314
315        buffer.fill(0xFF);
316        self.transfer_bytes(buffer)?;
317
318        // These two bytes are always sent. They are either a valid CRC, or
319        // junk, depending on whether CRC mode was enabled.
320        let mut crc_bytes = [0xFF; 2];
321        self.transfer_bytes(&mut crc_bytes)?;
322        if self.options.use_crc {
323            let crc = u16::from_be_bytes(crc_bytes);
324            let calc_crc = crc16(buffer);
325            if crc != calc_crc {
326                return Err(Error::CrcError(crc, calc_crc));
327            }
328        }
329
330        Ok(())
331    }
332
333    /// Write an arbitrary number of bytes to the card using the SD protocol and
334    /// an optional CRC.
335    fn write_data(&mut self, token: u8, buffer: &[u8]) -> Result<(), Error> {
336        self.write_byte(token)?;
337        self.write_bytes(buffer)?;
338        let crc_bytes = if self.options.use_crc {
339            crc16(buffer).to_be_bytes()
340        } else {
341            [0xFF, 0xFF]
342        };
343        // These two bytes are always sent. They are either a valid CRC, or
344        // junk, depending on whether CRC mode was enabled.
345        self.write_bytes(&crc_bytes)?;
346
347        let status = self.read_byte()?;
348        if (status & DATA_RES_MASK) != DATA_RES_ACCEPTED {
349            Err(Error::WriteError)
350        } else {
351            Ok(())
352        }
353    }
354
355    /// Check the card is initialised.
356    fn check_init(&mut self) -> Result<(), Error> {
357        if self.card_type.is_none() {
358            // If we don't know what the card type is, try and initialise the
359            // card. This will tell us what type of card it is.
360            self.acquire()
361        } else {
362            Ok(())
363        }
364    }
365
366    /// Initializes the card into a known state (or at least tries to).
367    fn acquire(&mut self) -> Result<(), Error> {
368        crate::debug!("acquiring card with opts: {:?}", self.options);
369        let f = |s: &mut Self| {
370            // Assume it hasn't worked
371            let mut card_type;
372            crate::trace!("Reset card..");
373            // Enter SPI mode.
374            let mut delay = Delay::new(s.options.acquire_retries);
375            for _attempts in 1.. {
376                crate::trace!("Enter SPI mode, attempt: {}..", _attempts);
377                match s.card_command(CmdId::CMD0_GoIdleState, 0) {
378                    Err(Error::TimeoutCommand(CmdId::CMD0_GoIdleState)) => {
379                        // Try again?
380                        crate::warn!("Timed out, trying again..");
381                        // Try flushing the card as done here: https://github.com/greiman/SdFat/blob/master/src/SdCard/SdSpiCard.cpp#L170,
382                        // https://github.com/rust-embedded-community/embedded-sdmmc-rs/pull/65#issuecomment-1270709448
383                        for _ in 0..0xFF {
384                            s.write_byte(0xFF)?;
385                        }
386                    }
387                    Err(e) => {
388                        return Err(e);
389                    }
390                    Ok(R1_IDLE_STATE) => {
391                        break;
392                    }
393                    Ok(_r) => {
394                        // Try again
395                        crate::trace!("Got response: {:x}, trying again..", _r);
396                    }
397                }
398
399                delay.delay(&mut s.delayer, Error::CardNotFound)?;
400            }
401            // Enable CRC
402            crate::debug!("Enable CRC: {}", s.options.use_crc);
403            // "The SPI interface is initialized in the CRC OFF mode in default"
404            // -- SD Part 1 Physical Layer Specification v9.00, Section 7.2.2 Bus Transfer Protection
405            if s.options.use_crc && s.card_command(CmdId::CMD59_CrcOnOff, 1)? != R1_IDLE_STATE {
406                return Err(Error::CantEnableCRC);
407            }
408            // Check card version
409            let mut delay = Delay::new_command();
410            let arg = loop {
411                if s.card_command(CmdId::CMD8_SendIfCond, 0x1AA)?
412                    == (R1_ILLEGAL_COMMAND | R1_IDLE_STATE)
413                {
414                    card_type = CardType::SD1;
415                    break 0;
416                }
417                let mut buffer = [0xFF; 4];
418                s.transfer_bytes(&mut buffer)?;
419                let status = buffer[3];
420                if status == 0xAA {
421                    card_type = CardType::SD2;
422                    break 0x4000_0000;
423                }
424                delay.delay(
425                    &mut s.delayer,
426                    Error::TimeoutCommand(CmdId::CMD8_SendIfCond),
427                )?;
428            };
429
430            let mut delay = Delay::new_command();
431            while s.card_acmd(AcmdId::ACMD41_SdSendOpCond, arg)? != R1_READY_STATE {
432                delay.delay(
433                    &mut s.delayer,
434                    Error::TimeoutACommand(AcmdId::ACMD41_SdSendOpCond),
435                )?;
436            }
437
438            if card_type == CardType::SD2 {
439                if s.card_command(CmdId::CMD58_ReadOcr, 0)? != 0 {
440                    return Err(Error::Cmd58Error);
441                }
442                let mut buffer = [0xFF; 4];
443                s.transfer_bytes(&mut buffer)?;
444                if (buffer[0] & 0xC0) == 0xC0 {
445                    card_type = CardType::SdhcSdxc;
446                }
447                // Ignore the other three bytes
448            }
449            crate::debug!("Card version: {:?}", card_type);
450            s.card_type = Some(card_type);
451            Ok(())
452        };
453        let result = f(self);
454        let _ = self.read_byte();
455        result
456    }
457
458    /// Perform an application-specific command.
459    fn card_acmd(&mut self, command: AcmdId, arg: u32) -> Result<u8, Error> {
460        self.card_command(CmdId::CMD55_AppCmd, 0)?;
461        self.card_acmd_after_escape(command, arg)
462    }
463
464    fn card_acmd_after_escape(&mut self, command: AcmdId, arg: u32) -> Result<u8, Error> {
465        // Wait for the required idle gap (Ncc) after the CMD55 escape response
466        // before clocking out the application command.
467        self.wait_not_busy(Delay::new_command())?;
468        let mut buf = [
469            0x40 | command as u8,
470            (arg >> 24) as u8,
471            (arg >> 16) as u8,
472            (arg >> 8) as u8,
473            arg as u8,
474            0,
475        ];
476        buf[5] = (crc7(&buf[0..5]) << 1) | 1;
477
478        self.write_bytes(&buf)?;
479
480        let mut delay = Delay::new_command();
481        loop {
482            let result = self.read_byte()?;
483            if (result & 0x80) == ERROR_OK {
484                return Ok(result);
485            }
486            delay.delay(&mut self.delayer, Error::TimeoutACommand(command))?;
487        }
488    }
489
490    /// Perform a command.
491    fn card_command(&mut self, command: CmdId, arg: u32) -> Result<u8, Error> {
492        if command != CmdId::CMD0_GoIdleState && command != CmdId::CMD12_StopTransmission {
493            self.wait_not_busy(Delay::new_command())?;
494        }
495
496        let mut buf = [
497            0x40 | command as u8,
498            (arg >> 24) as u8,
499            (arg >> 16) as u8,
500            (arg >> 8) as u8,
501            arg as u8,
502            0,
503        ];
504        buf[5] = (crc7(&buf[0..5]) << 1) | 1;
505
506        self.write_bytes(&buf)?;
507
508        // skip stuff byte for stop read
509        if command == CmdId::CMD12_StopTransmission {
510            let _result = self.read_byte()?;
511        }
512
513        let mut delay = Delay::new_command();
514        loop {
515            let result = self.read_byte()?;
516            if (result & 0x80) == ERROR_OK {
517                return Ok(result);
518            }
519            delay.delay(&mut self.delayer, Error::TimeoutCommand(command))?;
520        }
521    }
522
523    /// Receive a byte from the SPI bus by clocking out an 0xFF byte.
524    fn read_byte(&mut self) -> Result<u8, Error> {
525        self.transfer_byte(0xFF)
526    }
527
528    /// Send a byte over the SPI bus and ignore what comes back.
529    fn write_byte(&mut self, out: u8) -> Result<(), Error> {
530        let _ = self.transfer_byte(out)?;
531        Ok(())
532    }
533
534    /// Send one byte and receive one byte over the SPI bus.
535    fn transfer_byte(&mut self, out: u8) -> Result<u8, Error> {
536        let mut read_buf = [0u8; 1];
537        self.spi
538            .transfer(&mut read_buf, &[out])
539            .map_err(|_| Error::Transport)?;
540        Ok(read_buf[0])
541    }
542
543    /// Send multiple bytes and ignore what comes back over the SPI bus.
544    fn write_bytes(&mut self, out: &[u8]) -> Result<(), Error> {
545        self.spi.write(out).map_err(|_e| Error::Transport)?;
546        Ok(())
547    }
548
549    /// Send multiple bytes and replace them with what comes back over the SPI bus.
550    fn transfer_bytes(&mut self, in_out: &mut [u8]) -> Result<(), Error> {
551        self.spi
552            .transfer_in_place(in_out)
553            .map_err(|_e| Error::Transport)?;
554        Ok(())
555    }
556
557    /// Spin until the card returns 0xFF, or we spin too many times and
558    /// timeout.
559    fn wait_not_busy(&mut self, mut delay: Delay) -> Result<(), Error> {
560        loop {
561            let s = self.read_byte()?;
562            if s == 0xFF {
563                break;
564            }
565            delay.delay(&mut self.delayer, Error::TimeoutWaitNotBusy)?;
566        }
567        Ok(())
568    }
569}
570
571/// Options for acquiring the card.
572#[cfg_attr(feature = "defmt-log", derive(defmt::Format))]
573#[derive(Debug)]
574pub struct AcquireOpts {
575    /// Set to true to enable CRC checking on reading/writing blocks of data.
576    ///
577    /// Set to false to disable the CRC. Some cards don't support CRC correctly
578    /// and this option may be useful in that instance.
579    ///
580    /// On by default because without it you might get silent data corruption on
581    /// your card.
582    pub use_crc: bool,
583
584    /// Sets the number of times we will retry to acquire the card before giving up and returning
585    /// `Err(Error::CardNotFound)`. By default, card acquisition will be retried 50 times.
586    pub acquire_retries: u32,
587}
588
589impl Default for AcquireOpts {
590    fn default() -> Self {
591        AcquireOpts {
592            use_crc: true,
593            acquire_retries: 50,
594        }
595    }
596}
597
598/// The possible errors this crate can generate.
599#[cfg_attr(feature = "defmt-log", derive(defmt::Format))]
600#[derive(Debug, Copy, Clone)]
601pub enum Error {
602    /// We got an error from the SPI peripheral
603    Transport,
604    /// We failed to enable CRC checking on the SD card
605    CantEnableCRC,
606    /// We didn't get a response when reading data from the card
607    TimeoutReadBuffer,
608    /// We didn't get a response when waiting for the card to not be busy
609    TimeoutWaitNotBusy,
610    /// We didn't get a response when executing this command
611    TimeoutCommand(CmdId),
612    /// We didn't get a response when executing this application-specific command
613    TimeoutACommand(AcmdId),
614    /// We got a bad response from Command 58
615    Cmd58Error,
616    /// We failed to read the Card Specific Data register
617    RegisterReadError,
618    /// We got a CRC mismatch (card gave us, we calculated)
619    CrcError(u16, u16),
620    /// Error reading from the card
621    ReadError,
622    /// Error writing to the card
623    WriteError,
624    /// Can't perform this operation with the card in this state
625    BadState,
626    /// Couldn't find the card
627    CardNotFound,
628    /// Couldn't set a GPIO pin
629    GpioError,
630}
631
632impl core::fmt::Display for Error {
633    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
634        match self {
635            Error::Transport => write!(f, "error from SPI peripheral"),
636            Error::CantEnableCRC => write!(f, "failed to enable CRC checking"),
637            Error::TimeoutReadBuffer => write!(f, "timeout when reading data"),
638            Error::TimeoutWaitNotBusy => write!(f, "timeout when waiting for card to not be busy"),
639            Error::TimeoutCommand(command) => {
640                write!(f, "timeout when executing command {command:?}")
641            }
642            Error::TimeoutACommand(command) => write!(
643                f,
644                "timeout when executing application-specific command {command:?}"
645            ),
646            Error::Cmd58Error => write!(f, "bad response from command 58"),
647            Error::RegisterReadError => write!(f, "failed to read Card Specific Data register"),
648            Error::CrcError(_, _) => write!(f, "CRC mismatch"),
649            Error::ReadError => write!(f, "read error"),
650            Error::WriteError => write!(f, "write error"),
651            Error::BadState => write!(f, "cannot perform operation with card in thiis state"),
652            Error::CardNotFound => write!(f, "card not found"),
653            Error::GpioError => write!(f, "cannot set GPIO pin"),
654        }
655    }
656}
657
658impl core::error::Error for Error {}
659
660/// This an object you can use to busy-wait with a timeout.
661///
662/// Will let you call `delay` up to `max_retries` times before `delay` returns
663/// an error.
664struct Delay {
665    retries_left: u32,
666}
667
668impl Delay {
669    /// The default number of retries for a read operation.
670    ///
671    /// At ~10us each this is ~100ms.
672    ///
673    /// See `Part1_Physical_Layer_Simplified_Specification_Ver9.00-1.pdf` Section 4.6.2.1
674    pub const DEFAULT_READ_RETRIES: u32 = 10_000;
675
676    /// The default number of retries for a write operation.
677    ///
678    /// At ~10us each this is ~500ms.
679    ///
680    /// See `Part1_Physical_Layer_Simplified_Specification_Ver9.00-1.pdf` Section 4.6.2.2
681    pub const DEFAULT_WRITE_RETRIES: u32 = 50_000;
682
683    /// The default number of retries for a control command.
684    ///
685    /// At ~10us each this is ~100ms.
686    ///
687    /// No value is given in the specification, so we pick the same as the read timeout.
688    pub const DEFAULT_COMMAND_RETRIES: u32 = 10_000;
689
690    /// Create a new Delay object with the given maximum number of retries.
691    fn new(max_retries: u32) -> Delay {
692        Delay {
693            retries_left: max_retries,
694        }
695    }
696
697    /// Create a new Delay object with the maximum number of retries for a read operation.
698    fn new_read() -> Delay {
699        Delay::new(Self::DEFAULT_READ_RETRIES)
700    }
701
702    /// Create a new Delay object with the maximum number of retries for a write operation.
703    fn new_write() -> Delay {
704        Delay::new(Self::DEFAULT_WRITE_RETRIES)
705    }
706
707    /// Create a new Delay object with the maximum number of retries for a command operation.
708    fn new_command() -> Delay {
709        Delay::new(Self::DEFAULT_COMMAND_RETRIES)
710    }
711
712    /// Wait for a while.
713    ///
714    /// Checks the retry counter first, and if we hit the max retry limit, the
715    /// value `err` is returned. Otherwise we wait for 10us and then return
716    /// `Ok(())`.
717    fn delay<T>(&mut self, delayer: &mut T, err: Error) -> Result<(), Error>
718    where
719        T: embedded_hal::delay::DelayNs,
720    {
721        if self.retries_left == 0 {
722            Err(err)
723        } else {
724            delayer.delay_us(10);
725            self.retries_left -= 1;
726            Ok(())
727        }
728    }
729}
730
731// ****************************************************************************
732//
733// End Of File
734//
735// ****************************************************************************