Go Down

Topic: SD card initialization in SD mode (Read 436 times) previous topic - next topic

Owais

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

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

Owais

#2
Sep 05, 2014, 12:10 pm Last Edit: Sep 06, 2014, 12:16 am by Owais Reason: 1
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.

Code: [Select]

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 );
}


Code: [Select]

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;
}

Go Up