cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 SDMMC ACMD51

AShir.10
Associate II

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

 

 

1 REPLY 1
AShir.10
Associate II

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.