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(&self, blocks: &mut [Block], start_block_idx: BlockIdx) -> Result<(), Self::Error> {
166 let mut inner = self.inner.borrow_mut();
167 debug!("Read {} blocks @ {}", blocks.len(), start_block_idx.0,);
168 inner.check_init()?;
169 inner.read(blocks, start_block_idx)
170 }
171
172 /// Write one or more blocks, starting at the given block index.
173 ///
174 /// This will trigger card (re-)initialisation.
175 fn write(&self, blocks: &[Block], start_block_idx: BlockIdx) -> Result<(), Self::Error> {
176 let mut inner = self.inner.borrow_mut();
177 debug!("Writing {} blocks @ {}", blocks.len(), start_block_idx.0);
178 inner.check_init()?;
179 inner.write(blocks, start_block_idx)
180 }
181
182 /// Determine how many blocks this device can hold.
183 ///
184 /// This will trigger card (re-)initialisation.
185 fn num_blocks(&self) -> Result<BlockCount, Self::Error> {
186 let mut inner = self.inner.borrow_mut();
187 inner.check_init()?;
188 inner.num_blocks()
189 }
190}
191
192/// Inner details for the SD Card driver.
193///
194/// All the APIs required `&mut self`.
195struct SdCardInner<SPI, DELAYER>
196where
197 SPI: embedded_hal::spi::SpiDevice<u8>,
198 DELAYER: embedded_hal::delay::DelayNs,
199{
200 spi: SPI,
201 delayer: DELAYER,
202 card_type: Option<CardType>,
203 options: AcquireOpts,
204}
205
206impl<SPI, DELAYER> SdCardInner<SPI, DELAYER>
207where
208 SPI: embedded_hal::spi::SpiDevice<u8>,
209 DELAYER: embedded_hal::delay::DelayNs,
210{
211 /// Read one or more blocks, starting at the given block index.
212 fn read(&mut self, blocks: &mut [Block], start_block_idx: BlockIdx) -> Result<(), Error> {
213 let start_idx = match self.card_type {
214 Some(CardType::SD1 | CardType::SD2) => start_block_idx.0 * 512,
215 Some(CardType::SDHC) => start_block_idx.0,
216 None => return Err(Error::CardNotFound),
217 };
218
219 if blocks.len() == 1 {
220 // Start a single-block read
221 self.card_command(CMD17, start_idx)?;
222 self.read_data(&mut blocks[0].contents)?;
223 } else {
224 // Start a multi-block read
225 self.card_command(CMD18, start_idx)?;
226 for block in blocks.iter_mut() {
227 self.read_data(&mut block.contents)?;
228 }
229 // Stop the read
230 self.card_command(CMD12, 0)?;
231 }
232 Ok(())
233 }
234
235 /// Write one or more blocks, starting at the given block index.
236 fn write(&mut self, blocks: &[Block], start_block_idx: BlockIdx) -> Result<(), Error> {
237 let start_idx = match self.card_type {
238 Some(CardType::SD1 | CardType::SD2) => start_block_idx.0 * 512,
239 Some(CardType::SDHC) => start_block_idx.0,
240 None => return Err(Error::CardNotFound),
241 };
242 if blocks.len() == 1 {
243 // Start a single-block write
244 self.card_command(CMD24, start_idx)?;
245 self.write_data(DATA_START_BLOCK, &blocks[0].contents)?;
246 self.wait_not_busy(Delay::new_write())?;
247 if self.card_command(CMD13, 0)? != 0x00 {
248 return Err(Error::WriteError);
249 }
250 if self.read_byte()? != 0x00 {
251 return Err(Error::WriteError);
252 }
253 } else {
254 // > It is recommended using this command preceding CMD25, some of the cards will be faster for Multiple
255 // > Write Blocks operation. Note that the host should send ACMD23 just before WRITE command if the host
256 // > wants to use the pre-erased feature
257 self.card_acmd(ACMD23, blocks.len() as u32)?;
258 // wait for card to be ready before sending the next command
259 self.wait_not_busy(Delay::new_write())?;
260
261 // Start a multi-block write
262 self.card_command(CMD25, start_idx)?;
263 for block in blocks.iter() {
264 self.wait_not_busy(Delay::new_write())?;
265 self.write_data(WRITE_MULTIPLE_TOKEN, &block.contents)?;
266 }
267 // Stop the write
268 self.wait_not_busy(Delay::new_write())?;
269 self.write_byte(STOP_TRAN_TOKEN)?;
270 }
271 Ok(())
272 }
273
274 /// Determine how many blocks this device can hold.
275 fn num_blocks(&mut self) -> Result<BlockCount, Error> {
276 let csd = self.read_csd()?;
277 debug!("CSD: {:?}", csd);
278 let num_blocks = match csd {
279 Csd::V1(ref contents) => contents.card_capacity_blocks(),
280 Csd::V2(ref contents) => contents.card_capacity_blocks(),
281 };
282 Ok(BlockCount(num_blocks))
283 }
284
285 /// Return the usable size of this SD card in bytes.
286 fn num_bytes(&mut self) -> Result<u64, Error> {
287 let csd = self.read_csd()?;
288 debug!("CSD: {:?}", csd);
289 match csd {
290 Csd::V1(ref contents) => Ok(contents.card_capacity_bytes()),
291 Csd::V2(ref contents) => Ok(contents.card_capacity_bytes()),
292 }
293 }
294
295 /// Can this card erase single blocks?
296 pub fn erase_single_block_enabled(&mut self) -> Result<bool, Error> {
297 let csd = self.read_csd()?;
298 match csd {
299 Csd::V1(ref contents) => Ok(contents.erase_single_block_enabled()),
300 Csd::V2(ref contents) => Ok(contents.erase_single_block_enabled()),
301 }
302 }
303
304 /// Read the 'card specific data' block.
305 fn read_csd(&mut self) -> Result<Csd, Error> {
306 match self.card_type {
307 Some(CardType::SD1) => {
308 let mut csd = CsdV1::new();
309 if self.card_command(CMD9, 0)? != 0 {
310 return Err(Error::RegisterReadError);
311 }
312 self.read_data(&mut csd.data)?;
313 Ok(Csd::V1(csd))
314 }
315 Some(CardType::SD2 | CardType::SDHC) => {
316 let mut csd = CsdV2::new();
317 if self.card_command(CMD9, 0)? != 0 {
318 return Err(Error::RegisterReadError);
319 }
320 self.read_data(&mut csd.data)?;
321 Ok(Csd::V2(csd))
322 }
323 None => Err(Error::CardNotFound),
324 }
325 }
326
327 /// Read an arbitrary number of bytes from the card using the SD Card
328 /// protocol and an optional CRC. Always fills the given buffer, so make
329 /// sure it's the right size.
330 fn read_data(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
331 // Get first non-FF byte.
332 let mut delay = Delay::new_read();
333 let status = loop {
334 let s = self.read_byte()?;
335 if s != 0xFF {
336 break s;
337 }
338 delay.delay(&mut self.delayer, Error::TimeoutReadBuffer)?;
339 };
340 if status != DATA_START_BLOCK {
341 return Err(Error::ReadError);
342 }
343
344 buffer.fill(0xFF);
345 self.transfer_bytes(buffer)?;
346
347 // These two bytes are always sent. They are either a valid CRC, or
348 // junk, depending on whether CRC mode was enabled.
349 let mut crc_bytes = [0xFF; 2];
350 self.transfer_bytes(&mut crc_bytes)?;
351 if self.options.use_crc {
352 let crc = u16::from_be_bytes(crc_bytes);
353 let calc_crc = crc16(buffer);
354 if crc != calc_crc {
355 return Err(Error::CrcError(crc, calc_crc));
356 }
357 }
358
359 Ok(())
360 }
361
362 /// Write an arbitrary number of bytes to the card using the SD protocol and
363 /// an optional CRC.
364 fn write_data(&mut self, token: u8, buffer: &[u8]) -> Result<(), Error> {
365 self.write_byte(token)?;
366 self.write_bytes(buffer)?;
367 let crc_bytes = if self.options.use_crc {
368 crc16(buffer).to_be_bytes()
369 } else {
370 [0xFF, 0xFF]
371 };
372 // These two bytes are always sent. They are either a valid CRC, or
373 // junk, depending on whether CRC mode was enabled.
374 self.write_bytes(&crc_bytes)?;
375
376 let status = self.read_byte()?;
377 if (status & DATA_RES_MASK) != DATA_RES_ACCEPTED {
378 Err(Error::WriteError)
379 } else {
380 Ok(())
381 }
382 }
383
384 /// Check the card is initialised.
385 fn check_init(&mut self) -> Result<(), Error> {
386 if self.card_type.is_none() {
387 // If we don't know what the card type is, try and initialise the
388 // card. This will tell us what type of card it is.
389 self.acquire()
390 } else {
391 Ok(())
392 }
393 }
394
395 /// Initializes the card into a known state (or at least tries to).
396 fn acquire(&mut self) -> Result<(), Error> {
397 debug!("acquiring card with opts: {:?}", self.options);
398 let f = |s: &mut Self| {
399 // Assume it hasn't worked
400 let mut card_type;
401 trace!("Reset card..");
402 // Enter SPI mode.
403 let mut delay = Delay::new(s.options.acquire_retries);
404 for _attempts in 1.. {
405 trace!("Enter SPI mode, attempt: {}..", _attempts);
406 match s.card_command(CMD0, 0) {
407 Err(Error::TimeoutCommand(0)) => {
408 // Try again?
409 warn!("Timed out, trying again..");
410 // Try flushing the card as done here: https://github.com/greiman/SdFat/blob/master/src/SdCard/SdSpiCard.cpp#L170,
411 // https://github.com/rust-embedded-community/embedded-sdmmc-rs/pull/65#issuecomment-1270709448
412 for _ in 0..0xFF {
413 s.write_byte(0xFF)?;
414 }
415 }
416 Err(e) => {
417 return Err(e);
418 }
419 Ok(R1_IDLE_STATE) => {
420 break;
421 }
422 Ok(_r) => {
423 // Try again
424 warn!("Got response: {:x}, trying again..", _r);
425 }
426 }
427
428 delay.delay(&mut s.delayer, Error::CardNotFound)?;
429 }
430 // Enable CRC
431 debug!("Enable CRC: {}", s.options.use_crc);
432 // "The SPI interface is initialized in the CRC OFF mode in default"
433 // -- SD Part 1 Physical Layer Specification v9.00, Section 7.2.2 Bus Transfer Protection
434 if s.options.use_crc && s.card_command(CMD59, 1)? != R1_IDLE_STATE {
435 return Err(Error::CantEnableCRC);
436 }
437 // Check card version
438 let mut delay = Delay::new_command();
439 let arg = loop {
440 if s.card_command(CMD8, 0x1AA)? == (R1_ILLEGAL_COMMAND | R1_IDLE_STATE) {
441 card_type = CardType::SD1;
442 break 0;
443 }
444 let mut buffer = [0xFF; 4];
445 s.transfer_bytes(&mut buffer)?;
446 let status = buffer[3];
447 if status == 0xAA {
448 card_type = CardType::SD2;
449 break 0x4000_0000;
450 }
451 delay.delay(&mut s.delayer, Error::TimeoutCommand(CMD8))?;
452 };
453
454 let mut delay = Delay::new_command();
455 while s.card_acmd(ACMD41, arg)? != R1_READY_STATE {
456 delay.delay(&mut s.delayer, Error::TimeoutACommand(ACMD41))?;
457 }
458
459 if card_type == CardType::SD2 {
460 if s.card_command(CMD58, 0)? != 0 {
461 return Err(Error::Cmd58Error);
462 }
463 let mut buffer = [0xFF; 4];
464 s.transfer_bytes(&mut buffer)?;
465 if (buffer[0] & 0xC0) == 0xC0 {
466 card_type = CardType::SDHC;
467 }
468 // Ignore the other three bytes
469 }
470 debug!("Card version: {:?}", card_type);
471 s.card_type = Some(card_type);
472 Ok(())
473 };
474 let result = f(self);
475 let _ = self.read_byte();
476 result
477 }
478
479 /// Perform an application-specific command.
480 fn card_acmd(&mut self, command: u8, arg: u32) -> Result<u8, Error> {
481 self.card_command(CMD55, 0)?;
482 self.card_command(command, arg)
483 }
484
485 /// Perform a command.
486 fn card_command(&mut self, command: u8, arg: u32) -> Result<u8, Error> {
487 if command != CMD0 && command != CMD12 {
488 self.wait_not_busy(Delay::new_command())?;
489 }
490
491 let mut buf = [
492 0x40 | command,
493 (arg >> 24) as u8,
494 (arg >> 16) as u8,
495 (arg >> 8) as u8,
496 arg as u8,
497 0,
498 ];
499 buf[5] = crc7(&buf[0..5]);
500
501 self.write_bytes(&buf)?;
502
503 // skip stuff byte for stop read
504 if command == CMD12 {
505 let _result = self.read_byte()?;
506 }
507
508 let mut delay = Delay::new_command();
509 loop {
510 let result = self.read_byte()?;
511 if (result & 0x80) == ERROR_OK {
512 return Ok(result);
513 }
514 delay.delay(&mut self.delayer, Error::TimeoutCommand(command))?;
515 }
516 }
517
518 /// Receive a byte from the SPI bus by clocking out an 0xFF byte.
519 fn read_byte(&mut self) -> Result<u8, Error> {
520 self.transfer_byte(0xFF)
521 }
522
523 /// Send a byte over the SPI bus and ignore what comes back.
524 fn write_byte(&mut self, out: u8) -> Result<(), Error> {
525 let _ = self.transfer_byte(out)?;
526 Ok(())
527 }
528
529 /// Send one byte and receive one byte over the SPI bus.
530 fn transfer_byte(&mut self, out: u8) -> Result<u8, Error> {
531 let mut read_buf = [0u8; 1];
532 self.spi
533 .transfer(&mut read_buf, &[out])
534 .map_err(|_| Error::Transport)?;
535 Ok(read_buf[0])
536 }
537
538 /// Send multiple bytes and ignore what comes back over the SPI bus.
539 fn write_bytes(&mut self, out: &[u8]) -> Result<(), Error> {
540 self.spi.write(out).map_err(|_e| Error::Transport)?;
541 Ok(())
542 }
543
544 /// Send multiple bytes and replace them with what comes back over the SPI bus.
545 fn transfer_bytes(&mut self, in_out: &mut [u8]) -> Result<(), Error> {
546 self.spi
547 .transfer_in_place(in_out)
548 .map_err(|_e| Error::Transport)?;
549 Ok(())
550 }
551
552 /// Spin until the card returns 0xFF, or we spin too many times and
553 /// timeout.
554 fn wait_not_busy(&mut self, mut delay: Delay) -> Result<(), Error> {
555 loop {
556 let s = self.read_byte()?;
557 if s == 0xFF {
558 break;
559 }
560 delay.delay(&mut self.delayer, Error::TimeoutWaitNotBusy)?;
561 }
562 Ok(())
563 }
564}
565
566/// Options for acquiring the card.
567#[cfg_attr(feature = "defmt-log", derive(defmt::Format))]
568#[derive(Debug)]
569pub struct AcquireOpts {
570 /// Set to true to enable CRC checking on reading/writing blocks of data.
571 ///
572 /// Set to false to disable the CRC. Some cards don't support CRC correctly
573 /// and this option may be useful in that instance.
574 ///
575 /// On by default because without it you might get silent data corruption on
576 /// your card.
577 pub use_crc: bool,
578
579 /// Sets the number of times we will retry to acquire the card before giving up and returning
580 /// `Err(Error::CardNotFound)`. By default, card acquisition will be retried 50 times.
581 pub acquire_retries: u32,
582}
583
584impl Default for AcquireOpts {
585 fn default() -> Self {
586 AcquireOpts {
587 use_crc: true,
588 acquire_retries: 50,
589 }
590 }
591}
592
593/// The possible errors this crate can generate.
594#[cfg_attr(feature = "defmt-log", derive(defmt::Format))]
595#[derive(Debug, Copy, Clone)]
596pub enum Error {
597 /// We got an error from the SPI peripheral
598 Transport,
599 /// We failed to enable CRC checking on the SD card
600 CantEnableCRC,
601 /// We didn't get a response when reading data from the card
602 TimeoutReadBuffer,
603 /// We didn't get a response when waiting for the card to not be busy
604 TimeoutWaitNotBusy,
605 /// We didn't get a response when executing this command
606 TimeoutCommand(u8),
607 /// We didn't get a response when executing this application-specific command
608 TimeoutACommand(u8),
609 /// We got a bad response from Command 58
610 Cmd58Error,
611 /// We failed to read the Card Specific Data register
612 RegisterReadError,
613 /// We got a CRC mismatch (card gave us, we calculated)
614 CrcError(u16, u16),
615 /// Error reading from the card
616 ReadError,
617 /// Error writing to the card
618 WriteError,
619 /// Can't perform this operation with the card in this state
620 BadState,
621 /// Couldn't find the card
622 CardNotFound,
623 /// Couldn't set a GPIO pin
624 GpioError,
625}
626
627/// The different types of card we support.
628#[cfg_attr(feature = "defmt-log", derive(defmt::Format))]
629#[derive(Debug, Copy, Clone, PartialEq, Eq)]
630pub enum CardType {
631 /// An standard-capacity SD Card supporting v1.x of the standard.
632 ///
633 /// Uses byte-addressing internally, so limited to 2GiB in size.
634 SD1,
635 /// An standard-capacity SD Card supporting v2.x of the standard.
636 ///
637 /// Uses byte-addressing internally, so limited to 2GiB in size.
638 SD2,
639 /// An high-capacity 'SDHC' Card.
640 ///
641 /// Uses block-addressing internally to support capacities above 2GiB.
642 SDHC,
643}
644
645/// This an object you can use to busy-wait with a timeout.
646///
647/// Will let you call `delay` up to `max_retries` times before `delay` returns
648/// an error.
649struct Delay {
650 retries_left: u32,
651}
652
653impl Delay {
654 /// The default number of retries for a read operation.
655 ///
656 /// At ~10us each this is ~100ms.
657 ///
658 /// See `Part1_Physical_Layer_Simplified_Specification_Ver9.00-1.pdf` Section 4.6.2.1
659 pub const DEFAULT_READ_RETRIES: u32 = 10_000;
660
661 /// The default number of retries for a write operation.
662 ///
663 /// At ~10us each this is ~500ms.
664 ///
665 /// See `Part1_Physical_Layer_Simplified_Specification_Ver9.00-1.pdf` Section 4.6.2.2
666 pub const DEFAULT_WRITE_RETRIES: u32 = 50_000;
667
668 /// The default number of retries for a control command.
669 ///
670 /// At ~10us each this is ~100ms.
671 ///
672 /// No value is given in the specification, so we pick the same as the read timeout.
673 pub const DEFAULT_COMMAND_RETRIES: u32 = 10_000;
674
675 /// Create a new Delay object with the given maximum number of retries.
676 fn new(max_retries: u32) -> Delay {
677 Delay {
678 retries_left: max_retries,
679 }
680 }
681
682 /// Create a new Delay object with the maximum number of retries for a read operation.
683 fn new_read() -> Delay {
684 Delay::new(Self::DEFAULT_READ_RETRIES)
685 }
686
687 /// Create a new Delay object with the maximum number of retries for a write operation.
688 fn new_write() -> Delay {
689 Delay::new(Self::DEFAULT_WRITE_RETRIES)
690 }
691
692 /// Create a new Delay object with the maximum number of retries for a command operation.
693 fn new_command() -> Delay {
694 Delay::new(Self::DEFAULT_COMMAND_RETRIES)
695 }
696
697 /// Wait for a while.
698 ///
699 /// Checks the retry counter first, and if we hit the max retry limit, the
700 /// value `err` is returned. Otherwise we wait for 10us and then return
701 /// `Ok(())`.
702 fn delay<T>(&mut self, delayer: &mut T, err: Error) -> Result<(), Error>
703 where
704 T: embedded_hal::delay::DelayNs,
705 {
706 if self.retries_left == 0 {
707 Err(err)
708 } else {
709 delayer.delay_us(10);
710 self.retries_left -= 1;
711 Ok(())
712 }
713 }
714}
715
716// ****************************************************************************
717//
718// End Of File
719//
720// ****************************************************************************