Skip to main content
Visitor II
April 14, 2018
Question

SDMMC STM32f7 - SDMMC_GetCmdResp1() gets stuck

  • April 14, 2018
  • 3 replies
  • 4572 views
Posted on April 14, 2018 at 23:13

Hey everyone,

My app based on STM32CubeF7 Firmware Package V1.11.0 / 23-February-2018 gets stuck in SDMMC_GetCmdResp1() during directory scan randomly - it can stuck just after switching on or after 2 minutes of working. I can do nothing with sd until I switch off and switch on SD power.

0690X0000060AXFQA2.png

I found a ''solution'' by adding delay:

uint32_t SDMMC_CmdSendStatus(SDMMC_TypeDef *SDMMCx, uint32_t Argument)

{

SDMMC_CmdInitTypeDef sdmmc_cmdinit;

uint32_t errorstate = SDMMC_ERROR_NONE;

sdmmc_cmdinit.Argument = (uint32_t)Argument;

sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_STATUS;

sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT;

sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO;

sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE;

HAL_Delay(1);

SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit);

/* Check for error conditions */

errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SEND_STATUS, SDMMC_CMDTIMEOUT);

return errorstate;

}

it works good, without any issues, but very slow.

The second solution is disabling all other FreeRTOS Tasks that use about 50% CPU.

How to make it work in real world?

UPDATE: I found that in some cases before timeout I get SDMMC_ERROR_CMD_CRC_FAIL

0690X0000060AarQAE.png

#sd #stm32f7 #dma-sdmmc #sdmmc
    This topic has been closed for replies.

    3 replies

    Visitor II
    April 26, 2018
    Posted on April 26, 2018 at 15:55

    Eventually I found a solution on my own. It's strange, but not stranger than HAL libraries

    Working code:

    DRESULT SD_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)
    {
     DRESULT res = RES_ERROR;
     osEvent event;
     uint32_t timer;
     uint32_t alignedAddr = (uint32_t)buff & ~0x1F;
    if(count < 2)
    {
    if( BSP_SD_ReadBlocks((uint32_t*)buff,
    (uint32_t) (sector),
    count,SD_TIMEOUT) == MSD_OK)
    timer = osKernelSysTick() + SD_TIMEOUT;
    /* block until SDIO IP is ready or a timeout occur */
    while(timer > osKernelSysTick())
    {
     if (BSP_SD_GetCardState() == SD_TRANSFER_OK)
     {
    res = RES_OK;
    break;
     }
    }
    }
    else
    {
    #if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)
     if((uint32_t)buff < 0x60000000 && (uint32_t)buff >= 0x20010000)
     {
     //buff not in uncacheable SDRAM or DTCMRAM
     alignedAddr = (uint32_t)buff & ~0x1F;
     //save data near the beginning and the end of a cache to RAM
     SCB_CleanDCache_by_Addr((uint32_t*)alignedAddr, 32);
     SCB_CleanDCache_by_Addr((uint32_t*)alignedAddr + count*BLOCKSIZE, 32);
     }
    #endif
     //clean queue
     do{
     event = osMessageGet(SDQueueID, 0);
     }while(event.status == osEventMessage);
     if(BSP_SD_ReadBlocks_DMA((uint32_t*)buff,
    (uint32_t) (sector),
    count) == MSD_OK)
     {
    /* wait for a message from the queue or a timeout */
    event = osMessageGet(SDQueueID, SD_TIMEOUT);
    if (event.status == osEventMessage)
    {
     if (event.value.v == READ_CPLT_MSG)
     {
    timer = osKernelSysTick() + SD_TIMEOUT;
    /* block until SDIO IP is ready or a timeout occur */
    while(timer > osKernelSysTick())
    {
     if (BSP_SD_GetCardState() == SD_TRANSFER_OK)
     {
    res = RES_OK;
    #if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)
    /*
     the SCB_InvalidateDCache_by_Addr() requires a 32-Byte aligned address,
     adjust the address and the D-Cache size to invalidate accordingly.
     */
    if((uint32_t)buff < 0x60000000 && (uint32_t)buff >= 0x20010000)
    {
    //buff not in uncacheable SDRAM or DTCMRAM
    SCB_InvalidateDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr));
    }
    #endif
    break;
     }
    }
     }
    }
     }
    }
    return res;
    }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

    and

    DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
    {
     DRESULT res = RES_ERROR;
     osEvent event;
     uint32_t timer;
    #if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)
     uint32_t alignedAddr;
     /*
     the SCB_CleanDCache_by_Addr() requires a 32-Byte aligned address
     adjust the address and the D-Cache size to clean accordingly.
     */
     if((uint32_t)buff < 0x60000000 && (uint32_t)buff >= 0x20010000){
     alignedAddr = (uint32_t)buff & ~0x1F;
     SCB_CleanDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr));
     }
    #endif
     if(count < 2)
     {
     if(BSP_SD_WriteBlocks((uint32_t*)buff,
     (uint32_t) (sector),
     count, SD_TIMEOUT) == MSD_OK)
     {
     uint32_t timer = osKernelSysTick() + SD_TIMEOUT;
     /* block until SDIO IP is ready or a timeout occur */
     while(timer > osKernelSysTick())
     {
     if (BSP_SD_GetCardState() == SD_TRANSFER_OK)
     {
     res = RES_OK;
     break;
     }
     }
     }
     }
     else
     {
     //clean queue
     do{
     event = osMessageGet(SDQueueID, 0);
     }while(event.status == osEventMessage);
     if(BSP_SD_WriteBlocks_DMA((uint32_t*)buff,
    (uint32_t) (sector),
    count) == MSD_OK)
     {
    /* Get the message from the queue */
    event = osMessageGet(SDQueueID, SD_TIMEOUT);
    if (event.status == osEventMessage)
    {
     if (event.value.v == WRITE_CPLT_MSG)
     {
    timer = osKernelSysTick() + SD_TIMEOUT;
    /* block until SDIO IP is ready or a timeout occur */
    while(timer > osKernelSysTick())
    {
     if (BSP_SD_GetCardState() == SD_TRANSFER_OK)
     {
    res = RES_OK;
    break;
     }
    }
     }
    }
     }
     }
     return res;
    }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

    It works, not really perfectly, I get reading errors sometimes. Will update.

    Visitor II
    May 25, 2018
    Posted on May 25, 2018 at 08:17

    Hi Konstantin, I have the same problem, please did you find a definitive solution at he problem?

    Beast regards

    Visitor II
    May 27, 2018
    Posted on May 27, 2018 at 20:28

    Unfortunately, no. I've spent weeks and checked many solution with no success.

    Visitor II
    July 15, 2018
    Posted on July 15, 2018 at 18:01

    I am trying to write an image to SD card and I have exactly the same error. Using STM32 F746 discovery, no RTOS. My program is based on the STM provided example STM32Cube_FW_F7_V1.11.0/Projects/STM32746G-Discovery/Applications/FatFs/FatFs_uSD.

    The program was unstable, since I was receiving those sd underrun errors. I then tried reconfiguring the example to use DMA for reading/writing, but now I am getting stuck at the same point as original post here (SDMMC_GetCmdResp1() ).

    I&39m a begginner and obviously I am not the only one struggling with this. I&39m really confused, since the DMA seems to be initialized correctly(?) in BSP_SD_MspInit() and I changed sd_diskio.c read and write functions from BSP_SD_ReadBlocks() to BSP_SD_ReadBlocks_DMA() (and the same for write). I also tried implementing test/empty IRQ callback, but the code never reaches them. Did I forget something obvious?

    Turvey.Clive.002

      Would it be possible to get an working example with FatFS+SD card, no RTOS on STM32F746 discovery board?

    Graduate II
    July 15, 2018
    Posted on July 15, 2018 at 19:08

    Drop me an email at

    mailto:sourcer32@gmail.com

    I'll port the template over to V1.11.0
    Visitor II
    July 16, 2018
    206230CGIL3
    Graduate II
    August 15, 2024

    Hi all,

    Are there any solutions for the issue described here?

    I face the same problem, getting SDMMC_ERROR_CMD_RSP_TIMEOUT in SDMMC_GetCmdResp1(). No matter whether I use DMA or not.

    Goal of the application is to write sensor values to the uSD from my application and read the values via USB. I use Eclipse (Azure) ThreadX and FileX. I'm able to create files, but not writing into them.

    However, accessing the uSD from USB with USBX works fine. I can write files, using the same SDIO functionality. (Assuring by my SW that not both (USBX and FileX) access SDIO at the same time).

    Any help appreciated.
    Denise