stm32-rs / stm32h7xx-hal

Peripheral access API for STM32H7 series microcontrollers
BSD Zero Clause License
226 stars 103 forks source link

SDMMC example doesnt work for Nucleo-H743ZI2 #219

Closed ost-ing closed 3 years ago

ost-ing commented 3 years ago

Hello,

I've been struggling for quite some time to get the SDMMC example running on the Nucleo-H743ZI2 board. I've tried the example "as is", and also with additional tweaks trying to get it to work, I've reduced the clock rate to a value suitable for breadboarding (500kHz - 1MHz) I'm utilising a SDCard module from WaveShare, which I believe has the correct pull-up resistors: https://www.waveshare.com/sd-storage-board.htm

So my analysis so far is:

  1. I successfully have a clock generated by the STM32H7
  2. I can successfully send commands and receive commands from the SDCard.
  3. I am unable to get the program past this function: fn get_scr(&self, card: &mut Card) -> Result<(), Error>.
                /// Get SD CARD Configuration Register (SCR)
                fn get_scr(&self, card: &mut Card) -> Result<(), Error> {
                    // Read the the 64-bit SCR register
                    self.cmd(Cmd::set_block_length(8))?; // CMD16
                    self.cmd(Cmd::app_cmd(card.rca << 16))?;

                    self.start_datapath_transfer(8, 3, Dir::CardToHost);
                    self.cmd(Cmd::cmd51())?;

                    let mut scr = [0; 2];
                    let mut i = 0;
                    let mut status;
                    while {
                        status = self.sdmmc.star.read();

                        !(status.rxoverr().bit()
                          || status.dcrcfail().bit()
                          || status.dtimeout().bit()
                          || status.dbckend().bit())
                    } {
                        if status.rxfifoe().bit_is_clear() {
                            // FIFO not empty
                            scr[i] = self.sdmmc.fifor.read().bits();
                            i += 1;
                        }

                        if i == 2 {
                            break;
                        }
                    }

                    err_from_datapath_sm!(status);              // <----- THIS CALL FAILS WITH A TIMEOUT ERROR

                    // Bytes from wire are Big Endian
                    let scr = ((scr[1] as u64) << 32) | scr[0] as u64;
                    card.scr = SCR(u64::from_be(scr));

                    Ok(())
                }

Using a logic analyzer, I do see a small amount of data on the D0 line, I assume is related to self.start_datapath_transfer(8, 3, Dir::CardToHost); There is no data on any of the other data lines.

@richardeoin do you have any suggestions to why this timeout could be happening? Could there be some conflict between development boards?

I've tried 5 different sdcards all they all produce the same result.

Any help is greatly appreciated

mattico commented 3 years ago

I had the same issue (https://github.com/stm32-rs/stm32h7xx-hal/issues/145) but only when the card is removed and inserted at runtime, not when the card is present at power-on. Is this the same for you? Thinking about this now, I wonder if that just needs a delay between SD card detect and init_card to ensure the power is stable and the card is ready for initialization.

Have you tried different cards?

This may be relevant: https://community.st.com/s/question/0D50X0000BrEAhd/cant-resolve-issue-with-stm32h7-using-sdmmc-and-micro-sd-card

ost-ing commented 3 years ago

I've tried it both with card inserted on bootup, and also inserting it after bootup and its the same result. I've also tried 5 different SDCards, ranging from 32GB to 4GB in size in case of an incompatibility

mattico commented 3 years ago

Okay, my issue might be unrelated then. I imagine there can be different causes for a timeout to occur during initialization.

richardeoin commented 3 years ago

I've created PR https://github.com/stm32-rs/stm32h7xx-hal/pull/222 to remove a couple of potential roadblocks in the example. Any feedback is very welcome!

ost-ing commented 3 years ago

Thanks for the additional clarifications @richardeoin. I did some more digging into my issue, and it turns out that it was a problem with the connectors I was using, which is specific to the Nucleo board. When I use the ST Zio connector that is built in for SDMMC1, then the sdcard_init function completes successfully 🎉