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// ****************************************************************************