@@ -112,16 +112,23 @@ type I2cPins = (
112112type SpiBus = hal:: Spi < hal:: spi:: Enabled , pac:: SPI0 , 8 > ;
113113
114114/// What state our SD Card can be in
115- #[ derive( defmt:: Format , Debug , Copy , Clone , PartialEq , Eq ) ]
115+ #[ derive( defmt:: Format , Debug , Clone , PartialEq , Eq ) ]
116116enum CardState {
117117 Unplugged ,
118118 Uninitialised ,
119119 #[ allow( unused) ]
120- Online ,
120+ Online ( CardInfo ) ,
121121 #[ allow( unused) ]
122122 Errored ,
123123}
124124
125+ /// Describes an SD card we've discovered
126+ #[ derive( defmt:: Format , Debug , Clone , PartialEq , Eq ) ]
127+ struct CardInfo {
128+ /// Number of blocks on the SD card
129+ num_blocks : u64 ,
130+ }
131+
125132/// All the hardware we use on the Pico
126133struct Hardware {
127134 /// All the pins we use on the Raspberry Pi Pico
@@ -723,13 +730,6 @@ impl Hardware {
723730 )
724731 }
725732
726- // i2c_sda: {
727- //
728- // },
729- // i2c_scl: {
730- //
731- // },
732-
733733 /// Perform some SPI operation with the I/O chip selected.
734734 ///
735735 /// You are required to have called `self.release_cs_lines()` previously,
@@ -961,7 +961,7 @@ impl Hardware {
961961 if was_inserted { "inserted" } else { "removed" }
962962 ) ;
963963
964- self . card_state = match ( self . card_state , was_inserted) {
964+ self . card_state = match ( & self . card_state , was_inserted) {
965965 // Eject events
966966 ( CardState :: Unplugged , false ) => {
967967 defmt:: warn!( "Spurious unplug event" ) ;
@@ -971,7 +971,7 @@ impl Hardware {
971971 defmt:: info!( "SD Card removed" ) ;
972972 CardState :: Unplugged
973973 }
974- ( CardState :: Online , false ) => {
974+ ( CardState :: Online ( _ ) , false ) => {
975975 defmt:: warn!( "Active SD Card removed!" ) ;
976976 CardState :: Unplugged
977977 }
@@ -1189,6 +1189,77 @@ impl Hardware {
11891189 }
11901190 Ok ( bytes_in_fifo as usize )
11911191 }
1192+
1193+ fn sdcard_poll ( & mut self ) {
1194+ match self . card_state {
1195+ CardState :: Uninitialised => {
1196+ // Init the card here
1197+ use embedded_sdmmc:: BlockDevice ;
1198+ struct FakeSpi < ' a > ( & ' a mut Hardware ) ;
1199+ struct FakeCs ( ) ;
1200+ static IS_CS_LOW : AtomicBool = AtomicBool :: new ( false ) ;
1201+ impl < ' a > embedded_hal:: blocking:: spi:: Transfer < u8 > for FakeSpi < ' a > {
1202+ type Error = core:: convert:: Infallible ;
1203+ fn transfer < ' w > (
1204+ & mut self ,
1205+ words : & ' w mut [ u8 ] ,
1206+ ) -> Result < & ' w [ u8 ] , Self :: Error > {
1207+ if IS_CS_LOW . load ( Ordering :: SeqCst ) {
1208+ defmt:: info!( "out: {:?}" , words) ;
1209+ self . 0 . with_bus_cs ( 1 , |spi, _buffer| {
1210+ spi. transfer ( words) . unwrap ( ) ;
1211+ } ) ;
1212+ defmt:: info!( "in: {:?}" , words) ;
1213+ Ok ( words)
1214+ } else {
1215+ // Select a slot we don't use so the SD card won't be activated
1216+ defmt:: info!( "out: {:?}" , words) ;
1217+ self . 0 . with_bus_cs ( 7 , |spi, _buffer| {
1218+ spi. transfer ( words) . unwrap ( ) ;
1219+ } ) ;
1220+ defmt:: info!( "in: {:?}" , words) ;
1221+ Ok ( words)
1222+ }
1223+ }
1224+ }
1225+ impl embedded_hal:: digital:: v2:: OutputPin for FakeCs {
1226+ type Error = core:: convert:: Infallible ;
1227+ fn set_low ( & mut self ) -> Result < ( ) , Self :: Error > {
1228+ IS_CS_LOW . store ( true , Ordering :: SeqCst ) ;
1229+ Ok ( ( ) )
1230+ }
1231+
1232+ fn set_high ( & mut self ) -> Result < ( ) , Self :: Error > {
1233+ IS_CS_LOW . store ( true , Ordering :: SeqCst ) ;
1234+ Ok ( ( ) )
1235+ }
1236+ }
1237+ // Downclock SPI to 100 kHz
1238+ // hw.spi_bus.set_baudrate(hw.clocks, todo!());
1239+ let spi = FakeSpi ( self ) ;
1240+ let cs = FakeCs ( ) ;
1241+ let mut spi_interface = embedded_sdmmc:: SdMmcSpi :: new ( spi, cs) ;
1242+ let num_blocks = match spi_interface. acquire ( ) {
1243+ Ok ( card) => {
1244+ defmt:: info!( "Found card size!" ) ;
1245+ card. num_blocks ( )
1246+ }
1247+ Err ( e) => {
1248+ defmt:: warn!( "Failed to acquire SD card: {:?}" , e) ;
1249+ Err ( e)
1250+ }
1251+ } ;
1252+ if let Ok ( num_blocks) = num_blocks {
1253+ self . card_state = CardState :: Online ( CardInfo {
1254+ num_blocks : num_blocks. 0 as u64 ,
1255+ } ) ;
1256+ }
1257+ // Bring SPI clock back up again
1258+ // hw.spi_bus.set_baudrate(hw.clocks, todo!());
1259+ }
1260+ CardState :: Unplugged | CardState :: Errored | CardState :: Online ( _) => { }
1261+ }
1262+ }
11921263}
11931264
11941265fn sign_on ( ) {
@@ -1844,93 +1915,32 @@ pub extern "C" fn block_dev_get_info(device: u8) -> common::Option<common::block
18441915 let mut lock = HARDWARE . lock ( ) ;
18451916 let hw = lock. as_mut ( ) . unwrap ( ) ;
18461917
1847- let card_size = match hw. card_state {
1848- CardState :: Unplugged => None ,
1849- CardState :: Errored => None ,
1850- CardState :: Uninitialised => {
1851- // Init the card here
1852- use embedded_sdmmc:: BlockDevice ;
1853- struct FakeSpi < ' a > ( & ' a mut Hardware ) ;
1854- struct FakeCs ( ) ;
1855- static IS_CS_LOW : AtomicBool = AtomicBool :: new ( false ) ;
1856- impl < ' a > embedded_hal:: blocking:: spi:: Transfer < u8 > for FakeSpi < ' a > {
1857- type Error = core:: convert:: Infallible ;
1858- fn transfer < ' w > (
1859- & mut self ,
1860- words : & ' w mut [ u8 ] ,
1861- ) -> Result < & ' w [ u8 ] , Self :: Error > {
1862- if IS_CS_LOW . load ( Ordering :: SeqCst ) {
1863- defmt:: info!( "out: {:?}" , words) ;
1864- self . 0 . with_bus_cs ( 1 , |spi, _buffer| {
1865- spi. transfer ( words) . unwrap ( ) ;
1866- } ) ;
1867- defmt:: info!( "in: {:?}" , words) ;
1868- Ok ( words)
1869- } else {
1870- // Select a slot we don't use so the SD card won't be activated
1871- defmt:: info!( "out: {:?}" , words) ;
1872- self . 0 . with_bus_cs ( 7 , |spi, _buffer| {
1873- spi. transfer ( words) . unwrap ( ) ;
1874- } ) ;
1875- defmt:: info!( "in: {:?}" , words) ;
1876- Ok ( words)
1877- }
1878- }
1879- }
1880- impl embedded_hal:: digital:: v2:: OutputPin for FakeCs {
1881- type Error = core:: convert:: Infallible ;
1882- fn set_low ( & mut self ) -> Result < ( ) , Self :: Error > {
1883- IS_CS_LOW . store ( true , Ordering :: SeqCst ) ;
1884- Ok ( ( ) )
1885- }
1886-
1887- fn set_high ( & mut self ) -> Result < ( ) , Self :: Error > {
1888- IS_CS_LOW . store ( true , Ordering :: SeqCst ) ;
1889- Ok ( ( ) )
1890- }
1891- }
1892- // Downclock SPI to 100 kHz
1893- // hw.spi_bus.set_baudrate(hw.clocks, todo!());
1894- let spi = FakeSpi ( hw) ;
1895- let cs = FakeCs ( ) ;
1896- let mut spi_interface = embedded_sdmmc:: SdMmcSpi :: new ( spi, cs) ;
1897- let size = match spi_interface. acquire ( ) {
1898- Ok ( card) => {
1899- defmt:: info!( "Found card size!" ) ;
1900- card. num_blocks ( )
1901- . map ( |block_count| block_count. 0 as u64 )
1902- . ok ( )
1903- }
1904- Err ( e) => {
1905- defmt:: warn!( "Failed to acquire SD card: {:?}" , e) ;
1906- None
1907- }
1908- } ;
1909- // Bring SPI clock back up again
1910- // hw.spi_bus.set_baudrate(hw.clocks, todo!());
1911- size
1918+ hw. sdcard_poll ( ) ;
1919+
1920+ match & hw. card_state {
1921+ CardState :: Unplugged | CardState :: Uninitialised | CardState :: Errored => {
1922+ common:: Option :: Some ( common:: block_dev:: DeviceInfo {
1923+ name : common:: types:: ApiString :: new ( "SdCard0" ) ,
1924+ device_type : common:: block_dev:: DeviceType :: SecureDigitalCard ,
1925+ block_size : 0 ,
1926+ num_blocks : 0 ,
1927+ ejectable : false ,
1928+ removable : true ,
1929+ media_present : false ,
1930+ read_only : false ,
1931+ } )
19121932 }
1913- CardState :: Online => None ,
1914- } ;
1915-
1916- // This is our on-board card slot
1917- common:: Option :: Some ( common:: block_dev:: DeviceInfo {
1918- // This is the built-in SD card slot
1919- name : common:: types:: ApiString :: new ( "SdCard0" ) ,
1920- device_type : common:: block_dev:: DeviceType :: SecureDigitalCard ,
1921- // This is the standard for SD cards
1922- block_size : 512 ,
1923- // TODO: scan the card here
1924- num_blocks : card_size. unwrap_or ( 0 ) ,
1925- // No motorised eject
1926- ejectable : false ,
1927- // But you can take the card out
1928- removable : true ,
1929- // Pretend the card is out
1930- media_present : card_size. is_some ( ) ,
1931- // Don't care about this value when card is out
1932- read_only : false ,
1933- } )
1933+ CardState :: Online ( info) => common:: Option :: Some ( common:: block_dev:: DeviceInfo {
1934+ name : common:: types:: ApiString :: new ( "SdCard0" ) ,
1935+ device_type : common:: block_dev:: DeviceType :: SecureDigitalCard ,
1936+ block_size : 512 ,
1937+ num_blocks : info. num_blocks ,
1938+ ejectable : false ,
1939+ removable : true ,
1940+ media_present : true ,
1941+ read_only : false ,
1942+ } ) ,
1943+ }
19341944 }
19351945 _ => {
19361946 // Nothing else supported by this BIOS
0 commit comments