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}