cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 SDIO/SDCard

Daniel Sexton
Associate II
Posted on March 29, 2018 at 04:32

I am trying to get the STM407VET to communicate to an SD Card using the SDIO interface and drivers. Code base was generated from CubeMX and Eclipse is the IDE. Debugging with Open OCD. Hardware is custom.

I have tracked my problem down to the ability to just read back a response from the card.

Starting with the HAL_SD_INIT function and digging down, I get to the HAL_SD_InitCard() and then to __HAL_SD_ENAB:E where the interface comes up and I have a 400KHz clock. After a delay I then proceed to SD_PowerOn where I send the first command to the SD card.

I am using a 1 bit interface. On the Oscope I see that the Command goes out on the CMD line, the clock is 400KHz and a response comes back on the DAT0 line as expected. However I get an error 0X04 back from the SDMMC_GetCmdResp7 call which is a response timeout. On the Oscope I see that the response is coming back about 30usec from the end of the command.

At this point I don't understand why I can't at least get to the point where the responses can be processed.

The signal quality and the timing all look good. There is plenty of setup and hold time and no ringing on the signals. At 400KHz the clock speed is very low. The response appears to complete within 140usec.

Any advice you can offer to get me over this hump so that I can even begin to debug the FatFS would be helpful.

Thanks

6 REPLIES 6
Daniel Sexton
Associate II
Posted on April 26, 2018 at 17:56

I found a bug in the HAL_SD_WriteBlocks method generated by CubeMX. This caused a Hardware Fault.

The method allows the driver to read beyond the end of the data buffer provided and thus can cause the Hard Fault interrupt.

Here is the fix I put in place to prevent this - The changes are marked in comments.

SDIO_ConfigData(hsd->Instance, &config);

    uint32_t datacnt=0;        //*****Fix for overrun

    /* Write block(s) in polling mode */

#ifdef SDIO_STA_STBITERR

    while(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))

#else /* SDIO_STA_STBITERR not defined */

    while(!__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))

#endif /* SDIO_STA_STBITERR */

    {

        if (datacnt<NumberOfBlocks * BLOCKSIZE)        //***Fix for overrun

        {

          if(__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_TXFIFOHE))

          {

            /* Write data to SDIO Tx FIFO */

            for(count = 0U; count < 8U; count++)

            {

              SDIO_WriteFIFO(hsd->Instance, (tempbuff + count));

            }

            tempbuff += 8U;

            datacnt+=8*4;        //****Fix for overrun

          }

        }

      

      if((Timeout == 0U)||((HAL_GetTick()-tickstart) >=  Timeout))

      {

        /* Clear all the static flags */

        __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);  

        hsd->ErrorCode |= errorstate;

        hsd->State = HAL_SD_STATE_READY;

        return HAL_TIMEOUT;

      }

    }
Bertrand1
Senior

Many thanks.

With F4 V1.21.0, I had an HardFault and your patch solved the pb.

Could ST can check that and apply it on the next revision.

Bertrand

caleb
Associate III

This seems to fix it for me too on the SDMMC interface. I'll file a bug report and see what happens.

Here's my patch:

From 2077796b6f7489f6039667359553524bff41c1ab Mon Sep 17 00:00:00 2001

From: caleb crome <caleb@crome.org>

Date: Wed, 27 Feb 2019 09:50:14 -0800

Subject: [PATCH] buffer overrun fix for SDMMC on stm32f7xx_hal_sd.c

This I found this solution here https://community.st.com/s/question/0D50X00009XkWWHSA3/stm32f407-sdiosdcard?t=1551289670001

and modified it for the stm32f7 hal.

---

 Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sd.c | 3 +++

 1 file changed, 3 insertions(+)

diff --git a/Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sd.c b/Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sd.c

index 9f25343..8ba022a 100644

--- a/Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sd.c

+++ b/Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_sd.c

@@ -752,9 +752,11 @@ HAL_StatusTypeDef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint

   config.DPSM     = SDMMC_DPSM_ENABLE;

   SDMMC_ConfigData(hsd->Instance, &config);

   

+  uint32_t datacnt=0;    //*****Fix for overrun

   /* Write block(s) in polling mode */

   while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))

   {

+   if (datacnt < NumberOfBlocks * BLOCKSIZE) {//*****Fix for overrun

    if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_TXFIFOHE))

    {

     /* Write data to SDMMC Tx FIFO */

@@ -763,6 +765,7 @@ HAL_StatusTypeDef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint

      SDMMC_WriteFIFO(hsd->Instance, (tempbuff + count));

     }

     tempbuff += 8U;

+ datacnt+=8*4;}//*****Fix for overrun

    }

    

    if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))

-- 

2.17.1

Hardware flow control should be disabled on F405,407,415,417 devices, same code works ok on F412 where design has been revised. Not 100% sure on F427,F29,F439

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
caleb
Associate III

For bidirectional searching... here's a link to my bug report. I hope this gets fixed upstream:

https://community.st.com/s/question/0D50X0000ARPK0mSQH/stm32cubemx-sdmmc-fatfs-code-is-broken-with-a-buffer-overrun-here-is-a-fix

I tried disabling the hardware flow control and the buffer overrun still happens without this patch.