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}