Skip to content

Commit afdb7fb

Browse files
jonathanpallanteldruin
authored andcommitted
Reworked Card Type.
Now we store an Option<CardType>, and the user can unsafely declare a certain type of card to be fitted and initialised.
1 parent 2aa9f8a commit afdb7fb

File tree

1 file changed

+45
-21
lines changed

1 file changed

+45
-21
lines changed

src/sdcard/mod.rs

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ where
7272
inner: RefCell::new(SdCardInner {
7373
spi,
7474
cs,
75-
card_type: CardType::Unknown,
75+
card_type: None,
7676
options,
7777
}),
7878
}
@@ -85,8 +85,7 @@ where
8585
F: FnOnce(&mut SPI) -> T,
8686
{
8787
let mut inner = self.inner.borrow_mut();
88-
let result = func(&mut inner.spi);
89-
result
88+
func(&mut inner.spi)
9089
}
9190

9291
/// Return the usable size of this SD card in bytes.
@@ -108,7 +107,24 @@ where
108107
/// The next operation will assume the card has been freshly inserted.
109108
pub fn mark_card_uninit(&self) {
110109
let mut inner = self.inner.borrow_mut();
111-
inner.card_type = CardType::Unknown;
110+
inner.card_type = None;
111+
}
112+
113+
/// Get the card type.
114+
pub fn get_card_type(&self) -> Option<CardType> {
115+
let inner = self.inner.borrow();
116+
inner.card_type
117+
}
118+
119+
/// Tell the driver the card has been initialised.
120+
///
121+
/// # Safety
122+
///
123+
/// Only do this if the card has actually been initialised and is of the
124+
/// indicated type, otherwise corruption may occur.
125+
pub unsafe fn mark_card_as_init(&self, card_type: CardType) {
126+
let mut inner = self.inner.borrow_mut();
127+
inner.card_type = Some(card_type);
112128
}
113129
}
114130

@@ -165,7 +181,7 @@ where
165181
{
166182
spi: SPI,
167183
cs: CS,
168-
card_type: CardType,
184+
card_type: Option<CardType>,
169185
options: AcquireOpts,
170186
}
171187

@@ -178,9 +194,9 @@ where
178194
/// Read one or more blocks, starting at the given block index.
179195
fn read(&mut self, blocks: &mut [Block], start_block_idx: BlockIdx) -> Result<(), Error> {
180196
let start_idx = match self.card_type {
181-
CardType::SD1 | CardType::SD2 => start_block_idx.0 * 512,
182-
CardType::Sdhc => start_block_idx.0,
183-
CardType::Unknown => return Err(Error::CardNotFound),
197+
Some(CardType::SD1 | CardType::SD2) => start_block_idx.0 * 512,
198+
Some(CardType::SDHC) => start_block_idx.0,
199+
None => return Err(Error::CardNotFound),
184200
};
185201
self.with_chip_select(|s| {
186202
if blocks.len() == 1 {
@@ -203,9 +219,9 @@ where
203219
/// Write one or more blocks, starting at the given block index.
204220
fn write(&mut self, blocks: &[Block], start_block_idx: BlockIdx) -> Result<(), Error> {
205221
let start_idx = match self.card_type {
206-
CardType::SD1 | CardType::SD2 => start_block_idx.0 * 512,
207-
CardType::Sdhc => start_block_idx.0,
208-
CardType::Unknown => return Err(Error::CardNotFound),
222+
Some(CardType::SD1 | CardType::SD2) => start_block_idx.0 * 512,
223+
Some(CardType::SDHC) => start_block_idx.0,
224+
None => return Err(Error::CardNotFound),
209225
};
210226
self.with_chip_select(|s| {
211227
if blocks.len() == 1 {
@@ -273,23 +289,23 @@ where
273289
/// Read the 'card specific data' block.
274290
fn read_csd(&mut self) -> Result<Csd, Error> {
275291
match self.card_type {
276-
CardType::SD1 => {
292+
Some(CardType::SD1) => {
277293
let mut csd = CsdV1::new();
278294
if self.card_command(CMD9, 0)? != 0 {
279295
return Err(Error::RegisterReadError);
280296
}
281297
self.read_data(&mut csd.data)?;
282298
Ok(Csd::V1(csd))
283299
}
284-
CardType::SD2 | CardType::Sdhc => {
300+
Some(CardType::SD2 | CardType::SDHC) => {
285301
let mut csd = CsdV2::new();
286302
if self.card_command(CMD9, 0)? != 0 {
287303
return Err(Error::RegisterReadError);
288304
}
289305
self.read_data(&mut csd.data)?;
290306
Ok(Csd::V2(csd))
291307
}
292-
CardType::Unknown => Err(Error::CardNotFound),
308+
None => Err(Error::CardNotFound),
293309
}
294310
}
295311

@@ -353,7 +369,7 @@ where
353369

354370
/// Check the card is initialised.
355371
fn check_init(&mut self) -> Result<(), Error> {
356-
if self.card_type == CardType::Unknown {
372+
if self.card_type.is_none() {
357373
// If we don't know what the card type is, try and initialise the
358374
// card. This will tell us what type of card it is.
359375
self.acquire()
@@ -444,14 +460,14 @@ where
444460
return Err(Error::Cmd58Error);
445461
}
446462
if (s.receive()? & 0xC0) == 0xC0 {
447-
card_type = CardType::Sdhc;
463+
card_type = CardType::SDHC;
448464
}
449465
// Discard other three bytes
450466
s.receive()?;
451467
s.receive()?;
452468
s.receive()?;
453469
}
454-
s.card_type = card_type;
470+
s.card_type = Some(card_type);
455471
Ok(())
456472
};
457473
let result = f(self);
@@ -597,12 +613,20 @@ pub enum Error {
597613

598614
/// The different types of card we support.
599615
#[cfg_attr(feature = "defmt-log", derive(defmt::Format))]
600-
#[derive(Debug, Copy, Clone, PartialEq)]
601-
enum CardType {
602-
Unknown,
616+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
617+
pub enum CardType {
618+
/// An standard-capacity SD Card supporting v1.x of the standard.
619+
///
620+
/// Uses byte-addressing internally, so limited to 2GiB in size.
603621
SD1,
622+
/// An standard-capacity SD Card supporting v2.x of the standard.
623+
///
624+
/// Uses byte-addressing internally, so limited to 2GiB in size.
604625
SD2,
605-
Sdhc,
626+
/// An high-capacity 'SDHC' Card.
627+
///
628+
/// Uses block-addressing internally to support capacities above 2GiB.
629+
SDHC,
606630
}
607631

608632
/// A terrible hack for busy-waiting the CPU while we wait for the card to

0 commit comments

Comments
 (0)