2016-07-13 09:24 AM
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 flagSDMMC_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; } } }2016-07-14 05:57 AM
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-2016-07-14 07:04 AM
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.2016-07-14 07:57 AM
Hi luo.xinheng,
I check the Erratasheet relevant of your device 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-2016-07-14 08:22 AM
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
2016-07-14 09:35 AM
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-2016-07-15 02:33 AM
Hi luo.xinheng,
Yes, I confirm. It iwill be fixed in the coming firmware library release. -Hannibal-