IMX6UL eMMC命令分析

转载地址:https://blog.csdn.net/TSZ0000/article/details/86499051

 

CMD0 RESET

发送CMD0 eMMC会进入自行复位busy状态后进入idle状态


 
 
  1. #define MMC_CMD_GO_IDLE_STATE 0
  2. struct mmc_cmd cmd;
  3. int err;
  4. udelay( 1000);
  5. cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
  6. cmd.cmdarg = 0;
  7. cmd.resp_type = MMC_RSP_NONE;
  8. err = mmc_send_cmd(mmc, &cmd, NULL);
  9. if (err)
  10. return err;
  11. udelay( 2000);

CMD1 CHECK_BUSY

CMD1命令得到eMMC的OCR寄存器值

代码发送命令,bit[31]为1表示ready状态,为0表示busy状态


 
 
  1. #define MMC_CMD_SEND_OP_COND 1
  2. cmd.cmdidx = MMC_CMD_SEND_OP_COND;
  3. cmd.resp_type = MMC_RSP_R3;
  4. cmd.cmdarg = 0;
  5. if (use_arg && !mmc_host_is_spi(mmc))
  6. cmd.cmdarg = OCR_HCS |
  7. (mmc->cfg->voltages &
  8. (mmc->ocr & OCR_VOLTAGE_MASK)) |
  9. (mmc->ocr & OCR_ACCESS_MODE);
  10. err = mmc_send_cmd(mmc, &cmd, NULL);
  11. if (err)
  12. return err;
  13. mmc->ocr = cmd.response[ 0];

CMD2 GET_CID

发送CMD2进行认证(获取CID),寄存器描述,128比特,16字节

代码发送命令 


 
 
  1. #define MMC_CMD_ALL_SEND_CID 2
  2. /* Put the Card in Identify Mode */
  3. cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
  4. MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
  5. cmd.resp_type = MMC_RSP_R2;
  6. cmd.cmdarg = 0;
  7. err = mmc_send_cmd(mmc, &cmd, NULL);
  8. if ( err)
  9. return err;
  10. memcpy(mmc->cid, cmd. response, 16);

打印出CID数据


 
 
  1. printf( "Manufacturer ID: %x\n", mmc->cid[ 0] >> 24);
  2. printf( "OEM: %x\n", (mmc->cid[ 0] >> 8) & 0xffff);
  3. printf( "Name: %c%c%c%c%c \n", mmc->cid[ 0] & 0xff,
  4. (mmc->cid[ 1] >> 24), (mmc->cid[ 1] >> 16) & 0xff,
  5. (mmc->cid[ 1] >> 8) & 0xff, mmc->cid[ 1] & 0xff);

 
 
  1. Manufacturer ID: fe
  2. OEM: 14e
  3. Name: P1XXX

CMD3 STBY

然后发送CMD3,之后eMMC进入stby状态


 
 
  1. #define SD_CMD_SEND_RELATIVE_ADDR 3
  2. if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
  3. cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
  4. cmd.cmdarg = mmc->rca << 16;
  5. cmd.resp_type = MMC_RSP_R6;
  6. err = mmc_send_cmd(mmc, &cmd, NULL);
  7. if ( err)
  8. return err;
  9. if (IS_SD(mmc))
  10. mmc->rca = (cmd. response[ 0] >> 16) & 0xffff;
  11. }

CMD7

使用CMD7进入transfer状态,此命令用来设置eMMC的状态,因为当使用CMD0使eMMC复位后,eMMC处于idle或pre_idle状态,如果需要数据传输,必须将eMMC置于transfer_state


 
 
  1. #define MMC_CMD_SELECT_CARD 7
  2. /* Select the card, and put it into Transfer Mode */
  3. if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
  4. cmd.cmdidx = MMC_CMD_SELECT_CARD;
  5. cmd.resp_type = MMC_RSP_R1;
  6. cmd.cmdarg = mmc->rca << 16;
  7. err = mmc_send_cmd(mmc, &cmd, NULL);
  8. if ( err)
  9. return err;
  10. }

 CMD8 

CMD8命令用来获取EXT_CSD的值,虽然回复为R1,但是EXT_CSD的512字节值会被读取并存储到内存里,然后用户可以根据这些数据分析出eMMC当前支持的各种参数和状态,EXT_CSD是eMMC4之后才引入的寄存器组


 
 
  1. struct mmc_cmd cmd;
  2. struct mmc_data data;
  3. int err;
  4. /* Get the Card Status Register */
  5. cmd.cmdidx = MMC_CMD_SEND_EXT_CSD;
  6. cmd.resp_type = MMC_RSP_R1;
  7. cmd.cmdarg = 0;
  8. data.dest = (char *)ext_csd;
  9. data.blocks = 1;
  10. data.blocksize = MMC_MAX_BLOCK_LEN;
  11. data.flags = MMC_DATA_READ;
  12. err = mmc_send_cmd(mmc, &cmd, & data);

CMD9 GET_CSD

获取CSD寄存器值,描述如下

代码实现 


 
 
  1. #define MMC_CMD_SEND_CSD 9
  2. /* Get the Card-Specific Data */
  3. cmd.cmdidx = MMC_CMD_SEND_CSD;
  4. cmd.resp_type = MMC_RSP_R2;
  5. cmd.cmdarg = mmc->rca << 16;
  6. err = mmc_send_cmd(mmc, &cmd, NULL);
  7. /* Waiting for the ready status */
  8. mmc_send_status(mmc, timeout);
  9. if (err)
  10. return err;
  11. mmc->csd[ 0] = cmd.response[ 0];
  12. mmc->csd[ 1] = cmd.response[ 1];
  13. mmc->csd[ 2] = cmd.response[ 2];
  14. mmc->csd[ 3] = cmd.response[ 3];

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值