Skip to content

Commit d3beac2

Browse files
thejpstereldruin
authored andcommitted
Set a different delay depending on context.
The spec gives some suggested numbers for timeouts for reads and writes.
1 parent d029fd4 commit d3beac2

File tree

1 file changed

+43
-13
lines changed

1 file changed

+43
-13
lines changed

src/sdcard/mod.rs

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ where
229229
// Start a single-block write
230230
s.card_command(CMD24, start_idx)?;
231231
s.write_data(DATA_START_BLOCK, &blocks[0].contents)?;
232-
s.wait_not_busy()?;
232+
s.wait_not_busy(Delay::new_write())?;
233233
if s.card_command(CMD13, 0)? != 0x00 {
234234
return Err(Error::WriteError);
235235
}
@@ -240,11 +240,11 @@ where
240240
// Start a multi-block write
241241
s.card_command(CMD25, start_idx)?;
242242
for block in blocks.iter() {
243-
s.wait_not_busy()?;
243+
s.wait_not_busy(Delay::new_write())?;
244244
s.write_data(WRITE_MULTIPLE_TOKEN, &block.contents)?;
245245
}
246246
// Stop the write
247-
s.wait_not_busy()?;
247+
s.wait_not_busy(Delay::new_write())?;
248248
s.write_byte(STOP_TRAN_TOKEN)?;
249249
}
250250
Ok(())
@@ -315,7 +315,7 @@ where
315315
/// sure it's the right size.
316316
fn read_data(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
317317
// Get first non-FF byte.
318-
let mut delay = Delay::default();
318+
let mut delay = Delay::new_read();
319319
let status = loop {
320320
let s = self.read_byte()?;
321321
if s != 0xFF {
@@ -401,7 +401,7 @@ where
401401
// Assert CS
402402
s.cs_low()?;
403403
// Enter SPI mode.
404-
let mut delay = Delay::default();
404+
let mut delay = Delay::new_command();
405405
for attempts in 1.. {
406406
trace!("Enter SPI mode, attempt: {}..", attempts);
407407
match s.card_command(CMD0, 0) {
@@ -436,7 +436,7 @@ where
436436
return Err(Error::CantEnableCRC);
437437
}
438438
// Check card version
439-
let mut delay = Delay::default();
439+
let mut delay = Delay::new_command();
440440
let arg = loop {
441441
if s.card_command(CMD8, 0x1AA)? == (R1_ILLEGAL_COMMAND | R1_IDLE_STATE) {
442442
card_type = CardType::SD1;
@@ -452,7 +452,7 @@ where
452452
delay.delay(&mut s.delayer, Error::TimeoutCommand(CMD8))?;
453453
};
454454

455-
let mut delay = Delay::default();
455+
let mut delay = Delay::new_command();
456456
while s.card_acmd(ACMD41, arg)? != R1_READY_STATE {
457457
delay.delay(&mut s.delayer, Error::TimeoutACommand(ACMD41))?;
458458
}
@@ -499,7 +499,7 @@ where
499499
/// Perform a command.
500500
fn card_command(&mut self, command: u8, arg: u32) -> Result<u8, Error> {
501501
if command != CMD0 && command != CMD12 {
502-
self.wait_not_busy()?;
502+
self.wait_not_busy(Delay::new_command())?;
503503
}
504504

505505
let mut buf = [
@@ -519,7 +519,7 @@ where
519519
let _result = self.read_byte()?;
520520
}
521521

522-
let mut delay = Delay::default();
522+
let mut delay = Delay::new_command();
523523
loop {
524524
let result = self.read_byte()?;
525525
if (result & 0x80) == ERROR_OK {
@@ -562,8 +562,7 @@ where
562562

563563
/// Spin until the card returns 0xFF, or we spin too many times and
564564
/// timeout.
565-
fn wait_not_busy(&mut self) -> Result<(), Error> {
566-
let mut delay = Delay::default();
565+
fn wait_not_busy(&mut self, mut delay: Delay) -> Result<(), Error> {
567566
loop {
568567
let s = self.read_byte()?;
569568
if s == 0xFF {
@@ -656,10 +655,26 @@ struct Delay {
656655
}
657656

658657
impl Delay {
658+
/// The default number of retries for a read operation.
659+
///
660+
/// At ~10us each this is ~100ms.
661+
///
662+
/// See `Part1_Physical_Layer_Simplified_Specification_Ver9.00-1.pdf` Section 4.6.2.1
663+
pub const DEFAULT_READ_RETRIES: u32 = 10_000;
664+
659665
/// The default number of retries for a write operation.
660666
///
661-
/// At 10us each this is 320ms.
662-
pub const DEFAULT_WRITE_RETRIES: u32 = 32000;
667+
/// At ~10us each this is ~500ms.
668+
///
669+
/// See `Part1_Physical_Layer_Simplified_Specification_Ver9.00-1.pdf` Section 4.6.2.2
670+
pub const DEFAULT_WRITE_RETRIES: u32 = 50_000;
671+
672+
/// The default number of retries for a control command.
673+
///
674+
/// At ~10us each this is ~100ms.
675+
///
676+
/// No value is given in the specification, so we pick the same as the read timeout.
677+
pub const DEFAULT_COMMAND_RETRIES: u32 = 10_000;
663678

664679
/// Create a new Delay object with the given maximum number of retries.
665680
fn new(max_retries: u32) -> Delay {
@@ -668,6 +683,21 @@ impl Delay {
668683
}
669684
}
670685

686+
/// Create a new Delay object with the maximum number of retries for a read operation.
687+
fn new_read() -> Delay {
688+
Delay::new(Self::DEFAULT_READ_RETRIES)
689+
}
690+
691+
/// Create a new Delay object with the maximum number of retries for a write operation.
692+
fn new_write() -> Delay {
693+
Delay::new(Self::DEFAULT_WRITE_RETRIES)
694+
}
695+
696+
/// Create a new Delay object with the maximum number of retries for a command operation.
697+
fn new_command() -> Delay {
698+
Delay::new(Self::DEFAULT_COMMAND_RETRIES)
699+
}
700+
671701
/// Wait for a while.
672702
///
673703
/// Checks the retry counter first, and if we hit the max retry limit, the

0 commit comments

Comments
 (0)