转载地址:https://blog.csdn.net/TSZ0000/article/details/86499051
CMD0 RESET
发送CMD0 eMMC会进入自行复位busy状态后进入idle状态
-
#define MMC_CMD_GO_IDLE_STATE 0
-
-
struct mmc_cmd cmd;
-
int err;
-
udelay(
1000);
-
-
cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
-
cmd.cmdarg =
0;
-
cmd.resp_type = MMC_RSP_NONE;
-
-
err = mmc_send_cmd(mmc, &cmd,
NULL);
-
if (err)
-
return err;
-
udelay(
2000);
CMD1 CHECK_BUSY
CMD1命令得到eMMC的OCR寄存器值
代码发送命令,bit[31]为1表示ready状态,为0表示busy状态
-
#define MMC_CMD_SEND_OP_COND 1
-
-
cmd.cmdidx = MMC_CMD_SEND_OP_COND;
-
cmd.resp_type = MMC_RSP_R3;
-
cmd.cmdarg =
0;
-
if (use_arg && !mmc_host_is_spi(mmc))
-
cmd.cmdarg = OCR_HCS |
-
(mmc->cfg->voltages &
-
(mmc->ocr & OCR_VOLTAGE_MASK)) |
-
(mmc->ocr & OCR_ACCESS_MODE);
-
-
err = mmc_send_cmd(mmc, &cmd,
NULL);
-
if (err)
-
return err;
-
mmc->ocr = cmd.response[
0];
CMD2 GET_CID
发送CMD2进行认证(获取CID),寄存器描述,128比特,16字节
代码发送命令
-
#define MMC_CMD_ALL_SEND_CID
2
-
-
/* Put the Card
in Identify Mode */
-
cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
-
MMC_CMD_ALL_SEND_CID; /* cmd
not supported
in spi */
-
cmd.resp_type = MMC_RSP_R2;
-
cmd.cmdarg =
0;
-
-
err = mmc_send_cmd(mmc, &cmd,
NULL);
-
-
if (
err)
-
return
err;
-
-
memcpy(mmc->cid, cmd.
response,
16);
打印出CID数据
-
printf(
"Manufacturer ID: %x\n", mmc->cid[
0] >>
24);
-
printf(
"OEM: %x\n", (mmc->cid[
0] >>
8) &
0xffff);
-
printf(
"Name: %c%c%c%c%c \n", mmc->cid[
0] &
0xff,
-
(mmc->cid[
1] >>
24), (mmc->cid[
1] >>
16) &
0xff,
-
(mmc->cid[
1] >>
8) &
0xff, mmc->cid[
1] &
0xff);
-
Manufacturer ID: fe
-
OEM:
14e
-
Name: P1XXX
CMD3 STBY
然后发送CMD3,之后eMMC进入stby状态
-
#define SD_CMD_SEND_RELATIVE_ADDR
3
-
-
if (!mmc_host_is_spi(mmc)) { /* cmd
not supported
in spi */
-
cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
-
cmd.cmdarg = mmc->rca <<
16;
-
cmd.resp_type = MMC_RSP_R6;
-
-
err = mmc_send_cmd(mmc, &cmd,
NULL);
-
-
if (
err)
-
return
err;
-
-
if (IS_SD(mmc))
-
mmc->rca = (cmd.
response[
0] >>
16) &
0xffff;
-
}
CMD7
使用CMD7进入transfer状态,此命令用来设置eMMC的状态,因为当使用CMD0使eMMC复位后,eMMC处于idle或pre_idle状态,如果需要数据传输,必须将eMMC置于transfer_state
-
#define MMC_CMD_SELECT_CARD
7
-
-
/*
Select the card,
and put it into Transfer Mode */
-
if (!mmc_host_is_spi(mmc)) { /* cmd
not supported
in spi */
-
cmd.cmdidx = MMC_CMD_SELECT_CARD;
-
cmd.resp_type = MMC_RSP_R1;
-
cmd.cmdarg = mmc->rca <<
16;
-
err = mmc_send_cmd(mmc, &cmd,
NULL);
-
-
if (
err)
-
return
err;
-
}
CMD8
CMD8命令用来获取EXT_CSD的值,虽然回复为R1,但是EXT_CSD的512字节值会被读取并存储到内存里,然后用户可以根据这些数据分析出eMMC当前支持的各种参数和状态,EXT_CSD是eMMC4之后才引入的寄存器组
-
struct mmc_cmd cmd;
-
struct mmc_data
data;
-
int err;
-
-
/* Get the Card Status Register */
-
cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
-
cmd.resp_type = MMC_RSP_R1;
-
cmd.cmdarg =
0;
-
-
data.dest = (char *)ext_csd;
-
data.blocks =
1;
-
data.blocksize = MMC_MAX_BLOCK_LEN;
-
data.flags = MMC_DATA_READ;
-
-
err = mmc_send_cmd(mmc, &cmd, &
data);
CMD9 GET_CSD
获取CSD寄存器值,描述如下
代码实现
-
#define MMC_CMD_SEND_CSD 9
-
-
/* Get the Card-Specific Data */
-
cmd.cmdidx = MMC_CMD_SEND_CSD;
-
cmd.resp_type = MMC_RSP_R2;
-
cmd.cmdarg = mmc->rca <<
16;
-
-
err = mmc_send_cmd(mmc, &cmd,
NULL);
-
-
/* Waiting for the ready status */
-
mmc_send_status(mmc, timeout);
-
-
if (err)
-
return err;
-
-
mmc->csd[
0] = cmd.response[
0];
-
mmc->csd[
1] = cmd.response[
1];
-
mmc->csd[
2] = cmd.response[
2];
-
mmc->csd[
3] = cmd.response[
3];