Skip to content

Commit fb7403d

Browse files
committed
Take ownership of the SDIO device
1 parent ad0a91e commit fb7403d

File tree

2 files changed

+66
-62
lines changed

2 files changed

+66
-62
lines changed

examples/sdio-usb-block.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,28 +30,31 @@ static USB_STORAGE: Mutex<RefCell<Option<usbd_scsi::Scsi<UsbBusType, Storage>>>>
3030
Mutex::new(RefCell::new(None));
3131

3232
struct Storage {
33-
sdio: Sdio,
33+
sdio: RefCell<Sdio>,
3434
}
3535

3636
impl BlockDevice for Storage {
3737
const BLOCK_BYTES: usize = 512;
3838

3939
fn read_block(&self, lba: u32, block: &mut [u8]) -> Result<(), BlockDeviceError> {
40-
self.sdio.read_block(lba, block).map_err(|e| {
40+
let mut sdio = self.sdio.borrow_mut();
41+
sdio.read_block(lba, block).map_err(|e| {
4142
rprintln!("read error: {:?}", e);
4243
BlockDeviceError::HardwareError
4344
})
4445
}
4546

4647
fn write_block(&mut self, lba: u32, block: &[u8]) -> Result<(), BlockDeviceError> {
47-
self.sdio.write_block(lba, block).map_err(|e| {
48+
let mut sdio = self.sdio.borrow_mut();
49+
sdio.write_block(lba, block).map_err(|e| {
4850
rprintln!("write error: {:?}", e);
4951
BlockDeviceError::WriteError
5052
})
5153
}
5254

5355
fn max_lba(&self) -> u32 {
54-
self.sdio.card().map(|c| c.block_count() - 1).unwrap_or(0)
56+
let sdio = self.sdio.borrow();
57+
sdio.card().map(|c| c.block_count() - 1).unwrap_or(0)
5558
}
5659
}
5760

@@ -125,7 +128,7 @@ fn main() -> ! {
125128
.into_alternate_af12()
126129
.internal_pull_up(true);
127130

128-
Sdio::new((clk, cmd, d0, d1, d2, d3))
131+
Sdio::new(device.SDIO, (clk, cmd, d0, d1, d2, d3))
129132
};
130133

131134
rprintln!("Waiting for card...");
@@ -145,7 +148,9 @@ fn main() -> ! {
145148

146149
rprintln!("blocks: {:?}", sdio.card().map(|c| c.block_count()));
147150

148-
let sdhc = Storage { sdio };
151+
let sdhc = Storage {
152+
sdio: RefCell::new(sdio),
153+
};
149154

150155
unsafe {
151156
let usb = USB {

src/sdio.rs

Lines changed: 55 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ pub enum Error {
180180
}
181181

182182
pub struct Sdio {
183+
sdio: SDIO,
183184
bw: Buswidth,
184185
card: Option<Card>,
185186
}
@@ -238,8 +239,8 @@ pub struct Card {
238239
}
239240

240241
impl Sdio {
241-
pub fn new<PINS: Pins>(_pins: PINS) -> Self {
242-
let sdio = unsafe { &*SDIO::ptr() };
242+
pub fn new<PINS: Pins>(sdio: SDIO, _pins: PINS) -> Self {
243+
//let sdio = unsafe { &*SDIO::ptr() };
243244

244245
unsafe {
245246
//NOTE(unsafe) this reference will only be used for atomic writes with no side effects
@@ -272,6 +273,7 @@ impl Sdio {
272273
.modify(|_, w| unsafe { w.pwrctrl().bits(PowerCtrl::Off as u8) });
273274

274275
Sdio {
276+
sdio,
275277
bw: PINS::BUSWIDTH,
276278
card: None,
277279
}
@@ -282,19 +284,18 @@ impl Sdio {
282284
}
283285

284286
pub fn init_card(&mut self) -> Result<(), Error> {
285-
let sdio = unsafe { &*SDIO::ptr() };
286-
287287
// Enable power to card
288-
sdio.power
288+
self.sdio
289+
.power
289290
.modify(|_, w| unsafe { w.pwrctrl().bits(PowerCtrl::On as u8) });
290291

291292
// Enable clock
292-
sdio.clkcr.modify(|_, w| w.clken().set_bit());
293+
self.sdio.clkcr.modify(|_, w| w.clken().set_bit());
293294

294295
self.cmd(Cmd::idle())?;
295296

296297
self.cmd(Cmd::hs_send_ext_csd(0x1AA))?;
297-
let r1 = sdio.resp1.read().bits();
298+
let r1 = self.sdio.resp1.read().bits();
298299

299300
let mut card = if r1 == 0x1AA {
300301
/* v2 card */
@@ -315,7 +316,7 @@ impl Sdio {
315316
Err(Error::Crc) => (),
316317
Err(err) => return Err(err),
317318
}
318-
let ocr = sdio.resp1.read().bits();
319+
let ocr = self.sdio.resp1.read().bits();
319320
if ocr & 0x8000_0000 == 0 {
320321
// Still powering up
321322
continue;
@@ -334,21 +335,21 @@ impl Sdio {
334335

335336
// Get CID
336337
self.cmd(Cmd::all_send_cid())?;
337-
card.cid[0] = sdio.resp1.read().bits();
338-
card.cid[1] = sdio.resp2.read().bits();
339-
card.cid[2] = sdio.resp3.read().bits();
340-
card.cid[3] = sdio.resp4.read().bits();
338+
card.cid[0] = self.sdio.resp1.read().bits();
339+
card.cid[1] = self.sdio.resp2.read().bits();
340+
card.cid[2] = self.sdio.resp3.read().bits();
341+
card.cid[3] = self.sdio.resp4.read().bits();
341342

342343
// Get RCA
343344
self.cmd(Cmd::send_rel_addr())?;
344-
card.rca = sdio.resp1.read().bits() >> 16;
345+
card.rca = self.sdio.resp1.read().bits() >> 16;
345346

346347
// Get CSD
347348
self.cmd(Cmd::send_csd(card.rca << 16))?;
348-
card.csd[0] = sdio.resp1.read().bits();
349-
card.csd[1] = sdio.resp2.read().bits();
350-
card.csd[2] = sdio.resp3.read().bits();
351-
card.csd[3] = sdio.resp4.read().bits();
349+
card.csd[0] = self.sdio.resp1.read().bits();
350+
card.csd[1] = self.sdio.resp2.read().bits();
351+
card.csd[2] = self.sdio.resp3.read().bits();
352+
card.csd[3] = self.sdio.resp4.read().bits();
352353

353354
self.select_card(Some(&card))?;
354355

@@ -362,17 +363,19 @@ impl Sdio {
362363
Ok(())
363364
}
364365

365-
pub fn read_block(&self, addr: u32, buf: &mut [u8]) -> Result<(), Error> {
366-
let sdio = unsafe { &*SDIO::ptr() };
366+
pub fn read_block(&mut self, addr: u32, buf: &mut [u8]) -> Result<(), Error> {
367367
let _card = self.card()?;
368368

369369
self.cmd(Cmd::set_blocklen(512))?;
370370

371371
// Setup read command
372-
sdio.dtimer
372+
self.sdio
373+
.dtimer
373374
.write(|w| unsafe { w.datatime().bits(0xFFFF_FFFF) });
374-
sdio.dlen.write(|w| unsafe { w.datalength().bits(512) });
375-
sdio.dctrl.write(|w| unsafe {
375+
self.sdio
376+
.dlen
377+
.write(|w| unsafe { w.datalength().bits(512) });
378+
self.sdio.dctrl.write(|w| unsafe {
376379
w.dblocksize()
377380
.bits(9) //512
378381
.dtdir()
@@ -385,7 +388,7 @@ impl Sdio {
385388
let mut i = 0;
386389
let mut sta;
387390
while {
388-
sta = sdio.sta.read();
391+
sta = self.sdio.sta.read();
389392
!(sta.rxoverr().bit()
390393
|| sta.dcrcfail().bit()
391394
|| sta.dtimeout().bit()
@@ -394,7 +397,7 @@ impl Sdio {
394397
} {
395398
if sta.rxfifohf().bit() {
396399
for _ in 0..8 {
397-
let bytes = sdio.fifo.read().bits().to_le_bytes();
400+
let bytes = self.sdio.fifo.read().bits().to_le_bytes();
398401
buf[i..i + 4].copy_from_slice(&bytes);
399402
i += 4;
400403
}
@@ -416,18 +419,19 @@ impl Sdio {
416419
Ok(())
417420
}
418421

419-
pub fn write_block(&self, addr: u32, buf: &[u8]) -> Result<(), Error> {
420-
let sdio = unsafe { &*SDIO::ptr() };
421-
422+
pub fn write_block(&mut self, addr: u32, buf: &[u8]) -> Result<(), Error> {
422423
let _card = self.card()?;
423424

424425
self.cmd(Cmd::set_blocklen(512))?;
425426

426427
// Setup write command
427-
sdio.dtimer
428+
self.sdio
429+
.dtimer
428430
.write(|w| unsafe { w.datatime().bits(0xFFFF_FFFF) });
429-
sdio.dlen.write(|w| unsafe { w.datalength().bits(512) });
430-
sdio.dctrl.write(|w| unsafe {
431+
self.sdio
432+
.dlen
433+
.write(|w| unsafe { w.datalength().bits(512) });
434+
self.sdio.dctrl.write(|w| unsafe {
431435
w.dblocksize()
432436
.bits(9) //512
433437
.dtdir()
@@ -440,7 +444,7 @@ impl Sdio {
440444
let mut i = 0;
441445
let mut sta;
442446
while {
443-
sta = sdio.sta.read();
447+
sta = self.sdio.sta.read();
444448
!(sta.txunderr().bit()
445449
|| sta.dcrcfail().bit()
446450
|| sta.dtimeout().bit()
@@ -452,7 +456,7 @@ impl Sdio {
452456
let mut wb = [0u8; 4];
453457
wb.copy_from_slice(&buf[i..i + 4]);
454458
let word = u32::from_le_bytes(wb);
455-
sdio.fifo.write(|w| unsafe { w.bits(word) });
459+
self.sdio.fifo.write(|w| unsafe { w.bits(word) });
456460
i += 4;
457461
}
458462
}
@@ -474,19 +478,18 @@ impl Sdio {
474478
}
475479

476480
fn read_card_status(&mut self) -> Result<(), Error> {
477-
let sdio = unsafe { &*SDIO::ptr() };
478-
479481
let card = self.card()?;
480482

481483
self.cmd(Cmd::set_blocklen(64))?;
482484

483485
self.cmd(Cmd::app_cmd(card.rca << 16))?;
484486

485487
// Prepare the transfer
486-
sdio.dtimer
488+
self.sdio
489+
.dtimer
487490
.write(|w| unsafe { w.datatime().bits(0xFFFF_FFFF) });
488-
sdio.dlen.write(|w| unsafe { w.datalength().bits(64) });
489-
sdio.dctrl.write(|w| unsafe {
491+
self.sdio.dlen.write(|w| unsafe { w.datalength().bits(64) });
492+
self.sdio.dctrl.write(|w| unsafe {
490493
w.dblocksize()
491494
.bits(6) // 64
492495
.dtdir()
@@ -501,15 +504,15 @@ impl Sdio {
501504
let mut idx = 0;
502505
let mut sta;
503506
while {
504-
sta = sdio.sta.read();
507+
sta = self.sdio.sta.read();
505508
!(sta.rxoverr().bit()
506509
|| sta.dcrcfail().bit()
507510
|| sta.dtimeout().bit()
508511
|| sta.dbckend().bit())
509512
} {
510513
if sta.rxfifohf().bit() {
511514
for _ in 0..8 {
512-
status[idx] = sdio.fifo.read().bits();
515+
status[idx] = self.sdio.fifo.read().bits();
513516
idx += 1;
514517
}
515518
}
@@ -544,31 +547,31 @@ impl Sdio {
544547
}
545548

546549
fn get_scr(&self, card: &mut Card) -> Result<(), Error> {
547-
let sdio = unsafe { &*SDIO::ptr() };
548-
549550
self.cmd(Cmd::set_blocklen(8))?;
550551
self.cmd(Cmd::app_cmd(card.rca << 16))?;
551552

552-
sdio.dtimer
553+
self.sdio
554+
.dtimer
553555
.write(|w| unsafe { w.datatime().bits(0xFFFF_FFFF) });
554-
sdio.dlen.write(|w| unsafe { w.datalength().bits(8) });
555-
sdio.dctrl
556+
self.sdio.dlen.write(|w| unsafe { w.datalength().bits(8) });
557+
self.sdio
558+
.dctrl
556559
.write(|w| unsafe { w.dblocksize().bits(3).dtdir().set_bit().dten().set_bit() });
557560
self.cmd(Cmd::cmd51())?;
558561

559562
let mut scr = [0; 2];
560563
let mut i = 0;
561564
let mut sta;
562565
while {
563-
sta = sdio.sta.read();
566+
sta = self.sdio.sta.read();
564567

565568
!(sta.rxoverr().bit()
566569
|| sta.dcrcfail().bit()
567570
|| sta.dtimeout().bit()
568571
|| sta.dbckend().bit())
569572
} {
570573
if sta.rxdavl().bit() {
571-
scr[i] = sdio.fifo.read().bits();
574+
scr[i] = self.sdio.fifo.read().bits();
572575
i += 1;
573576
}
574577

@@ -600,8 +603,6 @@ impl Sdio {
600603

601604
/// Set bus width and clock frequency
602605
fn set_bus(&self, width: Buswidth, freq: ClockFreq, card: &Card) -> Result<(), Error> {
603-
let sdio = unsafe { &*SDIO::ptr() };
604-
605606
let (width, acmd_arg) = match width {
606607
Buswidth::Buswidth4 if card.supports_widebus() => (width, 2),
607608
_ => (Buswidth::Buswidth1, 1),
@@ -610,7 +611,7 @@ impl Sdio {
610611
self.cmd(Cmd::app_cmd(card.rca << 16))?;
611612
self.cmd(Cmd::acmd6(acmd_arg))?;
612613

613-
sdio.clkcr.modify(|_, w| unsafe {
614+
self.sdio.clkcr.modify(|_, w| unsafe {
614615
w.clkdiv()
615616
.bits(freq as u8)
616617
.widbus()
@@ -622,10 +623,8 @@ impl Sdio {
622623
}
623624

624625
fn cmd(&self, cmd: Cmd) -> Result<(), Error> {
625-
let sdio = unsafe { &*SDIO::ptr() };
626-
627626
// Clear interrupts
628-
sdio.icr.modify(|_, w| {
627+
self.sdio.icr.modify(|_, w| {
629628
w.ccrcfailc()
630629
.set_bit()
631630
.ctimeoutc()
@@ -655,9 +654,9 @@ impl Sdio {
655654
});
656655

657656
// Command arg
658-
sdio.arg.write(|w| unsafe { w.cmdarg().bits(cmd.arg) });
657+
self.sdio.arg.write(|w| unsafe { w.cmdarg().bits(cmd.arg) });
659658

660-
sdio.cmd.write(|w| unsafe {
659+
self.sdio.cmd.write(|w| unsafe {
661660
w.waitresp()
662661
.bits(cmd.resp as u8)
663662
.cmdindex()
@@ -674,14 +673,14 @@ impl Sdio {
674673
if cmd.resp == Response::None {
675674
// Wait for command sent or a timeout
676675
while {
677-
sta = sdio.sta.read();
676+
sta = self.sdio.sta.read();
678677
!(sta.ctimeout().bit() || sta.cmdsent().bit()) && timeout > 0
679678
} {
680679
timeout -= 1;
681680
}
682681
} else {
683682
while {
684-
sta = sdio.sta.read();
683+
sta = self.sdio.sta.read();
685684
!(sta.ctimeout().bit() || sta.cmdrend().bit() || sta.ccrcfail().bit())
686685
&& timeout > 0
687686
} {

0 commit comments

Comments
 (0)