SD card initialization in SD mode

Hello everyone,

I am trying to initialize an SD card in SD mode on SAM4. Since the HSMCI interface is teh same as SAM3 can anybody help me in this regard. I have configured the HSMCI interface but when I am sending commands to SD card I get failures.

Any help would be appreciated.

Regards,
Owais

Hello,

To be more clear about my situation, I have initialized the HSMCI interface of SAM4S. The clock is set at 400kHz and bus width at 1-bit for initialization of SD card. Secondly the SD card command CMD0, CMD8, CMD55, ACMD41, CMD2, CMD3 are executed successfully and the Relative Card Address is received as 45928. I am using a 4GB Micro SD HC card. After this, CMD9, CMD7, ACMD51 fail to execute and the card cannot be set into High Speed mode. I have tried this whole process in AS Example Unit Test and there it works without any of these issues. I am simple initializing the HSMCI interface and then the SD card. Though AS example does some other stuff that I am not following. Any help would be appreciated.

Regards,
Owais

Hello,

For more information I have included the code that I am using to initialize the HSMCI interface as well as the SD card as follows. If someone needs more detail please do ask.

uint32_t hsmci_init(void)
{
	//enable MCI's clock
	PMC->PMC_PCER0 = PMC_PCER0_PID18;
	//configure PIOs to be controlled by MCI
	PIOA->PIO_PDR = PINS_MCI;
	PIOA->PIO_IDR = PINS_MCI;
	PIOA->PIO_ABCDSR[0] &= ~PINS_MCI; // 0 - Peripheral C
	PIOA->PIO_ABCDSR[1] |=  PINS_MCI; // 1 - Peripheral C
	//PIOA->PIO_PUER = PINS_MCI; //Pullup enable
	// configure card detect pin
	PMC->PMC_PCER0 = PMC_PCER0_PID11;
	PIOA->PIO_PER = PIN_CDMCI;
	PIOA->PIO_IDR = PIN_CDMCI;
	PIOA->PIO_ODR = PIN_CDMCI;
	//PIOA->PIO_PUER = PIN_CDMCI;

	//configure MCI regs
	//perform software reset
	HSMCI->HSMCI_CR = HSMCI_CR_SWRST;
	// Set the Data Timeout Register to 2 Mega Cycles
	HSMCI->HSMCI_DTOR = HSMCI_DTOR_DTOMUL_1048576 | HSMCI_DTOR_DTOCYC(2);
	// Set Completion Signal Timeout to 2 Mega Cycles
	HSMCI->HSMCI_CSTOR = HSMCI_CSTOR_CSTOMUL_1048576 | HSMCI_CSTOR_CSTOCYC(2);
	// Set Configuration Register
	HSMCI->HSMCI_CFG = HSMCI_CFG_FIFOMODE | HSMCI_CFG_FERRCTRL;
	// Set power saving to maximum value
	HSMCI->HSMCI_MR = HSMCI_MR_PWSDIV_Msk;
	// Enable the HSMCI and the Power Saving
	HSMCI->HSMCI_CR = HSMCI_CR_MCIEN | HSMCI_CR_PWSEN;
	
	const uint8_t CLKDIV = 0x95;	
	const uint32_t MCI_CLKDIV_MASK = (uint32_t)CLKDIV;	//120MHz/(2x(CLKDIV+1)) = 400kHz
	const uint32_t MCI_BLKLEN_MASK = (uint32_t)(512 << 16);
	
	//set MCI Mode Register
#if HSMCI_MR_PDCMODE // In case of DMA enable force byte transfer
	HSMCI->HSMCI_MR = MCI_BLKLEN_MASK | MCI_CLKDIV_MASK | HSMCI_MR_FBYTE| HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF;
#else
	HSMCI->HSMCI_MR = MCI_BLKLEN_MASK | MCI_CLKDIV_MASK | HSMCI_MR_RDPROOF | HSMCI_MR_WRPROOF;
#endif

	//configure SDCR register select slot A and set 4 bit bus width
	HSMCI->HSMCI_SDCR = HSMCI_SDCR_SDCSEL_SLOTA | HSMCI_SDCR_SDCBUS_1;
	return ( OK );
}
uint32_t sd_init(void)
{
	//Index of current slot configured
	static uint8_t sd_mmc_slot_sel = 0;
	sd_mmc_card->type = CARD_TYPE_SD;
	sd_mmc_card->version = CARD_VER_UNKNOWN;
	sd_mmc_card->rca = 0;
	uint8_t v2 = 0;
	
	// Card need of 74 cycles clock minimum to start
	hsmci_send_clock();
	// CMD0 - Reset all cards to idle state.
	if (!hsmci_send_cmd(SDMMC_MCI_CMD0_GO_IDLE_STATE, 0))
	{
		//return FAIL;
		printf("CMD0 failed\n\r");
	}
	if (!sd_cmd8(&v2))
	{
		//return FAIL;
		printf("CMD8 failed\n\r");
	}
	// Try to get the SD card's operating condition
	if (!sd_mci_op_cond(v2))
	{
		//It is not a SD card
		//return FAIL;
		printf("Not a valid SD card\n\r");
	}
	// SD MEMORY, Put the Card in Identify Mode
	// Note: The CID is not used in this stack
	if (!hsmci_send_cmd(SDMMC_CMD2_ALL_SEND_CID, 0))
	{
		//return FAIL;
		printf("CMD2 failed\n\r");
	}
	// Ask the card to publish a new relative address (RCA).
	if (!hsmci_send_cmd(SD_CMD3_SEND_RELATIVE_ADDR, 0))
	{
		//return FAIL;
		printf("CMD3 failed\n\r");
	}
	sd_mmc_card->rca = (hsmci_get_response() >> 16) & 0xFFFF;
	printf("Card relative address is : %d\n\r", sd_mmc_card->rca);
	// SD MEMORY, Get the Card-Specific Data
	if (!hsmci_send_cmd(SDMMC_MCI_CMD9_SEND_CSD, sd_mmc_card->rca << 16))
	{
		//return FAIL;
		printf("CMD9 failed\n\r");
	}
	hsmci_get_response_128(sd_mmc_card->csd);
	sd_decode_csd();
		
	// Select the SD card and put it into Transfer Mode
	if (!hsmci_send_cmd(SDMMC_CMD7_SELECT_CARD_CMD, sd_mmc_card->rca << 16))
	{
		//return FAIL;
		printf("Failed to execute CMD7\n\r");
	}
	
	// SD MEMORY, Read the SCR to get card version
	if (!sd_acmd51())
	{
		//return FAIL;
		printf("ACMD51 failed\n\r");
	}
	if ((4 <= hsmci_get_bus_width(sd_mmc_slot_sel)))
	{
		// TRY to enable 4-bit mode
		if (!sd_acmd6())
		{
			//return FAIL;
			printf("ACMD6 failed\n\r");
		}
		// Switch to selected bus mode
		sd_mmc_configure_slot();
	}
	if (hsmci_is_high_speed_capable())
	{
		// TRY to enable High-Speed Mode		
		if (!sd_cm6_set_high_speed())
		{
			//return FAIL;
			printf("High Speed not set\n\r");
		}
		// Valid new configuration
		sd_mmc_configure_slot();
	}
	// SD MEMORY, Set default block size
	if (!hsmci_send_cmd(SDMMC_CMD16_SET_BLOCKLEN, SD_MMC_BLOCK_SIZE))
	{
		//return FAIL;
		printf("CMD16 failed\n\r");
	}
	return OK;
}