embedded_sdmmc/sdcard/
mod.rs

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