@@ -21,11 +21,50 @@ use crate::{debug, warn};
21
21
// Types and Implementations
22
22
// ****************************************************************************
23
23
24
+ /// A dummy "CS pin" that does nothing when set high or low.
25
+ ///
26
+ /// Should be used when constructing an [`SpiDevice`] implementation for use with [`SdCard`].
27
+ ///
28
+ /// Let the [`SpiDevice`] use this dummy CS pin that does not actually do anything, and pass the
29
+ /// card's real CS pin to [`SdCard`]'s constructor. This allows the driver to have more
30
+ /// fine-grained control of how the CS pin is managed than is allowed by default using the
31
+ /// [`SpiDevice`] trait, which is needed to implement the SD/MMC SPI communication spec correctly.
32
+ ///
33
+ /// If you're not sure how to get a [`SpiDevice`], you may use one of the implementations
34
+ /// in the [`embedded-hal-bus`] crate, providing a wrapped version of your platform's HAL-provided
35
+ /// [`SpiBus`] and [`DelayUs`] as well as our [`DummyCsPin`] in the constructor.
36
+ ///
37
+ /// [`SpiDevice`]: embedded_hal::spi::SpiDevice
38
+ /// [`SpiBus`]: embedded_hal::spi::SpiBus
39
+ /// [`DelayUs`]: embedded_hal::delay::DelayUs
40
+ /// [`embedded-hal-bus`]: https://docs.rs/embedded-hal-bus
41
+ pub struct DummyCsPin ;
42
+
43
+ impl embedded_hal:: digital:: ErrorType for DummyCsPin {
44
+ type Error = core:: convert:: Infallible ;
45
+ }
46
+
47
+ impl embedded_hal:: digital:: OutputPin for DummyCsPin {
48
+ #[ inline( always) ]
49
+ fn set_low ( & mut self ) -> Result < ( ) , Self :: Error > {
50
+ Ok ( ( ) )
51
+ }
52
+
53
+ #[ inline( always) ]
54
+ fn set_high ( & mut self ) -> Result < ( ) , Self :: Error > {
55
+ Ok ( ( ) )
56
+ }
57
+ }
58
+
24
59
/// Represents an SD Card on an SPI bus.
25
60
///
26
- /// Built from an SPI peripheral and a Chip Select pin. We need Chip Select to
27
- /// be separate so we can clock out some bytes without Chip Select asserted
28
- /// (which "flushes the SD cards registers" according to the spec).
61
+ /// Built from an [`SpiDevice`] implementation and a Chip Select pin.
62
+ /// Unfortunately, We need control of the chip select pin separately from the [`SpiDevice`]
63
+ /// implementation so we can clock out some bytes without Chip Select asserted
64
+ /// (which is necessary to make the SD card actually release the Spi bus after performing
65
+ /// operations on it, according to the spec). To support this, we provide [`DummyCsPin`]
66
+ /// which should be provided to your chosen [`SpiDevice`] implementation rather than the card's
67
+ /// actual CS pin. Then provide the actual CS pin to [`SdCard`]'s constructor.
29
68
///
30
69
/// All the APIs take `&self` - mutability is handled using an inner `RefCell`.
31
70
pub struct SdCard < SPI , CS , DELAYER >
45
84
{
46
85
/// Create a new SD/MMC Card driver using a raw SPI interface.
47
86
///
87
+ /// See the docs of the [`SdCard`] struct for more information about
88
+ /// how to construct the needed `SPI` and `CS` types.
89
+ ///
48
90
/// The card will not be initialised at this time. Initialisation is
49
91
/// deferred until a method is called on the object.
50
92
///
55
97
56
98
/// Construct a new SD/MMC Card driver, using a raw SPI interface and the given options.
57
99
///
100
+ /// See the docs of the [`SdCard`] struct for more information about
101
+ /// how to construct the needed `SPI` and `CS` types.
102
+ ///
58
103
/// The card will not be initialised at this time. Initialisation is
59
104
/// deferred until a method is called on the object.
60
105
pub fn new_with_options (
@@ -573,7 +618,7 @@ where
573
618
574
619
/// Send one byte and receive one byte over the SPI bus.
575
620
fn transfer_byte ( & mut self , out : u8 ) -> Result < u8 , Error > {
576
- let mut read_buf = [ 0u8 ; 1 ] ;
621
+ let mut read_buf = [ 0u8 ; 1 ] ;
577
622
self . spi
578
623
. transfer ( & mut read_buf, & [ out] )
579
624
. map_err ( |_| Error :: Transport ) ?;
@@ -588,7 +633,9 @@ where
588
633
589
634
/// Send multiple bytes and replace them with what comes back over the SPI bus.
590
635
fn transfer_bytes ( & mut self , in_out : & mut [ u8 ] ) -> Result < ( ) , Error > {
591
- self . spi . transfer_in_place ( in_out) . map_err ( |_e| Error :: Transport ) ?;
636
+ self . spi
637
+ . transfer_in_place ( in_out)
638
+ . map_err ( |_e| Error :: Transport ) ?;
592
639
Ok ( ( ) )
593
640
}
594
641
@@ -680,7 +727,7 @@ pub enum CardType {
680
727
/// Uses byte-addressing internally, so limited to 2GiB in size.
681
728
SD2 ,
682
729
/// An high-capacity 'SDHC' Card.
683
- ///
730
+ ///
684
731
/// Uses block-addressing internally to support capacities above 2GiB.
685
732
SDHC ,
686
733
}
0 commit comments