I’m having trouble getting the usdhc controller in the iMX6Q working with the onboard Micron MTFC4GACAJCN-4M eMMC device. Our driver works fine with SDHC cards (on SDHC2 and SDHC3). SDHC4 is connected to an eMMC device. We realize that some commands are different between SD cards and eMMC devices. The board is an OTS iMX6 Quad from Embedded Artists.
The issue is with sending CMD8 to get the extended CSD – it fails. The following commands are executed successfully before sending the CMD8: CMD0, CMD1, CMD2, CMD3, at this point the operating frequency is changed to 26 MHz per the iMX6 SDK, CMD9, CMD7 (eMMC does go to trans state), CMD6 to change to 8-bit bus, CMD16 ( 512 byte sectors – necessary??), and then CMD8.
On sending CMD8, the command is accepted (INTSTAT bit 0 is a 1), but no data transfers. We’ve tried the SDK code (PIO mode to double check) and our own code which uses DMA, but no data transfers. Here are the registers (SDK PIO mode) while waiting for data to transfer:
Note that INTSTAT is 1 (command complete), but PRSSTAT bit BREN is low meaning no data is available to read. CDIHB is high indicating transfer in progress. RTA is high indicating a data read is active. BLK_ATT shows 1 block of 512 bytes. Should SDOFF be high at this point or does that matter?
Here is the code for setting up the read:
static int32_t mmc_read_esd
(
SDHC_MemMapPtr reg_ptr
)
{
CMD cmd;
// Set block length
card_cmd_config(&cmd, CMD16, BLK_LEN, READ, RESPONSE_48, DATA_PRESENT_NONE, TRUE, TRUE);
usdhc_printf("Sending CMD16\n");
// Send CMD16
if(SUCCESS == host_send_cmd(reg_ptr, &cmd))
{
// Configure block attribute
host_cfg_block(reg_ptr, BLK_LEN, ONE, ESDHC_BLKATTR_WML_BLOCK);
// Read extended CSD
card_cmd_config(&cmd, CMD8, NO_ARG, READ, RESPONSE_48, DATA_PRESENT, TRUE, TRUE);
usdhc_printf("Sending CMD8\n");
// Send CMD8
if(SUCCESS == host_send_cmd(reg_ptr, &cmd))
{
return host_data_read(reg_ptr, (uint32_t *) ext_csd_data, BLK_LEN, ESDHC_BLKATTR_WML_BLOCK);
}
}
return(FAIL);
}
The command is accepted, and here’s the code for reading the buffer (which is the same code used to read CMD17/18 data for an SD card which works fine):
int32_t host_data_read
(
SDHC_MemMapPtr reg_ptr,
uint32_t *dst_ptr,
uint32_t length,
uint32_t wml
)
{
int32_t idx;
int32_t itr;
uint32_t loop;
// Enable Interrupt flags
reg_ptr->IRQSTATEN |= ESDHC_INTERRUPT_ENABLE;
// HW_USDHC_INT_STATUS_EN(instance).U |= ESDHC_INTERRUPT_ENABLE;
// Read data to dst_ptr
loop = length / (4 * wml); //wml is in 32-bit words - length is in bytes
for(idx = 0; idx < loop; idx++)
{
// Wait until buffer ready
while(!(reg_ptr->PRSSTAT & SDHC_PRSSTAT_BREN));
// Read from FIFO watermark words
for(itr = 0; itr < wml; itr++)
{
*dst_ptr = reg_ptr->DATPORT;
dst_ptr++;
}
}
// Read leftover data that is not WML aligned
// Note: loop is used here as the number of words left to read
loop = (length % (4 * wml)) / 4;
if(loop != 0)
{
// Wait until buffer ready
while(!(reg_ptr->PRSSTAT & SDHC_PRSSTAT_BREN));
// Read the leftover to destination buffer
for(itr = 0; itr < loop; itr++)
{
*dst_ptr = reg_ptr->DATPORT;
dst_ptr++;
}
Reading stalls waiting for the SDHC_PRSSTAT_BREN bit to be set – which never happens. This is using the SDK code.
Any ideas?
Solved! Go to Solution.
My bad - didn't read the TRM closely. When setting up the IOMUXC for the data pins I thought the pin muxes for port SDHC4 would be ALT_FUNC_0 like the other SDHC ports. Turns out they should be ALT_FUNC_1. Thanks for your help. Everything works now.
Why CMD8 for emmc in JEDEC spec should be the same CMD8 in SD Card association spec?
Hi Ken
one can test other emmc parts/boards as this particular emmc can be broken.
Also one can check procedure on i.MX6Q Sabre SD board. May be useful below link
where some emmc parts work and some not:
https://community.nxp.com/t5/i-MX-Processors/eMMC-8GB-to-4GB-crash-on-linux-yocto-boot/m-p/373231
Best regards
igor
The board came preloaded with uboot and linix on the eMMC and it does run.
>The board came preloaded with uboot and linix on the eMMC and it does run.
in such case you can debug it and compare procedure steps with failing case.
Best regards
igor
My bad - didn't read the TRM closely. When setting up the IOMUXC for the data pins I thought the pin muxes for port SDHC4 would be ALT_FUNC_0 like the other SDHC ports. Turns out they should be ALT_FUNC_1. Thanks for your help. Everything works now.
Please search the SD association spec to check if you can find the extended CSD in SD association spec, which is in the eMMC JEDEC spec. They are two different specs.