Skip to content

Commit 21fe2a9

Browse files
committed
Implement SDMMC reading.
1 parent 72bcc2f commit 21fe2a9

File tree

2 files changed

+198
-46
lines changed

2 files changed

+198
-46
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ bxcan = ">=0.4, <0.7"
2929
fugit = "0.3.5"
3030
bitfield = "0.13.2"
3131
sdio-host = "0.7.0"
32+
embedded-sdmmc = "0.3.0"
3233

3334
[dependencies.rand_core]
3435
version = "0.6.2"

src/sdmmc.rs

Lines changed: 197 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use core::{fmt, hint::black_box};
1+
use core::{fmt, ops::ControlFlow};
22

33
use fugit::HertzU32 as Hertz;
44
use sdio_host::{
@@ -128,9 +128,8 @@ pub enum BusWidth {
128128
#[repr(u8)]
129129
pub 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

151150
macro_rules! try_datapath {
@@ -197,7 +196,6 @@ fn clear_all_interrupts(icr: &sdmmc1::ICR) {
197196

198197
#[derive(Default)]
199198
pub struct SdCard {
200-
capacity: CardCapacity,
201199
ocr: OCR<SD>,
202200
cid: CID<SD>,
203201
rca: RCA<SD>,
@@ -209,7 +207,6 @@ pub struct SdCard {
209207
impl 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
224221
enum Dir {
225222
HostToCard = 0,
226223
CardToHost = 1,
227224
}
228225

229226
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 {
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

Comments
 (0)