@@ -254,10 +254,8 @@ where
254
254
self . write_data ( DATA_START_BLOCK , & blocks[ 0 ] . contents )
255
255
. await ?;
256
256
self . wait_not_busy ( Delay :: new_write ( ) ) . await ?;
257
- if self . card_command ( CMD13 , 0 ) . await ? != 0x00 {
258
- return Err ( Error :: WriteError ) ;
259
- }
260
- if self . read_byte ( ) . await ? != 0x00 {
257
+ let response = self . card_command ( CMD13 , 0 ) . await ?;
258
+ if response[ 0 ] != 0x00 || response[ 1 ] != 0x00 {
261
259
return Err ( Error :: WriteError ) ;
262
260
}
263
261
} else {
@@ -317,15 +315,17 @@ where
317
315
match self . card_type {
318
316
Some ( CardType :: SD1 ) => {
319
317
let mut csd = CsdV1 :: new ( ) ;
320
- if self . card_command ( CMD9 , 0 ) . await ? != 0 {
318
+ let cmd_response = self . card_command ( CMD9 , 0 ) . await ?;
319
+ if cmd_response[ 0 ] != 0 {
321
320
return Err ( Error :: RegisterReadError ) ;
322
321
}
323
322
self . read_data ( & mut csd. data ) . await ?;
324
323
Ok ( Csd :: V1 ( csd) )
325
324
}
326
325
Some ( CardType :: SD2 | CardType :: SDHC ) => {
327
326
let mut csd = CsdV2 :: new ( ) ;
328
- if self . card_command ( CMD9 , 0 ) . await ? != 0 {
327
+ let cmd_response = self . card_command ( CMD9 , 0 ) . await ?;
328
+ if cmd_response[ 0 ] != 0 {
329
329
return Err ( Error :: RegisterReadError ) ;
330
330
}
331
331
self . read_data ( & mut csd. data ) . await ?;
@@ -429,12 +429,12 @@ where
429
429
Err ( e) => {
430
430
return Err ( e) ;
431
431
}
432
- Ok ( R1_IDLE_STATE ) => {
432
+ Ok ( [ R1_IDLE_STATE , .. ] ) => {
433
433
break ;
434
434
}
435
435
Ok ( _r) => {
436
436
// Try again
437
- warn ! ( "Got response: {:x}, trying again.." , _r) ;
437
+ warn ! ( "Got response: {:x}, trying again.." , _r[ 0 ] ) ;
438
438
}
439
439
}
440
440
@@ -444,19 +444,18 @@ where
444
444
debug ! ( "Enable CRC: {}" , self . options. use_crc) ;
445
445
// "The SPI interface is initialized in the CRC OFF mode in default"
446
446
// -- SD Part 1 Physical Layer Specification v9.00, Section 7.2.2 Bus Transfer Protection
447
- if self . options . use_crc && self . card_command ( CMD59 , 1 ) . await ? != R1_IDLE_STATE {
447
+ if self . options . use_crc && self . card_command ( CMD59 , 1 ) . await ?[ 0 ] != R1_IDLE_STATE {
448
448
return Err ( Error :: CantEnableCRC ) ;
449
449
}
450
450
// Check card version
451
451
let mut delay = Delay :: new_command ( ) ;
452
452
let arg = loop {
453
- if self . card_command ( CMD8 , 0x1AA ) . await ? == ( R1_ILLEGAL_COMMAND | R1_IDLE_STATE ) {
453
+ let cmd_response = self . card_command ( CMD8 , 0x1AA ) . await ?;
454
+ if cmd_response[ 0 ] == ( R1_ILLEGAL_COMMAND | R1_IDLE_STATE ) {
454
455
card_type = CardType :: SD1 ;
455
456
break 0 ;
456
457
}
457
- let mut buffer = [ 0xFF ; 4 ] ;
458
- self . transfer_bytes ( & mut buffer) . await ?;
459
- let status = buffer[ 3 ] ;
458
+ let status = cmd_response[ 4 ] ;
460
459
if status == 0xAA {
461
460
card_type = CardType :: SD2 ;
462
461
break 0x4000_0000 ;
@@ -474,12 +473,11 @@ where
474
473
}
475
474
476
475
if card_type == CardType :: SD2 {
477
- if self . card_command ( CMD58 , 0 ) . await ? != 0 {
476
+ let cmd_response = self . card_command ( CMD58 , 0 ) . await ?;
477
+ if cmd_response[ 0 ] != 0 {
478
478
return Err ( Error :: Cmd58Error ) ;
479
479
}
480
- let mut buffer = [ 0xFF ; 4 ] ;
481
- self . transfer_bytes ( & mut buffer) . await ?;
482
- if ( buffer[ 0 ] & 0xC0 ) == 0xC0 {
480
+ if ( cmd_response[ 1 ] & 0xC0 ) == 0xC0 {
483
481
card_type = CardType :: SDHC ;
484
482
}
485
483
// Ignore the other three bytes
@@ -496,42 +494,41 @@ where
496
494
/// Perform an application-specific command.
497
495
async fn card_acmd ( & mut self , command : u8 , arg : u32 ) -> Result < u8 , Error > {
498
496
self . card_command ( CMD55 , 0 ) . await ?;
499
- self . card_command ( command, arg) . await
497
+ self . card_command ( command, arg) . await . map ( |r| r [ 0 ] )
500
498
}
501
499
502
500
/// Perform a command.
503
- async fn card_command ( & mut self , command : u8 , arg : u32 ) -> Result < u8 , Error > {
501
+ async fn card_command ( & mut self , command : u8 , arg : u32 ) -> Result < [ u8 ; 5 ] , Error > {
504
502
if command != CMD0 && command != CMD12 {
505
503
self . wait_not_busy ( Delay :: new_command ( ) ) . await ?;
506
504
}
507
505
508
- let mut buf = [
509
- 0x40 | command,
510
- ( arg >> 24 ) as u8 ,
511
- ( arg >> 16 ) as u8 ,
512
- ( arg >> 8 ) as u8 ,
513
- arg as u8 ,
514
- 0 ,
515
- ] ;
506
+ // Write the command and read the response in a single SPI transfer.
507
+ const COMMAND_BYTES : usize = 6 ;
508
+ const MAX_WAIT_BYTES : usize = 8 ;
509
+ const RESPONSE_BYTES : usize = 5 ;
510
+ const TRANSFER_BYTES : usize = COMMAND_BYTES + MAX_WAIT_BYTES + RESPONSE_BYTES ;
511
+
512
+ let mut buf = [ 0xFF ; TRANSFER_BYTES ] ;
513
+ buf[ 0 ] = 0x40 | command;
514
+ buf[ 1 ] = ( arg >> 24 ) as u8 ;
515
+ buf[ 2 ] = ( arg >> 16 ) as u8 ;
516
+ buf[ 3 ] = ( arg >> 8 ) as u8 ;
517
+ buf[ 4 ] = arg as u8 ;
516
518
buf[ 5 ] = crc7 ( & buf[ 0 ..5 ] ) ;
517
519
518
- self . write_bytes ( & buf) . await ?;
519
-
520
- // skip stuff byte for stop read
521
- if command == CMD12 {
522
- let _result = self . read_byte ( ) . await ?;
523
- }
524
-
525
- let mut delay = Delay :: new_command ( ) ;
526
- loop {
527
- let result = self . read_byte ( ) . await ?;
528
- if ( result & 0x80 ) == ERROR_OK {
529
- return Ok ( result) ;
530
- }
531
- delay
532
- . delay ( & mut self . delayer , Error :: TimeoutCommand ( command) )
533
- . await ?;
534
- }
520
+ self . transfer_bytes ( & mut buf) . await ?;
521
+
522
+ buf. iter ( )
523
+ . skip ( COMMAND_BYTES )
524
+ . position ( |& b| ( b & 0x80 ) == ERROR_OK )
525
+ . and_then ( |pos| {
526
+ let start = pos + COMMAND_BYTES ;
527
+ let end = start + RESPONSE_BYTES ;
528
+ buf. get ( start..end)
529
+ } )
530
+ . and_then ( |bytes| bytes. try_into ( ) . ok ( ) )
531
+ . ok_or ( Error :: TimeoutCommand ( command) )
535
532
}
536
533
537
534
/// Receive a byte from the SPI bus by clocking out an 0xFF byte.
0 commit comments