capsules_extra/sdcard.rs
1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Provides driver for accessing an SD Card and a userspace Driver.
6//!
7//! This allows initialization and block reads or writes on top of SPI.
8//!
9//! Usage
10//! -----
11//!
12//! ```rust,ignore
13//! # use kernel::static_init;
14//! # use capsules::virtual_alarm::VirtualMuxAlarm;
15//! # use kernel::hil::spi::SpiMasterDevice;
16//!
17//! let spi_mux = components::spi::SpiMuxComponent::new(
18//! &base_peripherals.spim0,
19//! dynamic_deferred_caller
20//! ).finalize(components::spi_mux_component_helper!(nrf52833::spi::SPIM));
21//! base_peripherals.spim0.configure(
22//! nrf52833::pinmux::Pinmux::new(SPI_MOSI_PIN as u32), // SD MOSI
23//! nrf52833::pinmux::Pinmux::new(SPI_MISO_PIN as u32), // SD MISO
24//! nrf52833::pinmux::Pinmux::new(SPI_SCK_PIN as u32), // SD SCK
25//! );
26//!
27//! let sdcard_spi = components::spi::SpiComponent::new(
28//! spi_mux,
29//! &nrf52833_peripherals.gpio_port[SPI_CS_PIN]
30//! ).finalize(components::spi_component_helper!(nrf52833::spi::SPIM));
31//!
32//! let sdcard_virtual_alarm = static_init!(
33//! capsules::virtual_alarm::VirtualMuxAlarm<'static, nrf52833::rtc::Rtc>,
34//! capsules::virtual_alarm::VirtualMuxAlarm::new(mux_alarm));
35//! sdcard_virtual_alarm.setup();
36//!
37//! let sdcard_tx_buffer = static_init!([u8; capsules::sdcard::TXRX_BUFFER_LENGTH],
38//! [0; capsules::sdcard::TXRX_BUFFER_LENGTH]);
39//! let sdcard_rx_buffer = static_init!([u8; capsules::sdcard::TXRX_BUFFER_LENGTH],
40//! [0; capsules::sdcard::TXRX_BUFFER_LENGTH]);
41//!
42//! let sdcard = static_init!(
43//! capsules::sdcard::SDCard<
44//! 'static,
45//! capsules::virtual_alarm::VirtualMuxAlarm<'static, nrf52833::rtc::Rtc>>,
46//! capsules::sdcard::SDCard::new(sdcard_spi,
47//! sdcard_virtual_alarm,
48//! Some(&SD_DETECT_PIN),
49//! sdcard_tx_buffer,
50//! sdcard_rx_buffer));
51//! sdcard_spi.set_client(sdcard);
52//! sdcard_virtual_alarm.set_alarm_client(sdcard);
53//! SD_DETECT_PIN.set_client(sdcard);
54//!
55//! let sdcard_kernel_buffer = static_init!([u8; capsules::sdcard::KERNEL_BUFFER_LENGTH],
56//! [0; capsules::sdcard::KERNEL_BUFFER_LENGTH]);
57//!
58//! let sdcard_driver = static_init!(
59//! capsules::sdcard::SDCardDriver<
60//! 'static,
61//! capsules::virtual_alarm::VirtualMuxAlarm<'static, nrf52833::rtc::Rtc>>,
62//! capsules::sdcard::SDCardDriver::new(
63//! sdcard,
64//! sdcard_kernel_buffer,
65//! board_kernel.create_grant(
66//! capsules::sdcard::DRIVER_NUM,
67//! &memory_allocation_capability)));
68//! sdcard.set_client(sdcard_driver);
69//! ```
70
71// Resources for SD Card API:
72// * elm-chan.org/docs/mmc/mmc_e.html
73// * alumni.cs.ucr.edu/~amitra/sdcard/Additional/sdcard_appnote_foust.pdf
74// * luckyresistor.me/cat-protector/software/sdcard-2/
75// * http://users.ece.utexas.edu/~valvano/EE345M/SD_Physical_Layer_Spec.pdf
76
77use core::cell::Cell;
78use core::cmp;
79
80use kernel::grant::{AllowRoCount, AllowRwCount, Grant, UpcallCount};
81use kernel::hil;
82use kernel::hil::time::ConvertTicks;
83use kernel::processbuffer::{ReadableProcessBuffer, WriteableProcessBuffer};
84use kernel::syscall::{CommandReturn, SyscallDriver};
85use kernel::utilities::cells::{OptionalCell, TakeCell};
86use kernel::utilities::leasable_buffer::SubSliceMut;
87use kernel::{ErrorCode, ProcessId};
88
89/// Syscall driver number.
90use capsules_core::driver;
91pub const DRIVER_NUM: usize = driver::NUM::SdCard as usize;
92
93/// Ids for read-only allow buffers
94mod ro_allow {
95 pub const WRITE: usize = 0;
96 /// The number of allow buffers the kernel stores for this grant
97 pub const COUNT: u8 = 1;
98}
99
100/// Ids for read-write allow buffers
101mod rw_allow {
102 pub const READ: usize = 0;
103 /// The number of allow buffers the kernel stores for this grant
104 pub const COUNT: u8 = 1;
105}
106
107/// Buffers used for SD card transactions, assigned in board `main.rs` files
108/// Constraints:
109///
110/// * RXBUFFER must be greater than or equal to TXBUFFER in length
111/// * Both RXBUFFER and TXBUFFER must be longer than the SD card's block size
112pub const TXRX_BUFFER_LENGTH: usize = 515;
113
114/// SD Card capsule, capable of being built on top of by other kernel capsules
115pub struct SDCard<'a, A: hil::time::Alarm<'a>> {
116 spi: &'a dyn hil::spi::SpiMasterDevice<'a>,
117 state: Cell<SpiState>,
118 after_state: Cell<SpiState>,
119
120 alarm: &'a A,
121 alarm_state: Cell<AlarmState>,
122 alarm_count: Cell<u8>,
123
124 is_initialized: Cell<bool>,
125 card_type: Cell<SDCardType>,
126
127 detect_pin: Cell<Option<&'a dyn hil::gpio::InterruptPin<'a>>>,
128
129 txbuffer: TakeCell<'static, [u8]>,
130 rxbuffer: TakeCell<'static, [u8]>,
131
132 client: OptionalCell<&'a dyn SDCardClient>,
133 client_buffer: TakeCell<'static, [u8]>,
134 client_offset: Cell<usize>,
135}
136
137/// SD card command codes
138#[allow(dead_code, non_camel_case_types)]
139#[derive(Clone, Copy, Debug, PartialEq)]
140enum SDCmd {
141 CMD0_Reset = 0, // Reset
142 CMD1_Init = 1, // Generic init
143 CMD8_CheckVoltage = 8, // Check voltage range
144 CMD9_ReadCSD = 9, // Read chip specific data (CSD) register
145 CMD12_StopRead = 12, // Stop multiple block read
146 CMD16_SetBlockSize = 16, // Set blocksize
147 CMD17_ReadSingle = 17, // Read single block
148 CMD18_ReadMultiple = 18, // Read multiple blocks
149 CMD24_WriteSingle = 24, // Write single block
150 CMD25_WriteMultiple = 25, // Write multiple blocks
151 CMD55_ManufSpecificCommand = 55, // Next command will be manufacturer specific
152 CMD58_ReadOCR = 58, // Read operation condition register (OCR)
153 ACMD41_ManufSpecificInit = 0x80 + 41, // Manufacturer specific Init
154}
155
156/// SD card response codes
157#[allow(dead_code, non_camel_case_types)]
158#[derive(Clone, Copy, Debug, PartialEq)]
159enum SDResponse {
160 R1_Status, // Status response, single byte
161 R2_ExtendedStatus, // Extended response, two bytes, unused in practice
162 R3_OCR, // OCR response, status + four bytes
163 R7_CheckVoltage, // Check voltage response, status + four bytes
164}
165
166/// SPI states
167#[derive(Clone, Copy, Debug, PartialEq)]
168enum SpiState {
169 Idle,
170
171 SendManufSpecificCmd { cmd: SDCmd, arg: u32 },
172
173 InitReset,
174 InitCheckVersion,
175 InitRepeatHCSInit,
176 InitCheckCapacity,
177 InitAppSpecificInit,
178 InitRepeatAppSpecificInit,
179 InitRepeatGenericInit,
180 InitSetBlocksize,
181 InitComplete,
182
183 StartReadBlocks { count: u32 },
184 WaitReadBlock,
185 ReadBlockComplete,
186 WaitReadBlocks { count: u32 },
187 ReceivedBlock { count: u32 },
188 ReadBlocksComplete,
189
190 StartWriteBlocks { count: u32 },
191 WriteBlockResponse,
192 WriteBlockBusy,
193 WaitWriteBlockBusy,
194}
195
196/// Alarm states
197#[derive(Clone, Copy, Debug, PartialEq)]
198enum AlarmState {
199 Idle,
200
201 DetectionChange,
202
203 RepeatHCSInit,
204 RepeatAppSpecificInit,
205 RepeatGenericInit,
206
207 WaitForDataBlock,
208 WaitForDataBlocks { count: u32 },
209
210 WaitForWriteBusy,
211}
212
213/// Error codes returned if an SD card transaction fails
214#[derive(Clone, Copy, Debug, PartialEq)]
215enum SdCardError {
216 CardStateChanged = -10001,
217 InitializationFailure = -10002,
218 ReadFailure = -10003,
219 WriteFailure = -10004,
220 TimeoutFailure = -10005,
221}
222
223/// SD card types, determined during initialization
224#[derive(Clone, Copy, Debug, PartialEq)]
225enum SDCardType {
226 Uninitialized = 0x00,
227 MMC = 0x01,
228 SDv1 = 0x02,
229 SDv2 = 0x04,
230 SDv2BlockAddressable = 0x04 | 0x08,
231}
232
233// Constants used in driver
234const SUCCESS_STATUS: u8 = 0x00;
235const INITIALIZING_STATUS: u8 = 0x01;
236const DATA_TOKEN: u8 = 0xFE;
237
238/// Callback functions from SDCard
239pub trait SDCardClient {
240 fn card_detection_changed(&self, installed: bool);
241 fn init_done(&self, block_size: u32, total_size: u64);
242 fn read_done(&self, data: &'static mut [u8], len: usize);
243 fn write_done(&self, buffer: &'static mut [u8]);
244 fn error(&self, error: u32);
245}
246
247/// Functions for initializing and accessing an SD card
248impl<'a, A: hil::time::Alarm<'a>> SDCard<'a, A> {
249 /// Create a new SD card interface
250 ///
251 /// spi - virtualized SPI to use for communication with SD card
252 /// alarm - virtualized Timer with a granularity of at least 1 ms
253 /// detect_pin - active low GPIO pin used to detect if an SD card is
254 /// installed
255 /// txbuffer - buffer for holding SPI write data, at least 515 bytes in
256 /// length
257 /// rxbuffer - buffer for holding SPI read data, at least 515 bytes in
258 /// length
259 pub fn new(
260 spi: &'a dyn hil::spi::SpiMasterDevice,
261 alarm: &'a A,
262 detect_pin: Option<&'static dyn hil::gpio::InterruptPin<'a>>,
263 txbuffer: &'static mut [u8; 515],
264 rxbuffer: &'static mut [u8; 515],
265 ) -> SDCard<'a, A> {
266 // initialize buffers
267 for byte in txbuffer.iter_mut() {
268 *byte = 0xFF;
269 }
270 for byte in rxbuffer.iter_mut() {
271 *byte = 0xFF;
272 }
273
274 // handle optional detect pin
275 let pin = detect_pin.inspect(|pin| {
276 pin.make_input();
277 });
278
279 // set up and return struct
280 SDCard {
281 spi,
282 state: Cell::new(SpiState::Idle),
283 after_state: Cell::new(SpiState::Idle),
284 alarm,
285 alarm_state: Cell::new(AlarmState::Idle),
286 alarm_count: Cell::new(0),
287 is_initialized: Cell::new(false),
288 card_type: Cell::new(SDCardType::Uninitialized),
289 detect_pin: Cell::new(pin),
290 txbuffer: TakeCell::new(txbuffer),
291 rxbuffer: TakeCell::new(rxbuffer),
292 client: OptionalCell::empty(),
293 client_buffer: TakeCell::empty(),
294 client_offset: Cell::new(0),
295 }
296 }
297
298 fn set_spi_slow_mode(&self) -> Result<(), ErrorCode> {
299 // need to be in slow mode while initializing the SD card
300 // set to CPHA=0, CPOL=0, 400 kHZ
301 self.spi.configure(
302 hil::spi::ClockPolarity::IdleLow,
303 hil::spi::ClockPhase::SampleLeading,
304 400000,
305 )
306 }
307
308 fn set_spi_fast_mode(&self) -> Result<(), ErrorCode> {
309 // can read/write in fast mode after the SD card is initialized
310 // set to CPHA=0, CPOL=0, 4 MHz
311 self.spi.configure(
312 hil::spi::ClockPolarity::IdleLow,
313 hil::spi::ClockPhase::SampleLeading,
314 4000000,
315 )
316 }
317
318 /// send a command over SPI and collect the response
319 /// Handles encoding of command, checksum, and padding bytes. The response
320 /// still needs to be parsed out of the read_buffer when complete
321 fn send_command(
322 &self,
323 cmd: SDCmd,
324 arg: u32,
325 write_buffer: &'static mut [u8],
326 read_buffer: &'static mut [u8],
327 recv_len: usize,
328 ) {
329 // Note: a good default recv_len is 10 bytes. Reading too many bytes
330 // rarely matters. However, it occasionally matters a lot, so we
331 // provide a settable recv_len
332
333 if self.is_initialized() {
334 // device is already initialized
335 // TODO verify SPI return value
336 let _ = self.set_spi_fast_mode();
337 } else {
338 // device is still being initialized
339 // TODO verify SPI return value
340 let _ = self.set_spi_slow_mode();
341 }
342
343 // send dummy bytes to start
344 write_buffer[0] = 0xFF;
345 write_buffer[1] = 0xFF;
346
347 // command
348 if (0x80 & cmd as u8) != 0x00 {
349 // application-specific command
350 write_buffer[2] = 0x40 | (0x7F & cmd as u8);
351 } else {
352 // normal command
353 write_buffer[2] = 0x40 | cmd as u8;
354 }
355
356 // argument, MSB first
357 write_buffer[3] = ((arg >> 24) & 0xFF) as u8;
358 write_buffer[4] = ((arg >> 16) & 0xFF) as u8;
359 write_buffer[5] = ((arg >> 8) & 0xFF) as u8;
360 write_buffer[6] = ((arg >> 0) & 0xFF) as u8;
361
362 // CRC is ignored except for CMD0 and maybe CMD8
363 // Established practice it to just always use the CMD0 CRC unless we
364 // are sending a CMD8
365 if cmd == SDCmd::CMD8_CheckVoltage {
366 write_buffer[7] = 0x87; // valid crc for CMD8(0x1AA)
367 } else {
368 write_buffer[7] = 0x95; // valid crc for CMD0
369 }
370
371 // append dummy bytes to transmission after command bytes
372 // Limit to minimum length between write_buffer and recv_len
373 for byte in write_buffer.iter_mut().skip(8).take(recv_len) {
374 *byte = 0xFF;
375 }
376
377 // Length is command bytes (8) plus recv_len
378 let len = cmp::min(
379 cmp::min(8 + recv_len, write_buffer.len()),
380 read_buffer.len(),
381 );
382
383 let mut wb: SubSliceMut<'static, u8> = write_buffer.into();
384 wb.slice(0..len);
385 let mut rb: SubSliceMut<'static, u8> = read_buffer.into();
386 rb.slice(0..len);
387
388 // start SPI transaction
389 let _ = self.spi.read_write_bytes(wb, Some(rb));
390 }
391
392 /// wrapper for easy reading of bytes over SPI
393 fn read_bytes(
394 &self,
395 write_buffer: &'static mut [u8],
396 read_buffer: &'static mut [u8],
397 recv_len: usize,
398 ) {
399 // TODO verify SPI return value
400 let _ = self.set_spi_fast_mode();
401
402 // set write buffer to null transactions
403 // Limit to minimum length between write_buffer and recv_len.
404 // Note: this could be optimized in the future by allowing SPI to read
405 // without a write buffer passed in
406 for byte in write_buffer.iter_mut().take(recv_len) {
407 *byte = 0xFF;
408 }
409
410 let mut wb: SubSliceMut<'static, u8> = write_buffer.into();
411 wb.slice(0..recv_len);
412 let mut rb: SubSliceMut<'static, u8> = read_buffer.into();
413 rb.slice(0..recv_len);
414
415 let _ = self.spi.read_write_bytes(wb, Some(rb));
416 }
417
418 /// wrapper for easy writing of bytes over SPI
419 fn write_bytes(
420 &self,
421 write_buffer: &'static mut [u8],
422 read_buffer: &'static mut [u8],
423 recv_len: usize,
424 ) {
425 // TODO verify SPI return value
426 let _ = self.set_spi_fast_mode();
427
428 let mut wb: SubSliceMut<'static, u8> = write_buffer.into();
429 wb.slice(0..recv_len);
430 let mut rb: SubSliceMut<'static, u8> = read_buffer.into();
431 rb.slice(0..recv_len);
432
433 let _ = self.spi.read_write_bytes(wb, Some(rb));
434 }
435
436 /// parse response bytes from SPI read buffer
437 /// Unfortunately there is a variable amount of delay in SD card responses,
438 /// so these bytes must be searched for
439 fn get_response(&self, response: SDResponse, read_buffer: &[u8]) -> (u8, u8, u32) {
440 let mut r1: u8 = 0xFF;
441 let mut r2: u8 = 0xFF;
442 let mut r3: u32 = 0xFFFFFFFF;
443
444 // scan through read buffer for response byte
445 for (i, &byte) in read_buffer.iter().enumerate() {
446 if (byte & 0x80) == 0x00 {
447 // status byte is always included
448 r1 = byte;
449
450 match response {
451 SDResponse::R2_ExtendedStatus => {
452 // status, then read/write status. Unused in practice
453 if i + 1 < read_buffer.len() {
454 r2 = read_buffer[i + 1];
455 }
456 }
457 SDResponse::R3_OCR | SDResponse::R7_CheckVoltage => {
458 // status, then Operating Condition Register
459 if i + 4 < read_buffer.len() {
460 r3 = (read_buffer[i + 1] as u32) << 24
461 | (read_buffer[i + 2] as u32) << 16
462 | (read_buffer[i + 3] as u32) << 8
463 | (read_buffer[i + 4] as u32);
464 }
465 }
466 _ => {
467 // R1, no bytes left to parse
468 }
469 }
470
471 // response found
472 break;
473 }
474 }
475
476 // return a tuple of the parsed bytes
477 (r1, r2, r3)
478 }
479
480 /// updates SD card state on SPI transaction returns
481 fn process_spi_states(
482 &self,
483 write_buffer: &'static mut [u8],
484 read_buffer: &'static mut [u8],
485 _: usize,
486 ) {
487 match self.state.get() {
488 SpiState::SendManufSpecificCmd { cmd, arg } => {
489 // send the application-specific command and resume the state
490 // machine
491 self.state.set(self.after_state.get());
492 self.after_state.set(SpiState::Idle);
493 self.send_command(cmd, arg, write_buffer, read_buffer, 10);
494 }
495
496 SpiState::InitReset => {
497 // check response
498 let (r1, _, _) = self.get_response(SDResponse::R1_Status, read_buffer);
499
500 // only continue if we are in idle state
501 if r1 == INITIALIZING_STATUS {
502 // next send Check Voltage Range command that is only valid
503 // on SDv2 cards. This is used to check which SD card
504 // version is installed. Note that 0xAA is an arbitrary
505 // check pattern that will be duplicated in the response
506 // and 0x100 specifies that the card is running between
507 // 2.7 and 3.6 volts
508 self.state.set(SpiState::InitCheckVersion);
509 self.send_command(
510 SDCmd::CMD8_CheckVoltage,
511 0x1AA,
512 write_buffer,
513 read_buffer,
514 10,
515 );
516 } else {
517 // error, send callback and quit
518 self.txbuffer.replace(write_buffer);
519 self.rxbuffer.replace(read_buffer);
520 self.state.set(SpiState::Idle);
521 self.alarm_state.set(AlarmState::Idle);
522 self.alarm_count.set(0);
523 self.client.map(move |client| {
524 client.error(SdCardError::InitializationFailure as u32);
525 });
526 }
527 }
528
529 SpiState::InitCheckVersion => {
530 // check response
531 let (r1, _, r7) = self.get_response(SDResponse::R7_CheckVoltage, read_buffer);
532
533 // look for test pattern duplicated in R7
534 if r1 == INITIALIZING_STATUS && r7 == 0x1AA {
535 // we have an SDv2 card
536 // send application-specific initialization in high capacity mode (HCS)
537 self.state.set(SpiState::SendManufSpecificCmd {
538 cmd: SDCmd::ACMD41_ManufSpecificInit,
539 arg: 0x40000000,
540 });
541 self.after_state.set(SpiState::InitRepeatHCSInit);
542 self.send_command(
543 SDCmd::CMD55_ManufSpecificCommand,
544 0x0,
545 write_buffer,
546 read_buffer,
547 10,
548 );
549 } else {
550 // we have either an SDv1 or MMCv3 card
551 // send application-specific initialization
552 self.state.set(SpiState::SendManufSpecificCmd {
553 cmd: SDCmd::ACMD41_ManufSpecificInit,
554 arg: 0x0,
555 });
556 self.after_state.set(SpiState::InitAppSpecificInit);
557 self.send_command(
558 SDCmd::CMD55_ManufSpecificCommand,
559 0x0,
560 write_buffer,
561 read_buffer,
562 10,
563 );
564 }
565 }
566
567 SpiState::InitRepeatHCSInit => {
568 // check response
569 let (r1, _, _) = self.get_response(SDResponse::R1_Status, read_buffer);
570
571 if r1 == SUCCESS_STATUS {
572 // card initialized
573 // check card capacity
574 self.alarm_count.set(0);
575 self.state.set(SpiState::InitCheckCapacity);
576 self.send_command(SDCmd::CMD58_ReadOCR, 0x0, write_buffer, read_buffer, 10);
577 } else if r1 == INITIALIZING_STATUS {
578 // replace buffers
579 self.txbuffer.replace(write_buffer);
580 self.rxbuffer.replace(read_buffer);
581
582 // try again after 10 ms
583 self.alarm_state.set(AlarmState::RepeatHCSInit);
584 let delay = self.alarm.ticks_from_ms(10);
585 self.alarm.set_alarm(self.alarm.now(), delay);
586 } else {
587 // error, send callback and quit
588 self.txbuffer.replace(write_buffer);
589 self.rxbuffer.replace(read_buffer);
590 self.state.set(SpiState::Idle);
591 self.alarm_state.set(AlarmState::Idle);
592 self.alarm_count.set(0);
593 self.client.map(move |client| {
594 client.error(SdCardError::InitializationFailure as u32);
595 });
596 }
597 }
598
599 SpiState::InitCheckCapacity => {
600 // check response
601 let (r1, _, r7) = self.get_response(SDResponse::R3_OCR, read_buffer);
602
603 if r1 == SUCCESS_STATUS {
604 if (r7 & 0x40000000) != 0x00000000 {
605 self.card_type.set(SDCardType::SDv2BlockAddressable);
606 } else {
607 self.card_type.set(SDCardType::SDv2);
608 }
609
610 // Read CSD register
611 // Note that the receive length needs to be increased here
612 // to capture the 16-byte register (plus some slack)
613 self.state.set(SpiState::InitComplete);
614 self.send_command(SDCmd::CMD9_ReadCSD, 0x0, write_buffer, read_buffer, 28);
615 } else {
616 // error, send callback and quit
617 self.txbuffer.replace(write_buffer);
618 self.rxbuffer.replace(read_buffer);
619 self.state.set(SpiState::Idle);
620 self.alarm_state.set(AlarmState::Idle);
621 self.alarm_count.set(0);
622 self.client.map(move |client| {
623 client.error(SdCardError::InitializationFailure as u32);
624 });
625 }
626 }
627
628 SpiState::InitAppSpecificInit => {
629 // check response
630 let (r1, _, _) = self.get_response(SDResponse::R1_Status, read_buffer);
631
632 if r1 == INITIALIZING_STATUS || r1 == SUCCESS_STATUS {
633 // SDv1 card
634 // send application-specific initialization
635 self.card_type.set(SDCardType::SDv1);
636 self.state.set(SpiState::SendManufSpecificCmd {
637 cmd: SDCmd::ACMD41_ManufSpecificInit,
638 arg: 0x0,
639 });
640 self.after_state.set(SpiState::InitRepeatAppSpecificInit);
641 self.send_command(
642 SDCmd::CMD55_ManufSpecificCommand,
643 0x0,
644 write_buffer,
645 read_buffer,
646 10,
647 );
648 } else {
649 // MMCv3 card
650 // send generic intialization
651 self.card_type.set(SDCardType::MMC);
652 self.state.set(SpiState::InitRepeatGenericInit);
653 self.send_command(SDCmd::CMD1_Init, 0x0, write_buffer, read_buffer, 10);
654 }
655 }
656
657 SpiState::InitRepeatAppSpecificInit => {
658 // check response
659 let (r1, _, _) = self.get_response(SDResponse::R1_Status, read_buffer);
660
661 if r1 == SUCCESS_STATUS {
662 // card initialized
663 // set blocksize to 512
664 self.alarm_count.set(0);
665 self.state.set(SpiState::InitSetBlocksize);
666 self.send_command(
667 SDCmd::CMD16_SetBlockSize,
668 512,
669 write_buffer,
670 read_buffer,
671 10,
672 );
673 } else if r1 == INITIALIZING_STATUS {
674 // replace buffers
675 self.txbuffer.replace(write_buffer);
676 self.rxbuffer.replace(read_buffer);
677
678 // try again after 10 ms
679 self.alarm_state.set(AlarmState::RepeatAppSpecificInit);
680 let delay = self.alarm.ticks_from_ms(10);
681 self.alarm.set_alarm(self.alarm.now(), delay);
682 } else {
683 // error, send callback and quit
684 self.txbuffer.replace(write_buffer);
685 self.rxbuffer.replace(read_buffer);
686 self.state.set(SpiState::Idle);
687 self.alarm_state.set(AlarmState::Idle);
688 self.alarm_count.set(0);
689 self.client.map(move |client| {
690 client.error(SdCardError::InitializationFailure as u32);
691 });
692 }
693 }
694
695 SpiState::InitRepeatGenericInit => {
696 // check response
697 let (r1, _, _) = self.get_response(SDResponse::R1_Status, read_buffer);
698
699 if r1 == SUCCESS_STATUS {
700 // card initialized
701 // set blocksize to 512
702 self.alarm_count.set(0);
703 self.state.set(SpiState::InitSetBlocksize);
704 self.send_command(
705 SDCmd::CMD16_SetBlockSize,
706 512,
707 write_buffer,
708 read_buffer,
709 10,
710 );
711 } else if r1 == INITIALIZING_STATUS {
712 // replace buffers
713 self.txbuffer.replace(write_buffer);
714 self.rxbuffer.replace(read_buffer);
715
716 // try again after 10 ms
717 self.alarm_state.set(AlarmState::RepeatGenericInit);
718 let delay = self.alarm.ticks_from_ms(10);
719 self.alarm.set_alarm(self.alarm.now(), delay);
720 } else {
721 // error, send callback and quit
722 self.txbuffer.replace(write_buffer);
723 self.rxbuffer.replace(read_buffer);
724 self.state.set(SpiState::Idle);
725 self.alarm_state.set(AlarmState::Idle);
726 self.alarm_count.set(0);
727 self.client.map(move |client| {
728 client.error(SdCardError::InitializationFailure as u32);
729 });
730 }
731 }
732
733 SpiState::InitSetBlocksize => {
734 // check response
735 let (r1, _, _) = self.get_response(SDResponse::R1_Status, read_buffer);
736
737 if r1 == SUCCESS_STATUS {
738 // Read CSD register
739 // Note that the receive length needs to be increased here
740 // to capture the 16-byte register (plus some slack)
741 self.state.set(SpiState::InitComplete);
742 self.send_command(SDCmd::CMD9_ReadCSD, 0x0, write_buffer, read_buffer, 28);
743 } else {
744 // error, send callback and quit
745 self.txbuffer.replace(write_buffer);
746 self.rxbuffer.replace(read_buffer);
747 self.state.set(SpiState::Idle);
748 self.alarm_state.set(AlarmState::Idle);
749 self.alarm_count.set(0);
750 self.client.map(move |client| {
751 client.error(SdCardError::InitializationFailure as u32);
752 });
753 }
754 }
755
756 SpiState::InitComplete => {
757 // check response
758 let (r1, _, _) = self.get_response(SDResponse::R1_Status, read_buffer);
759
760 if r1 == SUCCESS_STATUS {
761 let mut total_size: u64 = 0;
762
763 // find CSD register value
764 // Slide through 12-byte windows searching for beginning of
765 // the CSD register
766 for buf in read_buffer.windows(12) {
767 if buf[0] == DATA_TOKEN {
768 // get total size from CSD
769 if (buf[1] & 0xC0) == 0x00 {
770 // CSD version 1.0
771 let c_size = (((buf[7] & 0x03) as u32) << 10)
772 | (((buf[8] & 0xFF) as u32) << 2)
773 | (((buf[9] & 0xC0) as u32) >> 6);
774 let c_size_mult = (((buf[10] & 0x03) as u32) << 1)
775 | (((buf[11] & 0x80) as u32) >> 7);
776 let read_bl_len = (buf[6] & 0x0F) as u32;
777
778 let block_count = (c_size + 1) * (1 << (c_size_mult + 2));
779 let block_len = 1 << read_bl_len;
780 total_size = block_count as u64 * block_len as u64;
781 } else {
782 // CSD version 2.0
783 let c_size = (((buf[8] & 0x3F) as u32) << 16)
784 | (((buf[9] & 0xFF) as u32) << 8)
785 | ((buf[10] & 0xFF) as u32);
786 total_size = ((c_size as u64) + 1) * 512 * 1024;
787 }
788
789 break;
790 }
791 }
792
793 // replace buffers
794 self.txbuffer.replace(write_buffer);
795 self.rxbuffer.replace(read_buffer);
796
797 // initialization complete
798 self.state.set(SpiState::Idle);
799 self.is_initialized.set(true);
800
801 // perform callback
802 self.client.map(move |client| {
803 client.init_done(512, total_size);
804 });
805 } else {
806 // error, send callback and quit
807 self.txbuffer.replace(write_buffer);
808 self.rxbuffer.replace(read_buffer);
809 self.state.set(SpiState::Idle);
810 self.alarm_state.set(AlarmState::Idle);
811 self.alarm_count.set(0);
812 self.client.map(move |client| {
813 client.error(SdCardError::InitializationFailure as u32);
814 });
815 }
816 }
817
818 SpiState::StartReadBlocks { count } => {
819 // check response
820 let (r1, _, _) = self.get_response(SDResponse::R1_Status, read_buffer);
821
822 if r1 == SUCCESS_STATUS {
823 if count <= 1 {
824 // check for data block to be ready
825 self.state.set(SpiState::WaitReadBlock);
826 self.read_bytes(write_buffer, read_buffer, 1);
827 } else {
828 // check for data block to be ready
829 self.state.set(SpiState::WaitReadBlocks { count });
830 self.read_bytes(write_buffer, read_buffer, 1);
831 }
832 } else {
833 // error, send callback and quit
834 self.txbuffer.replace(write_buffer);
835 self.rxbuffer.replace(read_buffer);
836 self.state.set(SpiState::Idle);
837 self.alarm_state.set(AlarmState::Idle);
838 self.alarm_count.set(0);
839 self.client.map(move |client| {
840 client.error(SdCardError::ReadFailure as u32);
841 });
842 }
843 }
844
845 SpiState::WaitReadBlock => {
846 if read_buffer[0] == DATA_TOKEN {
847 // data ready to read. Read block plus CRC
848 self.alarm_count.set(0);
849 self.state.set(SpiState::ReadBlockComplete);
850 self.read_bytes(write_buffer, read_buffer, 512 + 2);
851 } else if read_buffer[0] == 0xFF {
852 // line is idling high, data is not ready
853
854 // replace buffers
855 self.txbuffer.replace(write_buffer);
856 self.rxbuffer.replace(read_buffer);
857
858 // try again after 1 ms
859 self.alarm_state.set(AlarmState::WaitForDataBlock);
860 let delay = self.alarm.ticks_from_ms(1);
861 self.alarm.set_alarm(self.alarm.now(), delay);
862 } else {
863 // error, send callback and quit
864 self.txbuffer.replace(write_buffer);
865 self.rxbuffer.replace(read_buffer);
866 self.state.set(SpiState::Idle);
867 self.alarm_state.set(AlarmState::Idle);
868 self.alarm_count.set(0);
869 self.client.map(move |client| {
870 client.error(SdCardError::ReadFailure as u32);
871 });
872 }
873 }
874
875 SpiState::ReadBlockComplete => {
876 // replace buffers
877 self.txbuffer.replace(write_buffer);
878 self.rxbuffer.replace(read_buffer);
879
880 // read finished, perform callback
881 self.state.set(SpiState::Idle);
882 self.rxbuffer.map(|read_buffer| {
883 self.client_buffer.take().map(move |buffer| {
884 // copy data to user buffer
885 // Limit to minimum length between buffer, read_buffer,
886 // and 512 (block size)
887 for (client_byte, &read_byte) in
888 buffer.iter_mut().zip(read_buffer.iter()).take(512)
889 {
890 *client_byte = read_byte;
891 }
892
893 // callback
894 let read_len = cmp::min(read_buffer.len(), cmp::min(buffer.len(), 512));
895 self.client.map(move |client| {
896 client.read_done(buffer, read_len);
897 });
898 });
899 });
900 }
901
902 SpiState::WaitReadBlocks { count } => {
903 if read_buffer[0] == DATA_TOKEN {
904 // data ready to read. Read block plus CRC
905 self.alarm_count.set(0);
906 self.state.set(SpiState::ReceivedBlock { count });
907 self.read_bytes(write_buffer, read_buffer, 512 + 2);
908 } else if read_buffer[0] == 0xFF {
909 // line is idling high, data is not ready
910
911 // replace buffers
912 self.txbuffer.replace(write_buffer);
913 self.rxbuffer.replace(read_buffer);
914
915 // try again after 1 ms
916 self.alarm_state
917 .set(AlarmState::WaitForDataBlocks { count });
918 let delay = self.alarm.ticks_from_ms(1);
919 self.alarm.set_alarm(self.alarm.now(), delay);
920 } else {
921 // error, send callback and quit
922 self.txbuffer.replace(write_buffer);
923 self.rxbuffer.replace(read_buffer);
924 self.state.set(SpiState::Idle);
925 self.alarm_state.set(AlarmState::Idle);
926 self.alarm_count.set(0);
927 self.client.map(move |client| {
928 client.error(SdCardError::ReadFailure as u32);
929 });
930 }
931 }
932
933 SpiState::ReceivedBlock { count } => {
934 // copy block over to client buffer
935 self.client_buffer.map(|buffer| {
936 // copy block into client buffer
937 // Limit to minimum length between buffer, read_buffer, and
938 // 512 (block size)
939 let offset = self.client_offset.get();
940 for (client_byte, &read_byte) in buffer
941 .iter_mut()
942 .skip(offset)
943 .zip(read_buffer.iter())
944 .take(512)
945 {
946 *client_byte = read_byte;
947 }
948
949 // update offset
950 let read_len = cmp::min(read_buffer.len(), cmp::min(buffer.len(), 512));
951 self.client_offset.set(offset + read_len);
952 });
953
954 if count <= 1 {
955 // all blocks received. Terminate multiple read
956 self.state.set(SpiState::ReadBlocksComplete);
957 self.send_command(SDCmd::CMD12_StopRead, 0x0, write_buffer, read_buffer, 10);
958 } else {
959 // check for next data block to be ready
960 self.state
961 .set(SpiState::WaitReadBlocks { count: count - 1 });
962 self.read_bytes(write_buffer, read_buffer, 1);
963 }
964 }
965
966 SpiState::ReadBlocksComplete => {
967 // check response
968 let (r1, _, _) = self.get_response(SDResponse::R1_Status, read_buffer);
969
970 if r1 == SUCCESS_STATUS {
971 // replace buffers
972 self.txbuffer.replace(write_buffer);
973 self.rxbuffer.replace(read_buffer);
974 self.state.set(SpiState::Idle);
975
976 // read finished, perform callback
977 self.client_buffer.take().map(move |buffer| {
978 self.client.map(move |client| {
979 client.read_done(buffer, self.client_offset.get());
980 });
981 });
982 } else {
983 // error, send callback and quit
984 self.txbuffer.replace(write_buffer);
985 self.rxbuffer.replace(read_buffer);
986 self.state.set(SpiState::Idle);
987 self.alarm_state.set(AlarmState::Idle);
988 self.alarm_count.set(0);
989 self.client.map(move |client| {
990 client.error(SdCardError::ReadFailure as u32);
991 });
992 }
993 }
994
995 SpiState::StartWriteBlocks { count } => {
996 // check response
997 let (r1, _, _) = self.get_response(SDResponse::R1_Status, read_buffer);
998
999 if r1 == SUCCESS_STATUS {
1000 if count <= 1 {
1001 let bytes_written = self.client_buffer.map_or(0, |buffer| {
1002 // copy over data from client buffer
1003 // Limit to minimum length between write_buffer,
1004 // buffer, and 512 (block size)
1005 for (write_byte, &client_byte) in
1006 write_buffer.iter_mut().skip(1).zip(buffer.iter()).take(512)
1007 {
1008 *write_byte = client_byte;
1009 }
1010
1011 // calculate number of bytes written
1012 cmp::min(write_buffer.len(), cmp::min(buffer.len(), 512))
1013 });
1014
1015 // set a known value for remaining bytes
1016 for write_byte in write_buffer
1017 .iter_mut()
1018 .skip(1)
1019 .skip(bytes_written)
1020 .take(512)
1021 {
1022 *write_byte = 0xFF;
1023 }
1024
1025 // set up remainder of data packet
1026 write_buffer[0] = DATA_TOKEN; // Data token
1027 write_buffer[513] = 0xFF; // dummy CRC
1028 write_buffer[514] = 0xFF; // dummy CRC
1029
1030 // write data packet
1031 self.state.set(SpiState::WriteBlockResponse);
1032 self.write_bytes(write_buffer, read_buffer, 515);
1033 } else {
1034 // multi-block SD card writes are unimplemented
1035 // This should have returned an error already, but if
1036 // we got here somehow, return an error and quit now
1037 self.txbuffer.replace(write_buffer);
1038 self.rxbuffer.replace(read_buffer);
1039 self.state.set(SpiState::Idle);
1040 self.alarm_state.set(AlarmState::Idle);
1041 self.alarm_count.set(0);
1042 self.client.map(move |client| {
1043 client.error(SdCardError::WriteFailure as u32);
1044 });
1045 }
1046 } else {
1047 // error, send callback and quit
1048 self.txbuffer.replace(write_buffer);
1049 self.rxbuffer.replace(read_buffer);
1050 self.state.set(SpiState::Idle);
1051 self.alarm_state.set(AlarmState::Idle);
1052 self.alarm_count.set(0);
1053 self.client.map(move |client| {
1054 client.error(SdCardError::WriteFailure as u32);
1055 });
1056 }
1057 }
1058
1059 SpiState::WriteBlockResponse => {
1060 // Get data packet
1061 self.state.set(SpiState::WriteBlockBusy);
1062 self.read_bytes(write_buffer, read_buffer, 1);
1063 }
1064
1065 SpiState::WriteBlockBusy => {
1066 if (read_buffer[0] & 0x1F) == 0x05 {
1067 // check if sd card is busy
1068 self.state.set(SpiState::WaitWriteBlockBusy);
1069 self.read_bytes(write_buffer, read_buffer, 1);
1070 } else {
1071 // error, send callback and quit
1072 self.txbuffer.replace(write_buffer);
1073 self.rxbuffer.replace(read_buffer);
1074 self.state.set(SpiState::Idle);
1075 self.alarm_state.set(AlarmState::Idle);
1076 self.alarm_count.set(0);
1077 self.client.map(move |client| {
1078 client.error(SdCardError::WriteFailure as u32);
1079 });
1080 }
1081 }
1082
1083 SpiState::WaitWriteBlockBusy => {
1084 // check if line is still held low (busy state)
1085 if read_buffer[0] != 0x00 {
1086 // replace buffers
1087 self.txbuffer.replace(write_buffer);
1088 self.rxbuffer.replace(read_buffer);
1089
1090 // read finished, perform callback
1091 self.state.set(SpiState::Idle);
1092 self.alarm_count.set(0);
1093 self.client_buffer.take().map(move |buffer| {
1094 self.client.map(move |client| {
1095 client.write_done(buffer);
1096 });
1097 });
1098 } else {
1099 // replace buffers
1100 self.txbuffer.replace(write_buffer);
1101 self.rxbuffer.replace(read_buffer);
1102
1103 // try again after 1 ms
1104 self.alarm_state.set(AlarmState::WaitForWriteBusy);
1105 let delay = self.alarm.ticks_from_ms(1);
1106 self.alarm.set_alarm(self.alarm.now(), delay);
1107 }
1108 }
1109
1110 SpiState::Idle => {
1111 // receiving an event from Idle means something was killed
1112
1113 // replace buffers
1114 self.txbuffer.replace(write_buffer);
1115 self.rxbuffer.replace(read_buffer);
1116 }
1117 }
1118 }
1119
1120 /// updates SD card state upon timer alarm fired
1121 fn process_alarm_states(&self) {
1122 // keep track of how many times the alarm has been called in a row
1123 let repeats = self.alarm_count.get();
1124 if repeats > 100 {
1125 // error, send callback and quit
1126 self.state.set(SpiState::Idle);
1127 self.alarm_state.set(AlarmState::Idle);
1128 self.alarm_count.set(0);
1129 self.client.map(move |client| {
1130 client.error(SdCardError::TimeoutFailure as u32);
1131 });
1132 } else {
1133 self.alarm_count.set(repeats + 1);
1134 }
1135
1136 match self.alarm_state.get() {
1137 AlarmState::DetectionChange => {
1138 // perform callback
1139 self.client.map(move |client| {
1140 client.card_detection_changed(self.is_installed());
1141 });
1142
1143 // re-enable interrupts
1144 self.detect_changes();
1145 self.alarm_count.set(0);
1146 self.alarm_state.set(AlarmState::Idle);
1147 }
1148
1149 AlarmState::RepeatHCSInit => {
1150 // check card initialization again
1151 self.txbuffer.take().map(|write_buffer| {
1152 self.rxbuffer.take().map(move |read_buffer| {
1153 // send application-specific initialization in high capcity mode (HCS)
1154 self.state.set(SpiState::SendManufSpecificCmd {
1155 cmd: SDCmd::ACMD41_ManufSpecificInit,
1156 arg: 0x40000000,
1157 });
1158 self.after_state.set(SpiState::InitRepeatHCSInit);
1159 self.send_command(
1160 SDCmd::CMD55_ManufSpecificCommand,
1161 0x0,
1162 write_buffer,
1163 read_buffer,
1164 10,
1165 );
1166 });
1167 });
1168
1169 self.alarm_state.set(AlarmState::Idle);
1170 }
1171
1172 AlarmState::RepeatAppSpecificInit => {
1173 // check card initialization again
1174 self.txbuffer.take().map(|write_buffer| {
1175 self.rxbuffer.take().map(move |read_buffer| {
1176 // send application-specific initialization
1177 self.state.set(SpiState::SendManufSpecificCmd {
1178 cmd: SDCmd::ACMD41_ManufSpecificInit,
1179 arg: 0x0,
1180 });
1181 self.after_state.set(SpiState::InitRepeatAppSpecificInit);
1182 self.send_command(
1183 SDCmd::CMD55_ManufSpecificCommand,
1184 0x0,
1185 write_buffer,
1186 read_buffer,
1187 10,
1188 );
1189 });
1190 });
1191
1192 self.alarm_state.set(AlarmState::Idle);
1193 }
1194
1195 AlarmState::RepeatGenericInit => {
1196 // check card initialization again
1197 self.txbuffer.take().map(|write_buffer| {
1198 self.rxbuffer.take().map(move |read_buffer| {
1199 // send generic initialization
1200 self.state.set(SpiState::InitRepeatGenericInit);
1201 self.send_command(SDCmd::CMD1_Init, 0x0, write_buffer, read_buffer, 10);
1202 });
1203 });
1204
1205 self.alarm_state.set(AlarmState::Idle);
1206 }
1207
1208 AlarmState::WaitForDataBlock => {
1209 // check card initialization again
1210 self.txbuffer.take().map(|write_buffer| {
1211 self.rxbuffer.take().map(move |read_buffer| {
1212 // wait until ready and then read data block, then done
1213 self.state.set(SpiState::WaitReadBlock);
1214 self.read_bytes(write_buffer, read_buffer, 1);
1215 });
1216 });
1217
1218 self.alarm_state.set(AlarmState::Idle);
1219 }
1220
1221 AlarmState::WaitForDataBlocks { count } => {
1222 // check card initialization again
1223 self.txbuffer.take().map(|write_buffer| {
1224 self.rxbuffer.take().map(move |read_buffer| {
1225 // wait until ready and then read data block, then done
1226 self.state.set(SpiState::WaitReadBlocks { count });
1227 self.read_bytes(write_buffer, read_buffer, 1);
1228 });
1229 });
1230
1231 self.alarm_state.set(AlarmState::Idle);
1232 }
1233
1234 AlarmState::WaitForWriteBusy => {
1235 // check card initialization again
1236 self.txbuffer.take().map(|write_buffer| {
1237 self.rxbuffer.take().map(move |read_buffer| {
1238 // check if sd card is busy
1239 self.state.set(SpiState::WaitWriteBlockBusy);
1240 self.read_bytes(write_buffer, read_buffer, 1);
1241 });
1242 });
1243
1244 self.alarm_state.set(AlarmState::Idle);
1245 }
1246
1247 AlarmState::Idle => {
1248 // receiving an event from Idle means something was killed
1249 // do nothing
1250 }
1251 }
1252 }
1253
1254 pub fn set_client<C: SDCardClient>(&self, client: &'static C) {
1255 self.client.set(client);
1256 }
1257
1258 pub fn is_installed(&self) -> bool {
1259 // if there is no detect pin, assume an sd card is installed
1260 self.detect_pin.get().is_none_or(|pin| {
1261 // sd card detection pin is active low
1262 !pin.read()
1263 })
1264 }
1265
1266 pub fn is_initialized(&self) -> bool {
1267 self.is_initialized.get()
1268 }
1269
1270 /// watches SD card detect pin for changes, sends callback on change
1271 pub fn detect_changes(&self) {
1272 self.detect_pin.get().map(|pin| {
1273 pin.enable_interrupts(hil::gpio::InterruptEdge::EitherEdge);
1274 });
1275 }
1276
1277 pub fn initialize(&self) -> Result<(), ErrorCode> {
1278 // if not already, set card to uninitialized again
1279 self.is_initialized.set(false);
1280
1281 // no point in initializing if the card is not installed
1282 if self.is_installed() {
1283 // reset the SD card in order to start initializing it
1284 self.txbuffer
1285 .take()
1286 .map_or(Err(ErrorCode::NOMEM), |txbuffer| {
1287 self.rxbuffer
1288 .take()
1289 .map_or(Err(ErrorCode::NOMEM), move |rxbuffer| {
1290 self.state.set(SpiState::InitReset);
1291 self.send_command(SDCmd::CMD0_Reset, 0x0, txbuffer, rxbuffer, 10);
1292
1293 // command started successfully
1294 Ok(())
1295 })
1296 })
1297 } else {
1298 // no sd card installed
1299 Err(ErrorCode::UNINSTALLED)
1300 }
1301 }
1302
1303 pub fn read_blocks(
1304 &self,
1305 buffer: &'static mut [u8],
1306 sector: u32,
1307 count: u32,
1308 ) -> Result<(), ErrorCode> {
1309 // only if initialized and installed
1310 if self.is_installed() {
1311 if self.is_initialized() {
1312 self.txbuffer
1313 .take()
1314 .map_or(Err(ErrorCode::NOMEM), |txbuffer| {
1315 self.rxbuffer
1316 .take()
1317 .map_or(Err(ErrorCode::NOMEM), move |rxbuffer| {
1318 // save the user buffer for later
1319 self.client_buffer.replace(buffer);
1320 self.client_offset.set(0);
1321
1322 // convert block address to byte address for non-block
1323 // access cards
1324 let mut address = sector;
1325 if self.card_type.get() != SDCardType::SDv2BlockAddressable {
1326 address *= 512;
1327 }
1328
1329 self.state.set(SpiState::StartReadBlocks { count });
1330 if count == 1 {
1331 self.send_command(
1332 SDCmd::CMD17_ReadSingle,
1333 address,
1334 txbuffer,
1335 rxbuffer,
1336 10,
1337 );
1338 } else {
1339 self.send_command(
1340 SDCmd::CMD18_ReadMultiple,
1341 address,
1342 txbuffer,
1343 rxbuffer,
1344 10,
1345 );
1346 }
1347
1348 // command started successfully
1349 Ok(())
1350 })
1351 })
1352 } else {
1353 // sd card not initialized
1354 Err(ErrorCode::RESERVE)
1355 }
1356 } else {
1357 // sd card not installed
1358 Err(ErrorCode::UNINSTALLED)
1359 }
1360 }
1361
1362 pub fn write_blocks(
1363 &self,
1364 buffer: &'static mut [u8],
1365 sector: u32,
1366 count: u32,
1367 ) -> Result<(), ErrorCode> {
1368 // only if initialized and installed
1369 if self.is_installed() {
1370 if self.is_initialized() {
1371 self.txbuffer
1372 .take()
1373 .map_or(Err(ErrorCode::NOMEM), |txbuffer| {
1374 self.rxbuffer
1375 .take()
1376 .map_or(Err(ErrorCode::NOMEM), move |rxbuffer| {
1377 // save the user buffer for later
1378 self.client_buffer.replace(buffer);
1379 self.client_offset.set(0);
1380
1381 // convert block address to byte address for non-block
1382 // access cards
1383 let mut address = sector;
1384 if self.card_type.get() != SDCardType::SDv2BlockAddressable {
1385 address *= 512;
1386 }
1387
1388 self.state.set(SpiState::StartWriteBlocks { count });
1389 if count == 1 {
1390 self.send_command(
1391 SDCmd::CMD24_WriteSingle,
1392 address,
1393 txbuffer,
1394 rxbuffer,
1395 10,
1396 );
1397
1398 // command started successfully
1399 Ok(())
1400 } else {
1401 // can't write multiple blocks yet
1402 Err(ErrorCode::NOSUPPORT)
1403 }
1404 })
1405 })
1406 } else {
1407 // sd card not initialized
1408 Err(ErrorCode::RESERVE)
1409 }
1410 } else {
1411 // sd card not installed
1412 Err(ErrorCode::UNINSTALLED)
1413 }
1414 }
1415}
1416
1417/// Handle callbacks from the SPI peripheral
1418impl<'a, A: hil::time::Alarm<'a>> hil::spi::SpiMasterClient for SDCard<'a, A> {
1419 fn read_write_done(
1420 &self,
1421 write_buffer: SubSliceMut<'static, u8>,
1422 read_buffer: Option<SubSliceMut<'static, u8>>,
1423 status: Result<usize, ErrorCode>,
1424 ) {
1425 // unwrap so we don't have to deal with options everywhere
1426 read_buffer.map(move |read_buffer| {
1427 self.process_spi_states(write_buffer.take(), read_buffer.take(), status.unwrap_or(0));
1428 });
1429 }
1430}
1431
1432/// Handle callbacks from the timer
1433impl<'a, A: hil::time::Alarm<'a>> hil::time::AlarmClient for SDCard<'a, A> {
1434 fn alarm(&self) {
1435 self.process_alarm_states();
1436 }
1437}
1438
1439/// Handle callbacks from the card detection pin
1440impl<'a, A: hil::time::Alarm<'a>> hil::gpio::Client for SDCard<'a, A> {
1441 fn fired(&self) {
1442 // check if there was an open transaction with the sd card
1443 if self.alarm_state.get() != AlarmState::Idle || self.state.get() != SpiState::Idle {
1444 // something was running when this occurred. Kill the transaction and
1445 // send an error callback
1446 self.state.set(SpiState::Idle);
1447 self.alarm_state.set(AlarmState::Idle);
1448 self.client.map(move |client| {
1449 client.error(SdCardError::CardStateChanged as u32);
1450 });
1451 }
1452
1453 // either the card is new or gone, in either case it isn't initialized
1454 self.is_initialized.set(false);
1455
1456 // disable additional interrupts
1457 self.detect_pin.get().map(|pin| {
1458 pin.disable_interrupts();
1459 });
1460
1461 // run a timer for 500 ms in order to let the sd card settle
1462 self.alarm_state.set(AlarmState::DetectionChange);
1463 let delay = self.alarm.ticks_from_ms(500);
1464 self.alarm.set_alarm(self.alarm.now(), delay);
1465 }
1466}
1467
1468/// Application driver for SD Card capsule.
1469///
1470/// This is used if the SDCard is going to be attached directly to userspace
1471/// syscalls. SDCardDriver can be ignored if another capsule is going to build
1472/// off of the SDCard instead
1473pub struct SDCardDriver<'a, A: hil::time::Alarm<'a>> {
1474 sdcard: &'a SDCard<'a, A>,
1475 kernel_buf: TakeCell<'static, [u8]>,
1476 grants: Grant<
1477 App,
1478 UpcallCount<1>,
1479 AllowRoCount<{ ro_allow::COUNT }>,
1480 AllowRwCount<{ rw_allow::COUNT }>,
1481 >,
1482 current_process: OptionalCell<ProcessId>,
1483}
1484
1485/// Holds buffers and whatnot that the application has passed us.
1486#[derive(Default)]
1487pub struct App;
1488
1489/// Buffer for SD card driver, assigned in board `main.rs` files
1490pub const KERNEL_BUFFER_LENGTH: usize = 512;
1491
1492/// Functions for SDCardDriver
1493impl<'a, A: hil::time::Alarm<'a>> SDCardDriver<'a, A> {
1494 /// Create new SD card userland interface
1495 ///
1496 /// sdcard - SDCard interface to provide application access to
1497 /// kernel_buf - buffer used to hold SD card blocks, must be at least 512
1498 /// bytes in length
1499 pub fn new(
1500 sdcard: &'a SDCard<'a, A>,
1501 kernel_buf: &'static mut [u8; 512],
1502 grants: Grant<
1503 App,
1504 UpcallCount<1>,
1505 AllowRoCount<{ ro_allow::COUNT }>,
1506 AllowRwCount<{ rw_allow::COUNT }>,
1507 >,
1508 ) -> SDCardDriver<'a, A> {
1509 // return new SDCardDriver
1510 SDCardDriver {
1511 sdcard,
1512 kernel_buf: TakeCell::new(kernel_buf),
1513 grants,
1514 current_process: OptionalCell::empty(),
1515 }
1516 }
1517}
1518
1519/// Handle callbacks from SDCard
1520impl<'a, A: hil::time::Alarm<'a>> SDCardClient for SDCardDriver<'a, A> {
1521 fn card_detection_changed(&self, installed: bool) {
1522 self.current_process.map(|process_id| {
1523 let _ = self.grants.enter(process_id, |_app, kernel_data| {
1524 kernel_data
1525 .schedule_upcall(0, (0, installed as usize, 0))
1526 .ok();
1527 });
1528 });
1529 }
1530
1531 fn init_done(&self, block_size: u32, total_size: u64) {
1532 self.current_process.map(|process_id| {
1533 let _ = self.grants.enter(process_id, |_app, kernel_data| {
1534 let size_in_kb = ((total_size >> 10) & 0xFFFFFFFF) as usize;
1535 kernel_data
1536 .schedule_upcall(0, (1, block_size as usize, size_in_kb))
1537 .ok();
1538 });
1539 });
1540 }
1541
1542 fn read_done(&self, data: &'static mut [u8], len: usize) {
1543 self.kernel_buf.replace(data);
1544
1545 self.current_process.map(|process_id| {
1546 let _ = self.grants.enter(process_id, |_, kernel_data| {
1547 let mut read_len = 0;
1548 self.kernel_buf.map(|data| {
1549 kernel_data
1550 .get_readwrite_processbuffer(rw_allow::READ)
1551 .and_then(|read| {
1552 read.mut_enter(|read_buffer| {
1553 // copy bytes to user buffer
1554 // Limit to minimum length between read_buffer, data, and
1555 // len field
1556 for (read_byte, &data_byte) in
1557 read_buffer.iter().zip(data.iter()).take(len)
1558 {
1559 read_byte.set(data_byte);
1560 }
1561 read_len = cmp::min(read_buffer.len(), cmp::min(data.len(), len));
1562 read_len
1563 })
1564 })
1565 .unwrap_or(0);
1566 });
1567
1568 // perform callback
1569 // Note that we are explicitly performing the callback even if no
1570 // data was read or if the app's read_buffer doesn't exist
1571 kernel_data.schedule_upcall(0, (2, read_len, 0)).ok();
1572 });
1573 });
1574 }
1575
1576 fn write_done(&self, buffer: &'static mut [u8]) {
1577 self.kernel_buf.replace(buffer);
1578
1579 self.current_process.map(|process_id| {
1580 let _ = self.grants.enter(process_id, |_app, kernel_data| {
1581 kernel_data.schedule_upcall(0, (3, 0, 0)).ok();
1582 });
1583 });
1584 }
1585
1586 fn error(&self, error: u32) {
1587 self.current_process.map(|process_id| {
1588 let _ = self.grants.enter(process_id, |_app, kernel_data| {
1589 kernel_data.schedule_upcall(0, (4, error as usize, 0)).ok();
1590 });
1591 });
1592 }
1593}
1594
1595/// Connections to userspace syscalls
1596impl<'a, A: hil::time::Alarm<'a>> SyscallDriver for SDCardDriver<'a, A> {
1597 fn command(
1598 &self,
1599 command_num: usize,
1600 data: usize,
1601 _: usize,
1602 process_id: ProcessId,
1603 ) -> CommandReturn {
1604 if command_num == 0 {
1605 // Handle unconditional driver existence check.
1606 return CommandReturn::success();
1607 }
1608
1609 // Check if this driver is free, or already dedicated to this process.
1610 let match_or_empty_or_nonexistant = self.current_process.map_or(true, |current_process| {
1611 self.grants
1612 .enter(current_process, |_, _| current_process == process_id)
1613 .unwrap_or(true)
1614 });
1615 if match_or_empty_or_nonexistant {
1616 self.current_process.set(process_id);
1617 } else {
1618 return CommandReturn::failure(ErrorCode::NOMEM);
1619 }
1620
1621 match command_num {
1622 // is_installed
1623 1 => {
1624 let value = self.sdcard.is_installed() as u32;
1625 CommandReturn::success_u32(value)
1626 }
1627
1628 // initialize
1629 2 => match self.sdcard.initialize() {
1630 Ok(()) => CommandReturn::success(),
1631 Err(e) => CommandReturn::failure(e),
1632 },
1633
1634 // read_block
1635 3 => self.kernel_buf.take().map_or(
1636 CommandReturn::failure(ErrorCode::BUSY),
1637 |kernel_buf| {
1638 CommandReturn::from(self.sdcard.read_blocks(kernel_buf, data as u32, 1))
1639 },
1640 ),
1641
1642 // write_block
1643 4 => {
1644 let result: Result<(), ErrorCode> = self
1645 .grants
1646 .enter(process_id, |_, kernel_data| {
1647 kernel_data
1648 .get_readonly_processbuffer(ro_allow::WRITE)
1649 .and_then(|write| {
1650 write.enter(|write_buffer| {
1651 self.kernel_buf.take().map_or(
1652 Err(ErrorCode::BUSY),
1653 |kernel_buf| {
1654 // copy over write data from application
1655 // Limit to minimum length between kernel_buf,
1656 // write_buffer, and 512 (block size)
1657 for (kernel_byte, write_byte) in kernel_buf
1658 .iter_mut()
1659 .zip(write_buffer.iter())
1660 .take(512)
1661 {
1662 *kernel_byte = write_byte.get();
1663 }
1664
1665 // begin writing
1666 self.sdcard.write_blocks(kernel_buf, data as u32, 1)
1667 },
1668 )
1669 })
1670 })
1671 .unwrap_or(Err(ErrorCode::NOMEM))
1672 })
1673 .unwrap_or(Err(ErrorCode::NOMEM));
1674 CommandReturn::from(result)
1675 }
1676
1677 _ => CommandReturn::failure(ErrorCode::NOSUPPORT),
1678 }
1679 }
1680
1681 fn allocate_grant(&self, processid: ProcessId) -> Result<(), kernel::process::Error> {
1682 self.grants.enter(processid, |_, _| {})
1683 }
1684}