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