Skip to main content
Visitor II
November 12, 2024
Question

STM32H7 SDMMC ACMD51

  • November 12, 2024
  • 1 reply
  • 717 views

Hello,

I'm migrating the code from stm32f4 to stm32h7 and stuck with SDMMC ACMD51 command. This command reads SD configuration register via data lines (8 bytes total).

Is there is any way to configure this request to set DBCKCEND flag when it receives all bytes? Or FIFO flags polling only the way?

Here is my attempt to do it:

 

#define SDIO SDMMC1
#define SD_ACMD51 51|SDMMC_RESPONSE_SHORT|SDMMC_WAIT_NO|SDMMC_CPSM_ENABLE|SDMMC_CMDTRANS

SDIO->DTIMER = 0xFFFFFF;
SDIO->DLEN = 8;
SDIO->DCTRL = SDMMC_DCTRL_RWSTART|(3<<SDMMC_DCTRL_DBLOCKSIZE_Pos)|SDMMC_DCTRL_DTDIR;
result= sdio_send_acmd_blocking(SD_ACMD51, 0);
if(result!=0) return result;
result = wait_for_sd_data_ready(); //waiting for DBCKCEND interrupt

 

 

    This topic has been closed for replies.

    1 reply

    AShir.10Author
    Visitor II
    November 14, 2024

    So, I found a solution by using IDMA:

    	SDIO->ICR= SDMMC_ICR_DATAENDC;
    //32 bytes minimum burst, but if DLEN < 32 bytes it will only transfer DLEN bytes
    //see page 2408 of RM0433
    	SDIO->IDMABSIZE = 1<<5;
    	SDIO->IDMABASE0 = (size_t)&SDIO_m.SCR[0].word; 
    	SDIO->IDMACTRL = SDMMC_IDMA_IDMAEN;
    	SDIO->DLEN = 8;
    	SDIO->DCTRL = (3<<4)|(1<<1);
    // need to set CMDTRANS bit that after this command 
    //it will enable Data Path State Machine
    	result= sdio_send_acmd_blocking(SD_ACMD51|SDMMC_CMD_CMDTRANS, 0); 
    	if(result!=0) 
    		return result;
    	if((SDIO_m.sdio_last_status)&SDIO_ERR_FLAGS) 
    		return ((SDIO_m.sdio_last_status)&SDIO_ERR_FLAGS);
    	SDIO->MASK |= SDMMC_MASK_DATAENDIE;
    	result = wait_for_sd_data_ready(); //waiting for DATAEND interrupt
    	SDIO->IDMACTRL = 0;
    	SDIO->MASK &= ~SDMMC_MASK_DATAENDIE;
    	if((SDIO_m.sdio_last_status)&SDIO_ERR_FLAGS) 
    		return ((SDIO_m.sdio_last_status)&SDIO_ERR_FLAGS);
    	SDIO_m.SCR[1].word = __REV(SDIO_m.SCR[1].word);
    	SDIO_m.SCR[0].word = __REV(SDIO_m.SCR[0].word);
    	swap_words(&SDIO_m.SCR[0].word);

    Data transfer end will rise DATAEND flag.