1use super::sdmmc_proto::*;
9use super::{Block, BlockCount, BlockDevice, BlockIdx};
10use core::cell::RefCell;
11use nb::block;
12
13const DEFAULT_DELAY_COUNT: u32 = 32_000;
14
15pub struct SdMmcSpi<SPI, CS>
19where
20 SPI: embedded_hal::spi::FullDuplex<u8>,
21 CS: embedded_hal::digital::v2::OutputPin,
22 <SPI as embedded_hal::spi::FullDuplex<u8>>::Error: core::fmt::Debug,
23{
24 spi: RefCell<SPI>,
25 cs: RefCell<CS>,
26 card_type: CardType,
27 state: State,
28}
29
30#[derive(Debug, Copy, Clone)]
32pub enum Error {
33 Transport,
35 CantEnableCRC,
37 TimeoutReadBuffer,
39 TimeoutWaitNotBusy,
41 TimeoutCommand(u8),
43 TimeoutACommand(u8),
45 Cmd58Error,
47 RegisterReadError,
49 CrcError(u16, u16),
51 ReadError,
53 WriteError,
55 BadState,
57 CardNotFound,
59 GpioError,
61}
62
63#[derive(Debug, Copy, Clone, PartialEq, Eq)]
65pub enum State {
66 NoInit,
67 Error,
68 Idle,
69}
70
71#[derive(Debug, Copy, Clone, PartialEq)]
73enum CardType {
74 SD1,
75 SD2,
76 SDHC,
77}
78
79struct Delay(u32);
84
85impl Delay {
86 fn new() -> Delay {
87 Delay(DEFAULT_DELAY_COUNT)
88 }
89
90 fn delay(&mut self, err: Error) -> Result<(), Error> {
91 if self.0 == 0 {
92 Err(err)
93 } else {
94 let dummy_var: u32 = 0;
95 for _ in 0..100 {
96 unsafe { core::ptr::read_volatile(&dummy_var) };
97 }
98 self.0 -= 1;
99 Ok(())
100 }
101 }
102}
103
104impl<SPI, CS> SdMmcSpi<SPI, CS>
105where
106 SPI: embedded_hal::spi::FullDuplex<u8>,
107 CS: embedded_hal::digital::v2::OutputPin,
108 <SPI as embedded_hal::spi::FullDuplex<u8>>::Error: core::fmt::Debug,
109{
110 pub fn new(spi: SPI, cs: CS) -> SdMmcSpi<SPI, CS> {
112 SdMmcSpi {
113 spi: RefCell::new(spi),
114 cs: RefCell::new(cs),
115 card_type: CardType::SD1,
116 state: State::NoInit,
117 }
118 }
119
120 pub fn spi(&mut self) -> core::cell::RefMut<SPI> {
123 self.spi.borrow_mut()
124 }
125
126 fn cs_high(&self) -> Result<(), Error> {
127 self.cs
128 .borrow_mut()
129 .set_high()
130 .map_err(|_| Error::GpioError)
131 }
132
133 fn cs_low(&self) -> Result<(), Error> {
134 self.cs.borrow_mut().set_low().map_err(|_| Error::GpioError)
135 }
136
137 pub fn init(&mut self) -> Result<(), Error> {
140 let f = |s: &mut Self| {
141 s.state = State::Error;
143 s.cs_high()?;
145 for _ in 0..10 {
146 s.send(0xFF)?;
147 }
148 s.cs_low()?;
150 let mut attempts = 32;
152 while attempts > 0 {
153 match s.card_command(CMD0, 0) {
154 Err(Error::TimeoutCommand(0)) => {
155 attempts -= 1;
157 }
158 Err(e) => {
159 return Err(e);
160 }
161 Ok(R1_IDLE_STATE) => {
162 break;
163 }
164 Ok(_) => {
165 }
167 }
168 }
169 if attempts == 0 {
170 return Err(Error::CardNotFound);
171 }
172 if s.card_command(CMD59, 1)? != R1_IDLE_STATE {
174 return Err(Error::CantEnableCRC);
175 }
176 let mut delay = Delay::new();
178 loop {
179 if s.card_command(CMD8, 0x1AA)? == (R1_ILLEGAL_COMMAND | R1_IDLE_STATE) {
180 s.card_type = CardType::SD1;
181 break;
182 }
183 s.receive()?;
184 s.receive()?;
185 s.receive()?;
186 let status = s.receive()?;
187 if status == 0xAA {
188 s.card_type = CardType::SD2;
189 break;
190 }
191 delay.delay(Error::TimeoutCommand(CMD8))?;
192 }
193
194 let arg = match s.card_type {
195 CardType::SD1 => 0,
196 CardType::SD2 | CardType::SDHC => 0x4000_0000,
197 };
198
199 let mut delay = Delay::new();
200 while s.card_acmd(ACMD41, arg)? != R1_READY_STATE {
201 delay.delay(Error::TimeoutACommand(ACMD41))?;
202 }
203
204 if s.card_type == CardType::SD2 {
205 if s.card_command(CMD58, 0)? != 0 {
206 return Err(Error::Cmd58Error);
207 }
208 if (s.receive()? & 0xC0) == 0xC0 {
209 s.card_type = CardType::SDHC;
210 }
211 s.receive()?;
213 s.receive()?;
214 s.receive()?;
215 }
216 s.state = State::Idle;
217 Ok(())
218 };
219 let result = f(self);
220 self.cs_high()?;
221 let _ = self.receive();
222 result
223 }
224
225 pub fn deinit(&mut self) {
227 self.state = State::NoInit;
228 }
229
230 pub fn card_size_bytes(&self) -> Result<u64, Error> {
232 self.check_state()?;
233 self.with_chip_select(|s| {
234 let csd = s.read_csd()?;
235 match csd {
236 Csd::V1(ref contents) => Ok(contents.card_capacity_bytes()),
237 Csd::V2(ref contents) => Ok(contents.card_capacity_bytes()),
238 }
239 })
240 }
241
242 pub fn erase(&mut self, _first_block: BlockIdx, _last_block: BlockIdx) -> Result<(), Error> {
244 self.check_state()?;
245 unimplemented!();
246 }
247
248 pub fn erase_single_block_enabled(&self) -> Result<bool, Error> {
250 self.check_state()?;
251 self.with_chip_select(|s| {
252 let csd = s.read_csd()?;
253 match csd {
254 Csd::V1(ref contents) => Ok(contents.erase_single_block_enabled()),
255 Csd::V2(ref contents) => Ok(contents.erase_single_block_enabled()),
256 }
257 })
258 }
259
260 fn check_state(&self) -> Result<(), Error> {
263 if self.state != State::Idle {
264 Err(Error::BadState)
265 } else {
266 Ok(())
267 }
268 }
269
270 fn with_chip_select_mut<F, T>(&self, func: F) -> Result<T, Error>
273 where
274 F: FnOnce(&Self) -> Result<T, Error>,
275 {
276 self.cs_low()?;
277 let result = func(self);
278 self.cs_high()?;
279 result
280 }
281
282 fn with_chip_select<F, T>(&self, func: F) -> Result<T, Error>
285 where
286 F: FnOnce(&Self) -> Result<T, Error>,
287 {
288 self.cs_low()?;
289 let result = func(self);
290 self.cs_high()?;
291 result
292 }
293
294 fn read_csd(&self) -> Result<Csd, Error> {
296 match self.card_type {
297 CardType::SD1 => {
298 let mut csd = CsdV1::new();
299 if self.card_command(CMD9, 0)? != 0 {
300 return Err(Error::RegisterReadError);
301 }
302 self.read_data(&mut csd.data)?;
303 Ok(Csd::V1(csd))
304 }
305 CardType::SD2 | CardType::SDHC => {
306 let mut csd = CsdV2::new();
307 if self.card_command(CMD9, 0)? != 0 {
308 return Err(Error::RegisterReadError);
309 }
310 self.read_data(&mut csd.data)?;
311 Ok(Csd::V2(csd))
312 }
313 }
314 }
315
316 fn read_data(&self, buffer: &mut [u8]) -> Result<(), Error> {
319 let mut delay = Delay::new();
321 let status = loop {
322 let s = self.receive()?;
323 if s != 0xFF {
324 break s;
325 }
326 delay.delay(Error::TimeoutReadBuffer)?;
327 };
328 if status != DATA_START_BLOCK {
329 return Err(Error::ReadError);
330 }
331
332 for b in buffer.iter_mut() {
333 *b = self.receive()?;
334 }
335
336 let mut crc = u16::from(self.receive()?);
337 crc <<= 8;
338 crc |= u16::from(self.receive()?);
339
340 let calc_crc = crc16(buffer);
341 if crc != calc_crc {
342 return Err(Error::CrcError(crc, calc_crc));
343 }
344
345 Ok(())
346 }
347
348 fn write_data(&self, token: u8, buffer: &[u8]) -> Result<(), Error> {
350 let calc_crc = crc16(buffer);
351 self.send(token)?;
352 for &b in buffer.iter() {
353 self.send(b)?;
354 }
355 self.send((calc_crc >> 8) as u8)?;
356 self.send(calc_crc as u8)?;
357 let status = self.receive()?;
358 if (status & DATA_RES_MASK) != DATA_RES_ACCEPTED {
359 Err(Error::WriteError)
360 } else {
361 Ok(())
362 }
363 }
364
365 fn card_acmd(&self, command: u8, arg: u32) -> Result<u8, Error> {
367 self.card_command(CMD55, 0)?;
368 self.card_command(command, arg)
369 }
370
371 fn card_command(&self, command: u8, arg: u32) -> Result<u8, Error> {
373 self.wait_not_busy()?;
374 let mut buf = [
375 0x40 | command,
376 (arg >> 24) as u8,
377 (arg >> 16) as u8,
378 (arg >> 8) as u8,
379 arg as u8,
380 0,
381 ];
382 buf[5] = crc7(&buf[0..5]);
383
384 for b in buf.iter() {
385 self.send(*b)?;
386 }
387
388 if command == CMD12 {
390 let _result = self.receive()?;
391 }
392
393 for _ in 0..512 {
394 let result = self.receive()?;
395 if (result & 0x80) == 0 {
396 return Ok(result);
397 }
398 }
399
400 Err(Error::TimeoutCommand(command))
401 }
402
403 fn receive(&self) -> Result<u8, Error> {
405 self.transfer(0xFF)
406 }
407
408 fn send(&self, out: u8) -> Result<(), Error> {
410 let _ = self.transfer(out)?;
411 Ok(())
412 }
413
414 fn transfer(&self, out: u8) -> Result<u8, Error> {
416 let mut spi = self.spi.borrow_mut();
417 block!(spi.send(out)).map_err(|_e| Error::Transport)?;
418 block!(spi.read()).map_err(|_e| Error::Transport)
419 }
420
421 fn wait_not_busy(&self) -> Result<(), Error> {
424 let mut delay = Delay::new();
425 loop {
426 let s = self.receive()?;
427 if s == 0xFF {
428 break;
429 }
430 delay.delay(Error::TimeoutWaitNotBusy)?;
431 }
432 Ok(())
433 }
434}
435
436impl<SPI, CS> BlockDevice for SdMmcSpi<SPI, CS>
437where
438 SPI: embedded_hal::spi::FullDuplex<u8>,
439 <SPI as embedded_hal::spi::FullDuplex<u8>>::Error: core::fmt::Debug,
440 CS: embedded_hal::digital::v2::OutputPin,
441{
442 type Error = Error;
443
444 fn read(
446 &self,
447 blocks: &mut [Block],
448 start_block_idx: BlockIdx,
449 _reason: &str,
450 ) -> Result<(), Self::Error> {
451 self.check_state()?;
452 let start_idx = match self.card_type {
453 CardType::SD1 | CardType::SD2 => start_block_idx.0 * 512,
454 CardType::SDHC => start_block_idx.0,
455 };
456 self.with_chip_select(|s| {
457 if blocks.len() == 1 {
458 s.card_command(CMD17, start_idx)?;
460 s.read_data(&mut blocks[0].contents)?;
461 } else {
462 s.card_command(CMD18, start_idx)?;
464 for block in blocks.iter_mut() {
465 s.read_data(&mut block.contents)?;
466 }
467 s.card_command(CMD12, 0)?;
469 }
470 Ok(())
471 })
472 }
473
474 fn write(&self, blocks: &[Block], start_block_idx: BlockIdx) -> Result<(), Self::Error> {
476 self.check_state()?;
477 let start_idx = match self.card_type {
478 CardType::SD1 | CardType::SD2 => start_block_idx.0 * 512,
479 CardType::SDHC => start_block_idx.0,
480 };
481 self.with_chip_select_mut(|s| {
482 if blocks.len() == 1 {
483 s.card_command(CMD24, start_idx)?;
485 s.write_data(DATA_START_BLOCK, &blocks[0].contents)?;
486 s.wait_not_busy()?;
487 if s.card_command(CMD13, 0)? != 0x00 {
488 return Err(Error::WriteError);
489 }
490 if s.receive()? != 0x00 {
491 return Err(Error::WriteError);
492 }
493 } else {
494 s.card_command(CMD25, start_idx)?;
496 for block in blocks.iter() {
497 s.wait_not_busy()?;
498 s.write_data(WRITE_MULTIPLE_TOKEN, &block.contents)?;
499 }
500 s.wait_not_busy()?;
502 s.send(STOP_TRAN_TOKEN)?;
503 }
504 Ok(())
505 })
506 }
507
508 fn num_blocks(&self) -> Result<BlockCount, Self::Error> {
510 let num_bytes = self.card_size_bytes()?;
511 let num_blocks = (num_bytes / 512) as u32;
512 Ok(BlockCount(num_blocks))
513 }
514}
515
516