@@ -48,6 +48,7 @@ pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080;
4848pub mod mcp23s17;
4949pub mod mutex;
5050pub mod rtc;
51+ pub mod sdcard;
5152pub mod vga;
5253
5354// -----------------------------------------------------------------------------
@@ -127,6 +128,8 @@ enum CardState {
127128struct CardInfo {
128129 /// Number of blocks on the SD card
129130 num_blocks : u64 ,
131+ /// Type of card
132+ card_type : embedded_sdmmc:: sdcard:: CardType
130133}
131134
132135/// All the hardware we use on the Pico
@@ -1197,63 +1200,21 @@ impl Hardware {
11971200 fn sdcard_poll ( & mut self ) {
11981201 match self . card_state {
11991202 CardState :: Uninitialised => {
1200- // Init the card here
1201- use embedded_sdmmc:: BlockDevice ;
1202- struct FakeSpi < ' a > ( & ' a mut Hardware ) ;
1203- struct FakeCs ( ) ;
1204- static IS_CS_LOW : AtomicBool = AtomicBool :: new ( false ) ;
1205- impl < ' a > embedded_hal:: blocking:: spi:: Transfer < u8 > for FakeSpi < ' a > {
1206- type Error = core:: convert:: Infallible ;
1207- fn transfer < ' w > (
1208- & mut self ,
1209- words : & ' w mut [ u8 ] ,
1210- ) -> Result < & ' w [ u8 ] , Self :: Error > {
1211- if IS_CS_LOW . load ( Ordering :: SeqCst ) {
1212- defmt:: trace!( "SD out: {:?}" , words) ;
1213- self . 0 . with_bus_cs ( 1 , |spi, _buffer| {
1214- spi. transfer ( words) . unwrap ( ) ;
1215- } ) ;
1216- defmt:: trace!( "SD in: {:?}" , words) ;
1217- Ok ( words)
1218- } else {
1219- // Select a slot we don't use so the SD card won't be activated
1220- self . 0 . with_bus_cs ( 7 , |spi, _buffer| {
1221- spi. transfer ( words) . unwrap ( ) ;
1222- } ) ;
1223- Ok ( words)
1224- }
1225- }
1226- }
1227- impl embedded_hal:: digital:: v2:: OutputPin for FakeCs {
1228- type Error = core:: convert:: Infallible ;
1229- fn set_low ( & mut self ) -> Result < ( ) , Self :: Error > {
1230- IS_CS_LOW . store ( true , Ordering :: SeqCst ) ;
1231- Ok ( ( ) )
1232- }
1233-
1234- fn set_high ( & mut self ) -> Result < ( ) , Self :: Error > {
1235- IS_CS_LOW . store ( true , Ordering :: SeqCst ) ;
1236- Ok ( ( ) )
1237- }
1238- }
12391203 // Downclock SPI to 100 kHz
12401204 // hw.spi_bus.set_baudrate(hw.clocks, todo!());
1241- let spi = FakeSpi ( self ) ;
1242- let cs = FakeCs ( ) ;
1243- let mut spi_interface = embedded_sdmmc:: SdMmcSpi :: new ( spi, cs) ;
1244- let num_blocks = match spi_interface. acquire ( ) {
1245- Ok ( card) => {
1246- defmt:: info!( "Found card size!" ) ;
1247- card. num_blocks ( )
1248- }
1249- Err ( e) => {
1250- defmt:: warn!( "Failed to acquire SD card: {:?}" , e) ;
1251- Err ( e)
1252- }
1253- } ;
1254- if let Ok ( num_blocks) = num_blocks {
1205+ use embedded_sdmmc:: BlockDevice ;
1206+ let spi = sdcard:: FakeSpi ( self ) ;
1207+ let cs = sdcard:: FakeCs ( ) ;
1208+ let delayer = sdcard:: FakeDelayer ( ) ;
1209+ let sdcard = embedded_sdmmc:: SdCard :: new ( spi, cs, delayer) ;
1210+ // Talk to the card to trigger a scan if its type
1211+ let num_blocks = sdcard. num_blocks ( ) ;
1212+ let card_type = sdcard. get_card_type ( ) ;
1213+ defmt:: info!( "Found card size {:?} blocks, type {:?}" , num_blocks, card_type) ;
1214+ if let ( Ok ( num_blocks) , Some ( card_type) ) = ( num_blocks, card_type) {
12551215 self . card_state = CardState :: Online ( CardInfo {
12561216 num_blocks : num_blocks. 0 as u64 ,
1217+ card_type
12571218 } ) ;
12581219 }
12591220 // Bring SPI clock back up again
@@ -1983,12 +1944,52 @@ pub extern "C" fn block_write(
19831944/// There are no requirements on the alignment of `data` but if it is
19841945/// aligned, the BIOS may be able to use a higher-performance code path.
19851946pub extern "C" fn block_read (
1986- _device : u8 ,
1987- _block : common:: block_dev:: BlockIdx ,
1988- _num_blocks : u8 ,
1989- _data : common:: ApiBuffer ,
1947+ device : u8 ,
1948+ block : common:: block_dev:: BlockIdx ,
1949+ num_blocks : u8 ,
1950+ data : common:: ApiBuffer ,
19901951) -> common:: Result < ( ) > {
1991- common:: Result :: Err ( common:: Error :: Unimplemented )
1952+ use embedded_sdmmc:: BlockDevice ;
1953+ if data. data_len != usize:: from ( num_blocks) * 512 {
1954+ return common:: Result :: Err ( common:: Error :: UnsupportedConfiguration ( 0 ) ) ;
1955+ }
1956+ match device {
1957+ 0 => {
1958+ let mut lock = HARDWARE . lock ( ) ;
1959+ let hw = lock. as_mut ( ) . unwrap ( ) ;
1960+ hw. sdcard_poll ( ) ;
1961+ let info = match & hw. card_state {
1962+ CardState :: Online ( info) => {
1963+ info. clone ( )
1964+ }
1965+ _ => return common:: Result :: Err ( common:: Error :: NoMediaFound )
1966+ } ;
1967+ let spi = sdcard:: FakeSpi ( hw) ;
1968+ let cs = sdcard:: FakeCs ( ) ;
1969+ let delayer = sdcard:: FakeDelayer ( ) ;
1970+ let sdcard = embedded_sdmmc:: SdCard :: new ( spi, cs, delayer) ;
1971+ unsafe {
1972+ sdcard. mark_card_as_init ( info. card_type ) ;
1973+ }
1974+ let blocks = unsafe {
1975+ core:: slice:: from_raw_parts_mut ( data. data as * mut embedded_sdmmc:: Block , data. data_len / 512 )
1976+ } ;
1977+ let start_block_idx = embedded_sdmmc:: BlockIdx ( block. 0 as u32 ) ;
1978+ match sdcard. read ( blocks, start_block_idx, "bios" ) {
1979+ Ok ( _) => {
1980+ common:: Result :: Ok ( ( ) )
1981+ }
1982+ Err ( e) => {
1983+ defmt:: warn!( "SD error reading {}: {:?}" , block. 0 , e) ;
1984+ common:: Result :: Err ( common:: Error :: DeviceError ( 0 ) )
1985+ }
1986+ }
1987+ }
1988+ _ => {
1989+ // Nothing else supported by this BIOS
1990+ common:: Result :: Err ( common:: Error :: InvalidDevice )
1991+ }
1992+ }
19921993}
19931994
19941995/// Verify one or more sectors on a block device (that is read them and
0 commit comments