cancel
Showing results for 
Search instead for 
Did you mean: 

CubeMx 4.15.1 + STM32L476RC + 1.5.1 + FatFS SD

Luo.Xinheng
Associate II
Posted on July 13, 2016 at 18:24

hello sir.

my project write SD card error, but it read SD card properly.

when I debug into code, I found 

__HAL_SD_SDMMC_GET_FLAG()

in 

HAL_SD_WriteBlocks()

function

 always get error flag 

SDMMC_FLAG_DCRCFAIL

. and it write nothing to SD card.

I checked my hardware, but it is OK. 

what wrong with my program?

  if(NumberOfBlocks > 1)

  {

    ......

  }

  else

  {

    /* Check for error conditions */

    errorstate = SD_CmdResp1Error(hsd, SD_CMD_READ_SINGLE_BLOCK); 

    

    if (errorstate != SD_OK)

    {

      return errorstate;

    }    

    

    /* In case of single block transfer, no need of stop transfer at all */

   

while(!__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND))

    {

      if (__HAL_SD_SDMMC_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF))

      {

        /* Read data from SDMMC Rx FIFO */

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

        {

          *(tempbuff + count) = SDMMC_ReadFIFO(hsd->Instance);

        }

        

        tempbuff += 8;

      }

    }   

  }

6 REPLIES 6
Walid FTITI_O
Senior II
Posted on July 14, 2016 at 14:57

Hi luo.xinheng,

It is mentioned in the reference manual that:

“During block write (CMD24 - 27) one or more blocks of data are transferred from the host to

the card with a CRC appended to the end of each block by the host. A card supporting block

write is always able to accept a block of data defined by WRITE_BL_LEN. If the CRC fails,

the card indicates the failure on the SDIO_D line and the transferred data are discarded and

not written, and all further transmitted blocks (in multiple block write mode) are ignored.�

Check if the dummy CRC value is correct ?

Are you using the ''HW flow control '' ?

-> Because there is a limitation mentionned in the relevant STM32F40x and STM32F41x Errata sheet:

''When enabling the HW flow control by setting bit 14 of the SDIO_CLKCR register to ‘1’, glitches can occur on the SDIOCLK output clock resulting in wrong data to be written into the SD/MMC card or into the SDIO device. As a consequence, a CRC error will be reported to the SD/SDIO MMC host interface (DCRCFAIL bit set to ‘1’ in SDIO_STA register).

Workaround None. Note: Do not use the HW flow control. Overrun errors (Rx mode) and FIFO underrun (Tx mode) should be managed by the application software

''

-Hannibal-

Luo.Xinheng
Associate II
Posted on July 14, 2016 at 16:04

thanks Hannibal. and I have some problems:

1. If DCRC error, then no data is writted, it OK;

2. No matter I use HW flow control or not, the project write SD card error as before.

3. I don't know how to write or check CRC value, I don't find any CRC function in the stm32CubeMX, Would you tell me where is it?

4. I have use stm32F411RE, and the program is same approximately, and it work OK. but when I copy it to stm32L476RC, it work wrong.

5. I only find how to setup  HardwareFlowControl,but how to disable FIFO underrun (Tx mode)?

/* SDMMC1 init function */

static void MX_SDMMC1_SD_Init(void)

{

  hsd1.Instance = SDMMC1;

  hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;

  hsd1.Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE;

  hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;

  hsd1.Init.BusWide = SDMMC_BUS_WIDE_1B;

  hsd1.Init.HardwareFlowControl=SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;

  hsd1.Init.ClockDiv = 0;

}

Thanks.

Walid FTITI_O
Senior II
Posted on July 14, 2016 at 16:57

Hi luo.xinheng,

I check the Erratasheet relevant of your device

http://www.st.com/content/ccc/resource/technical/document/errata_sheet/65/dd/2c/78/59/b0/4c/68/DM00111498.pdf/files/DM00111498.pdf/jcr:content/translations/en.DM00111498.pdf

and the solution of your problem is there:

2.7.1 Wrong CCRCFAIL status after a response without CRC is received

Description

The CRC is calculated even if the response to a command does not contain any CRC field. As a consequence, after the SDIO command IO_SEND_OP_COND (CMD5) is sent, the CCRCFAIL bit of the SDMMC_STA register is set.

Workaround

The CCRCFAIL bit in the SDMMC_STA register shall be ignored by the software. CCRCFAIL must be cleared by setting CCRCFAILC bit of the SDMMC_ICR register after reception of the response to the CMD5 command.

Apply the workaround and everything will be OK.

-Hannibal-

Luo.Xinheng
Associate II
Posted on July 14, 2016 at 17:22

Hi,Hannibal.

I know what wrong with the program.

In \Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_ll_sdmmc.h , it define 

#define SDMMC_DATABLOCK_SIZE_1B ((uint32_t)0x00000000)

#define SDMMC_DATABLOCK_SIZE_2B SDMMC_DCTRL_DBLOCKSIZE_0

#define SDMMC_DATABLOCK_SIZE_4B SDMMC_DCTRL_DBLOCKSIZE_1

#define SDMMC_DATABLOCK_SIZE_8B (SDMMC_DCTRL_DBLOCKSIZE_0|SDMMC_DCTRL_DBLOCKSIZE_1)

#define SDMMC_DATABLOCK_SIZE_16B SDMMC_DCTRL_DBLOCKSIZE_2

#define SDMMC_DATABLOCK_SIZE_32B (SDMMC_DCTRL_DBLOCKSIZE_0|SDMMC_DCTRL_DBLOCKSIZE_2)

#define SDMMC_DATABLOCK_SIZE_64B (SDMMC_DCTRL_DBLOCKSIZE_1|SDMMC_DCTRL_DBLOCKSIZE_2)

#define SDMMC_DATABLOCK_SIZE_128B

(SDMMC_DCTRL_DBLOCKSIZE_0|SDMMC_DCTRL_DBLOCKSIZE_1|SDMMC_DCTRL_DBLOCKSIZE_2)

#define SDMMC_DATABLOCK_SIZE_256B             SDMMC_DCTRL_DBLOCKSIZE_3

#define SDMMC_DATABLOCK_SIZE_512B             (SDMMC_DCTRL_DBLOCKSIZE_0|SDMMC_DCTRL_DBLOCKSIZE_3)

#define SDMMC_DATABLOCK_SIZE_1024B            (SDMMC_DCTRL_DBLOCKSIZE_1|SDMMC_DCTRL_DBLOCKSIZE_3)

#define SDMMC_DATABLOCK_SIZE_2048B            (SDMMC_DCTRL_DBLOCKSIZE_0|SDMMC_DCTRL_DBLOCKSIZE_1|SDMMC_DCTRL_DBLOCKSIZE_3) 

#define SDMMC_DATABLOCK_SIZE_4096B            (SDMMC_DCTRL_DBLOCKSIZE_2|SDMMC_DCTRL_DBLOCKSIZE_3)

#define SDMMC_DATABLOCK_SIZE_8192B            (SDMMC_DCTRL_DBLOCKSIZE_0|SDMMC_DCTRL_DBLOCKSIZE_2|SDMMC_DCTRL_DBLOCKSIZE_3)

#define SDMMC_DATABLOCK_SIZE_16384B           (SDMMC_DCTRL_DBLOCKSIZE_1|SDMMC_DCTRL_DBLOCKSIZE_2|SDMMC_DCTRL_DBLOCKSIZE_3)

and in \Drivers\CMSIS\Device\ST\STM32L4xx\Include\stm32l476xx.h

#define SDMMC_DCTRL_DBLOCKSIZE_Pos           (4U)                       

#define SDMMC_DCTRL_DBLOCKSIZE_0             (0x1U << SDMMC_DCTRL_DBLOCKSIZE_Pos) /*!< 0x00000010 */

#define SDMMC_DCTRL_DBLOCKSIZE_1             (0x2U << SDMMC_DCTRL_DBLOCKSIZE_Pos) /*!< 0x00000020 */

#define SDMMC_DCTRL_DBLOCKSIZE_2             (0x3U << SDMMC_DCTRL_DBLOCKSIZE_Pos) /*!< 0x00000040 */

#define SDMMC_DCTRL_DBLOCKSIZE_3             (0x4U << SDMMC_DCTRL_DBLOCKSIZE_Pos) /*!< 0x00000080 */

but we know , it equal define

#define SDMMC_DCTRL_DBLOCKSIZE_Pos           (4U)                       

#define SDMMC_DCTRL_DBLOCKSIZE_0           0x10U  /*!< 0x00000010 */

#define SDMMC_DCTRL_DBLOCKSIZE_1           0x20U  /*!< 0x00000020 */

#define SDMMC_DCTRL_DBLOCKSIZE_2           0x30U  /*!< 0x00000040 */

#define SDMMC_DCTRL_DBLOCKSIZE_3           0x40U  /*!< 0x00000080 */

it is wrong!

the corrent define is:

#define SDMMC_DCTRL_DBLOCKSIZE_Pos           (4U)                       

#define SDMMC_DCTRL_DBLOCKSIZE_0             (0x1U << SDMMC_DCTRL_DBLOCKSIZE_Pos) /*!< 0x00000010 */

#define SDMMC_DCTRL_DBLOCKSIZE_1             (0x2U << SDMMC_DCTRL_DBLOCKSIZE_Pos) /*!< 0x00000020 */

#define SDMMC_DCTRL_DBLOCKSIZE_2             (0x4U << SDMMC_DCTRL_DBLOCKSIZE_Pos) /*!< 0x00000040 */

#define SDMMC_DCTRL_DBLOCKSIZE_3             (0x8U << SDMMC_DCTRL_DBLOCKSIZE_Pos) /*!< 0x00000080 */

I correct this error, and my program is OK.

Luo Xinheng

Walid FTITI_O
Senior II
Posted on July 14, 2016 at 18:35

Hi luo.xinheng,

I see now tha you are talking about DCRCFAIL which is not concerned by the Erratasheet note.

So are you using our hardware or your own ? check the SDIO connection and of there is noise .

-Hannibal-

Walid FTITI_O
Senior II
Posted on July 15, 2016 at 11:33

Hi luo.xinheng,

Yes, I confirm. It iwill be fixed in the coming firmware library release.

-Hannibal-