1
- use core:: { fmt, hint :: black_box } ;
1
+ use core:: { fmt, ops :: ControlFlow } ;
2
2
3
3
use fugit:: HertzU32 as Hertz ;
4
4
use sdio_host:: {
@@ -128,9 +128,8 @@ pub enum BusWidth {
128
128
#[ repr( u8 ) ]
129
129
pub enum ClockFreq {
130
130
Freq24MHz = 0 ,
131
- Freq16MHz = 1 ,
132
131
Freq12MHz = 2 ,
133
- Freq8MHz = 8 ,
132
+ Freq8MHz = 4 ,
134
133
Freq4MHz = 10 ,
135
134
Freq1MHz = 46 ,
136
135
Freq400KHz = 118 ,
@@ -145,7 +144,7 @@ pub enum Error {
145
144
RxOverFlow ,
146
145
Timeout ,
147
146
TxUnderErr ,
148
- RespCmdMismatch ,
147
+ WrongResponseSize ,
149
148
}
150
149
151
150
macro_rules! try_datapath {
@@ -197,7 +196,6 @@ fn clear_all_interrupts(icr: &sdmmc1::ICR) {
197
196
198
197
#[ derive( Default ) ]
199
198
pub struct SdCard {
200
- capacity : CardCapacity ,
201
199
ocr : OCR < SD > ,
202
200
cid : CID < SD > ,
203
201
rca : RCA < SD > ,
@@ -209,7 +207,6 @@ pub struct SdCard {
209
207
impl fmt:: Debug for SdCard {
210
208
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
211
209
f. debug_struct ( "SdCard" )
212
- . field ( "capacity" , & self . capacity )
213
210
. field ( "cid" , & self . cid )
214
211
. field ( "csd" , & self . csd )
215
212
. field ( "ocr" , & self . ocr )
@@ -219,15 +216,28 @@ impl fmt::Debug for SdCard {
219
216
}
220
217
}
221
218
222
- #[ derive( Clone , Copy , Debug ) ]
219
+ #[ derive( Debug , Clone , Copy ) ]
223
220
/// Indicates transfer direction
224
221
enum Dir {
225
222
HostToCard = 0 ,
226
223
CardToHost = 1 ,
227
224
}
228
225
229
226
impl SdCard {
230
- pub fn get_address ( & self ) -> u16 {
227
+ /// Size in bytes.
228
+ pub fn size ( & self ) -> u64 {
229
+ self . csd . card_size ( )
230
+ }
231
+
232
+ fn capacity ( & self ) -> CardCapacity {
233
+ if self . ocr . high_capacity ( ) {
234
+ CardCapacity :: HighCapacity
235
+ } else {
236
+ CardCapacity :: StandardCapacity
237
+ }
238
+ }
239
+
240
+ pub fn address ( & self ) -> u16 {
231
241
self . rca . address ( )
232
242
}
233
243
@@ -249,20 +259,15 @@ pub enum SdCardVersion {
249
259
}
250
260
251
261
#[ derive( Debug ) ]
252
- pub struct SdMmc {
262
+ pub struct Sdmmc {
253
263
sdmmc : SDMMC1 ,
254
264
clock : Hertz ,
255
265
bus_width : BusWidth ,
256
266
card : Option < SdCard > ,
257
267
}
258
268
259
- impl SdMmc {
260
- pub fn new < PINS : Pins > (
261
- mut sdmmc : SDMMC1 ,
262
- _pins : PINS ,
263
- apb2 : & mut APB2 ,
264
- clocks : & Clocks ,
265
- ) -> Self {
269
+ impl Sdmmc {
270
+ pub fn new < PINS : Pins > ( sdmmc : SDMMC1 , _pins : PINS , apb2 : & mut APB2 , clocks : & Clocks ) -> Self {
266
271
SDMMC1 :: enable ( apb2) ;
267
272
SDMMC1 :: reset ( apb2) ;
268
273
@@ -297,6 +302,7 @@ impl SdMmc {
297
302
host
298
303
}
299
304
305
+ #[ inline]
300
306
pub fn init ( & mut self , freq : ClockFreq ) -> Result < ( ) , Error > {
301
307
self . power_card ( true ) ;
302
308
@@ -321,7 +327,7 @@ impl SdMmc {
321
327
let voltage_window = 1 << 5 ;
322
328
323
329
let mut timeout = 0xffff ;
324
- let ocr: OCR < SD > = loop {
330
+ card . ocr = loop {
325
331
if timeout == 0 {
326
332
return Err ( Error :: SoftwareTimeout ) ;
327
333
}
@@ -346,13 +352,6 @@ impl SdMmc {
346
352
}
347
353
} ;
348
354
349
- card. capacity = if ocr. high_capacity ( ) {
350
- CardCapacity :: HighCapacity
351
- } else {
352
- CardCapacity :: StandardCapacity
353
- } ;
354
- card. ocr = ocr;
355
-
356
355
self . cmd ( common_cmd:: all_send_cid ( ) ) ?;
357
356
card. cid = CID :: from ( [
358
357
self . sdmmc . resp1 . read ( ) . bits ( ) ,
@@ -386,6 +385,110 @@ impl SdMmc {
386
385
Ok ( ( ) )
387
386
}
388
387
388
+ pub fn read_block ( & mut self , addr : u32 , buf : & mut [ u8 ; 512 ] ) -> Result < ( ) , Error > {
389
+ let card = self . card ( ) ?;
390
+
391
+ let addr = match card. capacity ( ) {
392
+ CardCapacity :: StandardCapacity => addr * 512 ,
393
+ _ => addr,
394
+ } ;
395
+
396
+ self . cmd ( common_cmd:: set_block_length ( 512 ) ) ?;
397
+
398
+ self . start_datapath_transfer ( 512 , 9 , Dir :: CardToHost ) ;
399
+ self . cmd ( common_cmd:: read_single_block ( addr) ) ?;
400
+
401
+ let mut i = 0 ;
402
+ loop {
403
+ match self . read_fifo_hf ( |bits| {
404
+ buf[ i..( i + 4 ) ] . copy_from_slice ( & bits. to_be_bytes ( ) ) ;
405
+ i += 4 ;
406
+ } ) ? {
407
+ ControlFlow :: Break ( ( ) ) => {
408
+ if i == buf. len ( ) {
409
+ return Ok ( ( ) ) ;
410
+ } else {
411
+ return Err ( Error :: WrongResponseSize ) ;
412
+ }
413
+ }
414
+ ControlFlow :: Continue ( ( ) ) => continue ,
415
+ }
416
+ }
417
+ }
418
+
419
+ #[ inline]
420
+ pub fn read_blocks ( & mut self , addr : u32 , buf : & mut [ u8 ] ) -> Result < ( ) , Error > {
421
+ let card = self . card ( ) ?;
422
+
423
+ assert ! (
424
+ buf. len( ) % 512 == 0 ,
425
+ "Buffer length must be a multiple of 512."
426
+ ) ;
427
+
428
+ let addr = match card. capacity ( ) {
429
+ CardCapacity :: StandardCapacity => addr * 512 ,
430
+ _ => addr,
431
+ } ;
432
+
433
+ self . cmd ( common_cmd:: set_block_length ( 512 ) ) ?;
434
+
435
+ self . start_datapath_transfer ( buf. len ( ) as u32 , 9 , Dir :: CardToHost ) ;
436
+ self . cmd ( common_cmd:: read_multiple_blocks ( addr) ) ?;
437
+
438
+ let mut i = 0 ;
439
+ loop {
440
+ match self . read_fifo_hf ( |bits| {
441
+ buf[ i..( i + 4 ) ] . copy_from_slice ( & bits. to_be_bytes ( ) ) ;
442
+ i += 4 ;
443
+ } ) ? {
444
+ ControlFlow :: Break ( ( ) ) => {
445
+ self . cmd ( common_cmd:: stop_transmission ( ) ) ?;
446
+
447
+ if i == buf. len ( ) {
448
+ return Ok ( ( ) ) ;
449
+ } else {
450
+ return Err ( Error :: WrongResponseSize ) ;
451
+ }
452
+ }
453
+ ControlFlow :: Continue ( ( ) ) => continue ,
454
+ }
455
+ }
456
+ }
457
+
458
+ pub fn write_block ( & mut self , addr : u32 , block : & [ u8 ; 512 ] ) -> Result < ( ) , Error > {
459
+ self . card ( ) ?;
460
+
461
+ todo ! ( )
462
+ }
463
+
464
+ /// Read eight 32-bit values from a half-full FIFO.
465
+ #[ inline]
466
+ fn read_fifo_hf ( & mut self , mut f : impl FnMut ( u32 ) -> ( ) ) -> Result < ControlFlow < ( ) , ( ) > , Error > {
467
+ // TODO: Better timeout value.
468
+ let timeout: u32 = 0xffff_ffff ;
469
+ for _ in 0 ..timeout {
470
+ let sta = self . sdmmc . sta . read ( ) ;
471
+
472
+ try_datapath ! ( sta) ;
473
+
474
+ if sta. dbckend ( ) . bit ( ) {
475
+ return Ok ( ControlFlow :: Break ( ( ) ) ) ;
476
+ }
477
+
478
+ if sta. rxfifohf ( ) . bit ( ) {
479
+ for _ in 0 ..8 {
480
+ let bits = u32:: from_be ( self . sdmmc . fifo . read ( ) . bits ( ) ) ;
481
+ f ( bits)
482
+ }
483
+
484
+ return Ok ( ControlFlow :: Continue ( ( ) ) ) ;
485
+ }
486
+ }
487
+
488
+ Err ( Error :: SoftwareTimeout )
489
+ }
490
+
491
+ #[ inline]
389
492
fn set_bus ( & self , bus_width : BusWidth , freq : ClockFreq ) -> Result < ( ) , Error > {
390
493
let card_widebus = self . card ( ) ?. supports_widebus ( ) ;
391
494
@@ -451,20 +554,22 @@ impl SdMmc {
451
554
self . start_datapath_transfer ( 8 , 3 , Dir :: CardToHost ) ;
452
555
self . cmd ( sd_cmd:: send_scr ( ) ) ?;
453
556
454
- let mut scr = [ 0x00 ; 2 ] ;
557
+ let mut scr = [ 0 ; 2 ] ;
455
558
456
559
' outer: for n in scr. iter_mut ( ) . rev ( ) {
457
560
loop {
458
561
let sta = self . sdmmc . sta . read ( ) ;
459
562
460
563
try_datapath ! ( sta) ;
461
564
462
- if sta. dbckend ( ) . bit ( ) {
565
+ if sta. dataend ( ) . bit ( ) {
463
566
break ' outer;
464
567
}
465
568
466
569
if sta. rxdavl ( ) . bit_is_set ( ) {
467
- * n = self . sdmmc . fifo . read ( ) . bits ( ) . swap_bytes ( ) ;
570
+ let bits = u32:: from_be ( self . sdmmc . fifo . read ( ) . bits ( ) ) ;
571
+ * n = bits. to_le ( ) ;
572
+
468
573
continue ' outer;
469
574
}
470
575
}
@@ -485,7 +590,7 @@ impl SdMmc {
485
590
fn read_status ( & mut self ) -> Result < CardStatus < SdCard > , Error > {
486
591
let card = self . card ( ) ?;
487
592
488
- self . cmd ( common_cmd:: card_status ( card. get_address ( ) , false ) ) ?;
593
+ self . cmd ( common_cmd:: card_status ( card. address ( ) , false ) ) ?;
489
594
490
595
let r1 = self . sdmmc . resp1 . read ( ) . bits ( ) ;
491
596
Ok ( CardStatus :: from ( r1) )
@@ -505,27 +610,22 @@ impl SdMmc {
505
610
506
611
let mut sd_status = [ 0u32 ; 16 ] ;
507
612
508
- ' outer: for i in 0 ..2 {
509
- loop {
510
- let sta = self . sdmmc . sta . read ( ) ;
511
-
512
- try_datapath ! ( sta) ;
513
-
514
- if sta. dbckend ( ) . bit ( ) {
515
- break ' outer;
516
- }
517
-
518
- if sta. rxfifohf ( ) . bit ( ) {
519
- for j in 0 ..8 {
520
- sd_status[ 15 - i * 8 - j] = self . sdmmc . fifo . read ( ) . bits ( ) . swap_bytes ( ) ;
613
+ let mut i = sd_status. len ( ) ;
614
+ loop {
615
+ match self . read_fifo_hf ( |bits| {
616
+ i -= 1 ;
617
+ sd_status[ i] = bits. to_le ( ) ;
618
+ } ) ? {
619
+ ControlFlow :: Break ( ( ) ) => {
620
+ return if i == 0 {
621
+ Ok ( SDStatus :: from ( sd_status) )
622
+ } else {
623
+ Err ( Error :: WrongResponseSize )
521
624
}
522
-
523
- continue ' outer;
524
625
}
626
+ ControlFlow :: Continue ( ( ) ) => continue ,
525
627
}
526
628
}
527
-
528
- Ok ( SDStatus :: from ( sd_status) )
529
629
}
530
630
531
631
pub fn card ( & self ) -> Result < & SdCard , Error > {
@@ -541,7 +641,7 @@ impl SdMmc {
541
641
}
542
642
543
643
pub fn app_cmd < R : common_cmd:: Resp > ( & self , cmd : Cmd < R > ) -> Result < ( ) , Error > {
544
- let rca = self . card ( ) . map ( |card| card. get_address ( ) ) . unwrap_or ( 0 ) ;
644
+ let rca = self . card ( ) . map ( |card| card. address ( ) ) . unwrap_or ( 0 ) ;
545
645
self . cmd ( common_cmd:: app_cmd ( rca) ) ?;
546
646
self . cmd ( cmd)
547
647
}
@@ -607,4 +707,55 @@ impl SdMmc {
607
707
608
708
Err ( Error :: SoftwareTimeout )
609
709
}
710
+
711
+ pub fn into_block_device ( self ) -> SdmmcBlockDevice < Sdmmc > {
712
+ SdmmcBlockDevice {
713
+ sdmmc : core:: cell:: RefCell :: new ( self ) ,
714
+ }
715
+ }
716
+ }
717
+
718
+ pub struct SdmmcBlockDevice < SDMMC > {
719
+ sdmmc : core:: cell:: RefCell < SDMMC > ,
720
+ }
721
+
722
+ impl embedded_sdmmc:: BlockDevice for SdmmcBlockDevice < Sdmmc > {
723
+ type Error = Error ;
724
+
725
+ fn read (
726
+ & self ,
727
+ blocks : & mut [ embedded_sdmmc:: Block ] ,
728
+ start_block_idx : embedded_sdmmc:: BlockIdx ,
729
+ _reason : & str ,
730
+ ) -> Result < ( ) , Self :: Error > {
731
+ let start = start_block_idx. 0 ;
732
+ let mut sdmmc = self . sdmmc . borrow_mut ( ) ;
733
+ for block_idx in start..( start + blocks. len ( ) as u32 ) {
734
+ sdmmc. read_block (
735
+ block_idx,
736
+ & mut blocks[ ( block_idx - start) as usize ] . contents ,
737
+ ) ?;
738
+ }
739
+ Ok ( ( ) )
740
+ }
741
+
742
+ fn write (
743
+ & self ,
744
+ blocks : & [ embedded_sdmmc:: Block ] ,
745
+ start_block_idx : embedded_sdmmc:: BlockIdx ,
746
+ ) -> Result < ( ) , Self :: Error > {
747
+ let start = start_block_idx. 0 ;
748
+ let mut sdmmc = self . sdmmc . borrow_mut ( ) ;
749
+ for block_idx in start..( start + blocks. len ( ) as u32 ) {
750
+ sdmmc. write_block ( block_idx, & blocks[ ( block_idx - start) as usize ] . contents ) ?;
751
+ }
752
+ Ok ( ( ) )
753
+ }
754
+
755
+ fn num_blocks ( & self ) -> Result < embedded_sdmmc:: BlockCount , Self :: Error > {
756
+ let sdmmc = self . sdmmc . borrow_mut ( ) ;
757
+ Ok ( embedded_sdmmc:: BlockCount (
758
+ ( sdmmc. card ( ) ?. size ( ) / 512u64 ) as u32 ,
759
+ ) )
760
+ }
610
761
}
0 commit comments