1- use core:: { fmt, hint :: black_box } ;
1+ use core:: { fmt, ops :: ControlFlow } ;
22
33use fugit:: HertzU32 as Hertz ;
44use sdio_host:: {
@@ -128,9 +128,8 @@ pub enum BusWidth {
128128#[ repr( u8 ) ]
129129pub enum ClockFreq {
130130 Freq24MHz = 0 ,
131- Freq16MHz = 1 ,
132131 Freq12MHz = 2 ,
133- Freq8MHz = 8 ,
132+ Freq8MHz = 4 ,
134133 Freq4MHz = 10 ,
135134 Freq1MHz = 46 ,
136135 Freq400KHz = 118 ,
@@ -145,7 +144,7 @@ pub enum Error {
145144 RxOverFlow ,
146145 Timeout ,
147146 TxUnderErr ,
148- RespCmdMismatch ,
147+ WrongResponseSize ,
149148}
150149
151150macro_rules! try_datapath {
@@ -197,7 +196,6 @@ fn clear_all_interrupts(icr: &sdmmc1::ICR) {
197196
198197#[ derive( Default ) ]
199198pub struct SdCard {
200- capacity : CardCapacity ,
201199 ocr : OCR < SD > ,
202200 cid : CID < SD > ,
203201 rca : RCA < SD > ,
@@ -209,7 +207,6 @@ pub struct SdCard {
209207impl fmt:: Debug for SdCard {
210208 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
211209 f. debug_struct ( "SdCard" )
212- . field ( "capacity" , & self . capacity )
213210 . field ( "cid" , & self . cid )
214211 . field ( "csd" , & self . csd )
215212 . field ( "ocr" , & self . ocr )
@@ -219,15 +216,28 @@ impl fmt::Debug for SdCard {
219216 }
220217}
221218
222- #[ derive( Clone , Copy , Debug ) ]
219+ #[ derive( Debug , Clone , Copy ) ]
223220/// Indicates transfer direction
224221enum Dir {
225222 HostToCard = 0 ,
226223 CardToHost = 1 ,
227224}
228225
229226impl 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 {
231241 self . rca . address ( )
232242 }
233243
@@ -249,20 +259,15 @@ pub enum SdCardVersion {
249259}
250260
251261#[ derive( Debug ) ]
252- pub struct SdMmc {
262+ pub struct Sdmmc {
253263 sdmmc : SDMMC1 ,
254264 clock : Hertz ,
255265 bus_width : BusWidth ,
256266 card : Option < SdCard > ,
257267}
258268
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 {
266271 SDMMC1 :: enable ( apb2) ;
267272 SDMMC1 :: reset ( apb2) ;
268273
@@ -297,6 +302,7 @@ impl SdMmc {
297302 host
298303 }
299304
305+ #[ inline]
300306 pub fn init ( & mut self , freq : ClockFreq ) -> Result < ( ) , Error > {
301307 self . power_card ( true ) ;
302308
@@ -321,7 +327,7 @@ impl SdMmc {
321327 let voltage_window = 1 << 5 ;
322328
323329 let mut timeout = 0xffff ;
324- let ocr: OCR < SD > = loop {
330+ card . ocr = loop {
325331 if timeout == 0 {
326332 return Err ( Error :: SoftwareTimeout ) ;
327333 }
@@ -346,13 +352,6 @@ impl SdMmc {
346352 }
347353 } ;
348354
349- card. capacity = if ocr. high_capacity ( ) {
350- CardCapacity :: HighCapacity
351- } else {
352- CardCapacity :: StandardCapacity
353- } ;
354- card. ocr = ocr;
355-
356355 self . cmd ( common_cmd:: all_send_cid ( ) ) ?;
357356 card. cid = CID :: from ( [
358357 self . sdmmc . resp1 . read ( ) . bits ( ) ,
@@ -386,6 +385,110 @@ impl SdMmc {
386385 Ok ( ( ) )
387386 }
388387
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]
389492 fn set_bus ( & self , bus_width : BusWidth , freq : ClockFreq ) -> Result < ( ) , Error > {
390493 let card_widebus = self . card ( ) ?. supports_widebus ( ) ;
391494
@@ -451,20 +554,22 @@ impl SdMmc {
451554 self . start_datapath_transfer ( 8 , 3 , Dir :: CardToHost ) ;
452555 self . cmd ( sd_cmd:: send_scr ( ) ) ?;
453556
454- let mut scr = [ 0x00 ; 2 ] ;
557+ let mut scr = [ 0 ; 2 ] ;
455558
456559 ' outer: for n in scr. iter_mut ( ) . rev ( ) {
457560 loop {
458561 let sta = self . sdmmc . sta . read ( ) ;
459562
460563 try_datapath ! ( sta) ;
461564
462- if sta. dbckend ( ) . bit ( ) {
565+ if sta. dataend ( ) . bit ( ) {
463566 break ' outer;
464567 }
465568
466569 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+
468573 continue ' outer;
469574 }
470575 }
@@ -485,7 +590,7 @@ impl SdMmc {
485590 fn read_status ( & mut self ) -> Result < CardStatus < SdCard > , Error > {
486591 let card = self . card ( ) ?;
487592
488- self . cmd ( common_cmd:: card_status ( card. get_address ( ) , false ) ) ?;
593+ self . cmd ( common_cmd:: card_status ( card. address ( ) , false ) ) ?;
489594
490595 let r1 = self . sdmmc . resp1 . read ( ) . bits ( ) ;
491596 Ok ( CardStatus :: from ( r1) )
@@ -505,27 +610,22 @@ impl SdMmc {
505610
506611 let mut sd_status = [ 0u32 ; 16 ] ;
507612
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 )
521624 }
522-
523- continue ' outer;
524625 }
626+ ControlFlow :: Continue ( ( ) ) => continue ,
525627 }
526628 }
527-
528- Ok ( SDStatus :: from ( sd_status) )
529629 }
530630
531631 pub fn card ( & self ) -> Result < & SdCard , Error > {
@@ -541,7 +641,7 @@ impl SdMmc {
541641 }
542642
543643 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 ) ;
545645 self . cmd ( common_cmd:: app_cmd ( rca) ) ?;
546646 self . cmd ( cmd)
547647 }
@@ -607,4 +707,55 @@ impl SdMmc {
607707
608708 Err ( Error :: SoftwareTimeout )
609709 }
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+ }
610761}
0 commit comments