一、core.h 中的命令和响应定义
1.1 命令结构体定义
c
struct mmc_command {
u32 opcode;
u32 arg;
#define MMC_CMD23_ARG_REL_WR (1 << 31)
#define MMC_CMD23_ARG_PACKED ((0 << 31) | (1 << 30))
#define MMC_CMD23_ARG_TAG_REQ (1 << 29)
u32 resp[4];
unsigned int flags; /* expected response type */
#define MMC_RSP_PRESENT (1 << 0)
#define MMC_RSP_136 (1 << 1) /* 136 bit response */
#define MMC_RSP_CRC (1 << 2) /* expect valid crc */
#define MMC_RSP_BUSY (1 << 3) /* card may send busy */
#define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */
#define MMC_CMD_MASK (3 << 5) /* non-SPI command type */
#define MMC_CMD_AC (0 << 5)
#define MMC_CMD_ADTC (1 << 5)
#define MMC_CMD_BC (2 << 5)
#define MMC_CMD_BCR (3 << 5)
#define MMC_RSP_SPI_S1 (1 << 7) /* one status byte */
#define MMC_RSP_SPI_S2 (1 << 8) /* second byte */
#define MMC_RSP_SPI_B4 (1 << 9) /* four data bytes */
#define MMC_RSP_SPI_BUSY (1 << 10) /* card may send busy */
/*
* These are the native response types, and correspond to valid bit
* patterns of the above flags. One additional valid pattern
* is all zeros, which means we don't expect a response.
*/
#define MMC_RSP_NONE (0)
#define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R1B (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
#define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
#define MMC_RSP_R3 (MMC_RSP_PRESENT)
#define MMC_RSP_R4 (MMC_RSP_PRESENT)
#define MMC_RSP_R5 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R7 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define mmc_resp_type(cmd) ((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE))
/*
* These are the SPI response types for MMC, SD, and SDIO cards.
* Commands return R1, with maybe more info. Zero is an error type;
* callers must always provide the appropriate MMC_RSP_SPI_Rx flags.
*/
#define MMC_RSP_SPI_R1 (MMC_RSP_SPI_S1)
#define MMC_RSP_SPI_R1B (MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY)
#define MMC_RSP_SPI_R2 (MMC_RSP_SPI_S1|MMC_RSP_SPI_S2)
#define MMC_RSP_SPI_R3 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
#define MMC_RSP_SPI_R4 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
#define MMC_RSP_SPI_R5 (MMC_RSP_SPI_S1|MMC_RSP_SPI_S2)
#define MMC_RSP_SPI_R7 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
#define mmc_spi_resp_type(cmd) ((cmd)->flags & \
(MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY|MMC_RSP_SPI_S2|MMC_RSP_SPI_B4))
/*
* These are the command types.
*/
#define mmc_cmd_type(cmd) ((cmd)->flags & MMC_CMD_MASK)
unsigned int retries; /* max number of retries */
int error; /* command error */
/*
* Standard errno values are used for errors, but some have specific
* meaning in the MMC layer:
*
* ETIMEDOUT Card took too long to respond
* EILSEQ Basic format problem with the received or sent data
* (e.g. CRC check failed, incorrect opcode in response
* or bad end bit)
* EINVAL Request cannot be performed because of restrictions
* in hardware and/or the driver
* ENOMEDIUM Host can determine that the slot is empty and is
* actively failing requests
*/
unsigned int busy_timeout; /* busy detect timeout in ms */
/* Set this flag only for blocking sanitize request */
bool sanitize_busy;
struct mmc_data *data; /* data segment associated with cmd */
struct mmc_request *mrq; /* associated request */
};
1.2 命令结构体字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
opcode |
u32 | 命令码(0-63) |
arg |
u32 | 命令参数(32位) |
resp[4] |
u32[4] | 响应数据(最多136位,4个u32) |
flags |
unsigned int | 响应类型和命令类型标志 |
retries |
unsigned int | 最大重试次数 |
error |
int | 命令错误码 |
busy_timeout |
unsigned int | 忙信号超时(毫秒) |
sanitize_busy |
bool | 阻塞式sanitize请求标志 |
data |
struct mmc_data* | 关联的数据段 |
mrq |
struct mmc_request* | 关联的请求 |
1.3 命令类型定义(CMD类型)
c
#define MMC_CMD_MASK (3 << 5) /* non-SPI command type */
#define MMC_CMD_AC (0 << 5)
#define MMC_CMD_ADTC (1 << 5)
#define MMC_CMD_BC (2 << 5)
#define MMC_CMD_BCR (3 << 5)
命令类型说明:
| 类型 | 值 | 说明 | 示例命令 |
|---|---|---|---|
| MMC_CMD_AC | 0 << 5 | 点对点命令,无数据传输 | CMD3, CMD7, CMD9 |
| MMC_CMD_ADTC | 1 << 5 | 点对点命令,带数据传输 | CMD8, CMD17, CMD24 |
| MMC_CMD_BC | 2 << 5 | 广播命令,无响应 | CMD0 |
| MMC_CMD_BCR | 3 << 5 | 广播命令,带响应 | CMD1, CMD2 |
位域位置:
- 命令类型占用 flags 的位[6:5](2位)
1.4 响应类型标志位(RSP标志)
c
#define MMC_RSP_PRESENT (1 << 0)
#define MMC_RSP_136 (1 << 1) /* 136 bit response */
#define MMC_RSP_CRC (1 << 2) /* expect valid crc */
#define MMC_RSP_BUSY (1 << 3) /* card may send busy */
#define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */
响应标志位说明:
| 标志 | 位 | 说明 |
|---|---|---|
| MMC_RSP_PRESENT | bit 0 | 存在响应(1=有响应,0=无响应) |
| MMC_RSP_136 | bit 1 | 136位响应(1=136位,0=48位) |
| MMC_RSP_CRC | bit 2 | 需要CRC校验(1=需要,0=不需要) |
| MMC_RSP_BUSY | bit 3 | 卡可能发送忙信号(1=可能,0=不会) |
| MMC_RSP_OPCODE | bit 4 | 响应包含命令码(1=包含,0=不包含) |
1.5 标准响应类型组合(RSP类型)
c
#define MMC_RSP_NONE (0)
#define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R1B (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
#define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
#define MMC_RSP_R3 (MMC_RSP_PRESENT)
#define MMC_RSP_R4 (MMC_RSP_PRESENT)
#define MMC_RSP_R5 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R7 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
响应类型详细说明:
| 响应类型 | 标志组合 | 长度 | 格式 | 用途 |
|---|---|---|---|---|
| MMC_RSP_NONE | 0 | 0位 | 无响应 | CMD0等 |
| MMC_RSP_R1 | PRESENT|CRC|OPCODE | 48位 | [Start][Trans][CmdIdx][Status][CRC][End] | 命令状态响应 |
| MMC_RSP_R1B | PRESENT|CRC|OPCODE|BUSY | 48位+忙信号 | 同R1,但卡发送忙信号 | 带忙信号的响应 |
| MMC_RSP_R2 | PRESENT|136|CRC | 136位 | [Data(128位)][CRC7][End] | CID/CSD数据 |
| MMC_RSP_R3 | PRESENT | 48位 | [Start][Trans][CmdIdx][OCR][Reserved][End] | OCR寄存器 |
| MMC_RSP_R4 | PRESENT | 48位 | [Start][Trans][CmdIdx][Data][Reserved][End] | SDIO特定 |
| MMC_RSP_R5 | PRESENT|CRC|OPCODE | 48位 | [Start][Trans][CmdIdx][Status][CRC][End] | SDIO命令响应 |
| MMC_RSP_R6 | PRESENT|CRC|OPCODE | 48位 | [Start][Trans][CmdIdx][RCA][CRC][End] | SD RCA响应 |
| MMC_RSP_R7 | PRESENT|CRC|OPCODE | 48位 | [Start][Trans][CmdIdx][OCR][CRC][End] | SD OCR响应 |
响应类型位域组合:
MMC_RSP_R1 = 0b00011101 = 0x1D
bit[0] = 1 (PRESENT)
bit[2] = 1 (CRC)
bit[4] = 1 (OPCODE)
MMC_RSP_R1B = 0b00011111 = 0x1F
bit[0] = 1 (PRESENT)
bit[2] = 1 (CRC)
bit[3] = 1 (BUSY)
bit[4] = 1 (OPCODE)
MMC_RSP_R2 = 0b00000111 = 0x07
bit[0] = 1 (PRESENT)
bit[1] = 1 (136)
bit[2] = 1 (CRC)
MMC_RSP_R3 = 0b00000001 = 0x01
bit[0] = 1 (PRESENT)
1.6 SPI模式响应类型
c
#define MMC_RSP_SPI_S1 (1 << 7) /* one status byte */
#define MMC_RSP_SPI_S2 (1 << 8) /* second byte */
#define MMC_RSP_SPI_B4 (1 << 9) /* four data bytes */
#define MMC_RSP_SPI_BUSY (1 << 10) /* card may send busy */
c
#define MMC_RSP_SPI_R1 (MMC_RSP_SPI_S1)
#define MMC_RSP_SPI_R1B (MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY)
#define MMC_RSP_SPI_R2 (MMC_RSP_SPI_S1|MMC_RSP_SPI_S2)
#define MMC_RSP_SPI_R3 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
#define MMC_RSP_SPI_R4 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
#define MMC_RSP_SPI_R5 (MMC_RSP_SPI_S1|MMC_RSP_SPI_S2)
#define MMC_RSP_SPI_R7 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
SPI响应类型说明:
| 类型 | 标志组合 | 说明 |
|---|---|---|
| MMC_RSP_SPI_R1 | SPI_S1 | 1字节状态 |
| MMC_RSP_SPI_R1B | SPI_S1|SPI_BUSY | 1字节状态+忙信号 |
| MMC_RSP_SPI_R2 | SPI_S1|SPI_S2 | 2字节状态 |
| MMC_RSP_SPI_R3 | SPI_S1|SPI_B4 | 1字节状态+4字节数据 |
| MMC_RSP_SPI_R4 | SPI_S1|SPI_B4 | 1字节状态+4字节数据 |
| MMC_RSP_SPI_R5 | SPI_S1|SPI_S2 | 2字节状态 |
| MMC_RSP_SPI_R7 | SPI_S1|SPI_B4 | 1字节状态+4字节数据 |
1.7 CMD23参数定义
c
#define MMC_CMD23_ARG_REL_WR (1 << 31)
#define MMC_CMD23_ARG_PACKED ((0 << 31) | (1 << 30))
#define MMC_CMD23_ARG_TAG_REQ (1 << 29)
CMD23参数位域:
| 位 | 定义 | 说明 |
|---|---|---|
| bit[31] | REL_WR | 可靠写入(1=启用,0=禁用) |
| bit[30] | PACKED | 打包命令(1=启用,0=禁用) |
| bit[29] | TAG_REQ | 标签请求(1=启用,0=禁用) |
| bit[28:0] | BLOCK_COUNT | 块数量(29位) |
1.8 请求结构体定义
c
struct mmc_request {
struct mmc_command *sbc; /* SET_BLOCK_COUNT for multiblock */
struct mmc_command *cmd;
struct mmc_data *data;
struct mmc_command *stop;
struct completion completion;
void (*done)(struct mmc_request *);/* completion function */
struct mmc_host *host;
};
请求结构体字段:
| 字段 | 类型 | 说明 |
|---|---|---|
sbc |
struct mmc_command* | SET_BLOCK_COUNT命令(多块传输前) |
cmd |
struct mmc_command* | 主命令 |
data |
struct mmc_data* | 数据段 |
stop |
struct mmc_command* | 停止命令(多块传输后) |
completion |
struct completion | 完成信号量 |
done |
void ()(struct mmc_request) | 完成回调函数 |
host |
struct mmc_host* | 关联的主机 |
1.9 数据结构体定义
c
struct mmc_data {
unsigned int timeout_ns; /* data timeout (in ns, max 80ms) */
unsigned int timeout_clks; /* data timeout (in clocks) */
unsigned int blksz; /* data block size */
unsigned int blocks; /* number of blocks */
int error; /* data error */
unsigned int flags;
#define MMC_DATA_WRITE (1 << 8)
#define MMC_DATA_READ (1 << 9)
#define MMC_DATA_STREAM (1 << 10)
unsigned int bytes_xfered;
struct mmc_command *stop; /* stop command */
struct mmc_request *mrq; /* associated request */
unsigned int sg_len; /* size of scatter list */
int sg_count; /* mapped sg entries */
struct scatterlist *sg; /* I/O scatter list */
s32 host_cookie; /* host private data */
};
数据标志位:
| 标志 | 值 | 说明 |
|---|---|---|
| MMC_DATA_WRITE | 1 << 8 | 写数据(主机→卡) |
| MMC_DATA_READ | 1 << 9 | 读数据(卡→主机) |
| MMC_DATA_STREAM | 1 << 10 | 流模式传输 |
二、card.h 中的相关定义
2.1 卡结构体中的命令相关字段
c
struct mmc_card {
struct mmc_host *host; /* the host this device belongs to */
struct device dev; /* the device */
u32 ocr; /* the current OCR setting */
unsigned int rca; /* relative card address of device */
unsigned int type; /* card type */
#define MMC_TYPE_MMC 0 /* MMC card */
#define MMC_TYPE_SD 1 /* SD card */
#define MMC_TYPE_SDIO 2 /* SDIO card */
#define MMC_TYPE_SD_COMBO 3 /* SD combo (IO+mem) card */
unsigned int state; /* (our) card state */
#define MMC_STATE_PRESENT (1<<0) /* present in sysfs */
#define MMC_STATE_READONLY (1<<1) /* card is read-only */
#define MMC_STATE_BLOCKADDR (1<<2) /* card uses block-addressing */
#define MMC_CARD_SDXC (1<<3) /* card is SDXC */
#define MMC_CARD_REMOVED (1<<4) /* card has been removed */
#define MMC_STATE_DOING_BKOPS (1<<5) /* card is doing BKOPS */
#define MMC_STATE_SUSPENDED (1<<6) /* card is suspended */
unsigned int quirks; /* card quirks */
#define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */
#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */
/* for byte mode */
#define MMC_QUIRK_NONSTD_SDIO (1<<2) /* non-standard SDIO card attached */
/* (missing CIA registers) */
#define MMC_QUIRK_NONSTD_FUNC_IF (1<<4) /* SDIO card has nonstd function interfaces */
#define MMC_QUIRK_DISABLE_CD (1<<5) /* disconnect CD/DAT[3] resistor */
#define MMC_QUIRK_INAND_CMD38 (1<<6) /* iNAND devices have broken CMD38 */
#define MMC_QUIRK_BLK_NO_CMD23 (1<<7) /* Avoid CMD23 for regular multiblock */
#define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8) /* Avoid sending 512 bytes in */
/* byte mode */
#define MMC_QUIRK_LONG_READ_TIME (1<<9) /* Data read time > CSD says */
#define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10) /* Skip secure for erase/trim */
#define MMC_QUIRK_BROKEN_IRQ_POLLING (1<<11) /* Polling SDIO_CCCR_INTx could create a fake interrupt */
#define MMC_QUIRK_TRIM_BROKEN (1<<12) /* Skip trim */
unsigned int erase_size; /* erase size in sectors */
unsigned int erase_shift; /* if erase unit is power 2 */
unsigned int pref_erase; /* in sectors */
unsigned int eg_boundary; /* don't cross erase-group boundaries */
u8 erased_byte; /* value of erased bytes */
u32 raw_cid[4]; /* raw card CID */
u32 raw_csd[4]; /* raw card CSD */
u32 raw_scr[2]; /* raw card SCR */
struct mmc_cid cid; /* card identification */
struct mmc_csd csd; /* card specific */
struct mmc_ext_csd ext_csd; /* mmc v4 extended card specific */
struct sd_scr scr; /* extra SD information */
struct sd_ssr ssr; /* yet more SD information */
struct sd_switch_caps sw_caps; /* switch (CMD6) caps */
unsigned int sdio_funcs; /* number of SDIO functions */
struct sdio_cccr cccr; /* common card info */
struct sdio_cis cis; /* common tuple info */
struct sdio_func *sdio_func[SDIO_MAX_FUNCS]; /* SDIO functions (devices) */
struct sdio_func *sdio_single_irq; /* SDIO function when only one IRQ active */
unsigned num_info; /* number of info strings */
const char **info; /* info strings */
struct sdio_func_tuple *tuples; /* unknown common tuples */
unsigned int sd_bus_speed; /* Bus Speed Mode set for the card */
unsigned int mmc_avail_type; /* supported device type by both host and card */
unsigned int drive_strength; /* for UHS-I, HS200 or HS400 */
struct dentry *debugfs_root;
struct mmc_part part[MMC_NUM_PHY_PARTITION]; /* physical partitions */
unsigned int nr_parts;
};
card.h 中与命令相关的字段:
ocr:当前OCR设置(用于CMD1)rca:相对卡地址(用于CMD3、CMD7、CMD9等)raw_cid[4]:原始CID数据(来自CMD2响应)raw_csd[4]:原始CSD数据(来自CMD9响应)
三、flags 字段完整位域图
flags字段位域布局(32位):
┌─────────────────────────────────────────────────────────────┐
│ 位域 │ 标志定义 │
├────────────┼────────────────────────────────────────────────┤
│ [31:11] │ 保留 │
│ [10] │ MMC_RSP_SPI_BUSY │
│ [9] │ MMC_RSP_SPI_B4 │
│ [8] │ MMC_RSP_SPI_S2 │
│ [7] │ MMC_RSP_SPI_S1 │
│ [6:5] │ MMC_CMD_MASK (命令类型) │
│ │ 00 = MMC_CMD_AC │
│ │ 01 = MMC_CMD_ADTC │
│ │ 10 = MMC_CMD_BC │
│ │ 11 = MMC_CMD_BCR │
│ [4] │ MMC_RSP_OPCODE │
│ [3] │ MMC_RSP_BUSY │
│ [2] │ MMC_RSP_CRC │
│ [1] │ MMC_RSP_136 │
│ [0] │ MMC_RSP_PRESENT │
└─────────────────────────────────────────────────────────────┘
四、响应类型组合示例
4.1 R1响应组合
c
MMC_RSP_R1 = MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE
= (1 << 0) | (1 << 2) | (1 << 4)
= 0x01 | 0x04 | 0x10
= 0x15 (二进制: 0001 0101)
位域:
c
bit[0] = 1 (PRESENT - 有响应)
bit[1] = 0 (136 - 48位响应)
bit[2] = 1 (CRC - 需要CRC)
bit[3] = 0 (BUSY - 无忙信号)
bit[4] = 1 (OPCODE - 包含命令码)
4.2 R2响应组合
c
MMC_RSP_R2 = MMC_RSP_PRESENT | MMC_RSP_136 | MMC_RSP_CRC
= (1 << 0) | (1 << 1) | (1 << 2)
= 0x01 | 0x02 | 0x04
= 0x07 (二进制: 0000 0111)
位域:
c
bit[0] = 1 (PRESENT - 有响应)
bit[1] = 1 (136 - 136位响应)
bit[2] = 1 (CRC - 需要CRC)
bit[3] = 0 (BUSY - 无忙信号)
bit[4] = 0 (OPCODE - 不包含命令码)
4.3 R3响应组合
c
MMC_RSP_R3 = MMC_RSP_PRESENT
= (1 << 0)
= 0x01 (二进制: 0000 0001)
位域:
c
bit[0] = 1 (PRESENT - 有响应)
bit[1] = 0 (136 - 48位响应)
bit[2] = 0 (CRC - 不需要CRC)
bit[3] = 0 (BUSY - 无忙信号)
bit[4] = 0 (OPCODE - 不包含命令码)
五、命令和响应使用示例
5.1 CMD0示例
c
struct mmc_command cmd = {
.opcode = MMC_GO_IDLE_STATE, // 0
.arg = 0,
.flags = MMC_RSP_NONE | MMC_CMD_BC, // 无响应,广播命令
};
flags解析:
c
flags = 0x00 | (2 << 5) = 0x40
bit[6:5] = 10 (MMC_CMD_BC - 广播命令)
其他位 = 0 (无响应)
5.2 CMD1示例
c
struct mmc_command cmd = {
.opcode = MMC_SEND_OP_COND, // 1
.arg = ocr | (1 << 30), // OCR值,bit30=高容量支持
.flags = MMC_RSP_R3 | MMC_CMD_BCR, // R3响应,广播命令带响应
};
flags解析:
c
flags = 0x01 | (3 << 5) = 0x61
bit[0] = 1 (PRESENT)
bit[6:5] = 11 (MMC_CMD_BCR - 广播命令带响应)
5.3 CMD2示例
c
struct mmc_command cmd = {
.opcode = MMC_ALL_SEND_CID, // 2
.arg = 0,
.flags = MMC_RSP_R2 | MMC_CMD_BCR, // R2响应,广播命令带响应
};
flags解析:
c
flags = 0x07 | (3 << 5) = 0x67
bit[0] = 1 (PRESENT)
bit[1] = 1 (136位响应)
bit[2] = 1 (CRC)
bit[6:5] = 11 (MMC_CMD_BCR)
5.4 CMD9示例
c
struct mmc_command cmd = {
.opcode = MMC_SEND_CSD, // 9
.arg = card->rca << 16, // RCA地址
.flags = MMC_RSP_R2 | MMC_CMD_AC, // R2响应,点对点命令
};
flags解析:
c
flags = 0x07 | (0 << 5) = 0x07
bit[0] = 1 (PRESENT)
bit[1] = 1 (136位响应)
bit[2] = 1 (CRC)
bit[6:5] = 00 (MMC_CMD_AC - 点对点命令)
六、辅助宏定义
6.1 响应类型提取宏
c
#define mmc_resp_type(cmd) ((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE))
用途: 从flags中提取响应类型标志位
6.2 命令类型提取宏
c
#define mmc_cmd_type(cmd) ((cmd)->flags & MMC_CMD_MASK)
用途: 从flags中提取命令类型(AC/ADTC/BC/BCR)
6.3 SPI响应类型提取宏
c
#define mmc_spi_resp_type(cmd) ((cmd)->flags & \
(MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY|MMC_RSP_SPI_S2|MMC_RSP_SPI_B4))
用途: 从flags中提取SPI响应类型标志位
七、flags字段完整使用示例
7.1 完整flags组合示例
c
// CMD0 - GO_IDLE_STATE
cmd.flags = MMC_RSP_NONE | MMC_CMD_BC;
// flags = 0x00 | 0x40 = 0x40
// CMD1 - SEND_OP_COND
cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
// flags = 0x01 | 0x60 = 0x61
// CMD2 - ALL_SEND_CID
cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
// flags = 0x07 | 0x60 = 0x67
// CMD3 - SET_RELATIVE_ADDR
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
// flags = 0x15 | 0x00 = 0x15
// CMD7 - SELECT_CARD
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
// flags = 0x15 | 0x00 = 0x15
// CMD9 - SEND_CSD
cmd.flags = MMC_RSP_R2 | MMC_CMD_AC;
// flags = 0x07 | 0x00 = 0x07
// CMD8 - SEND_EXT_CSD
cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
// flags = 0x15 | 0x20 = 0x35
八、总结
8.1 命令类型(CMD类型)
| 类型 | 值 | 位域 | 说明 |
|---|---|---|---|
| MMC_CMD_AC | 0 << 5 | [6:5] = 00 | 点对点命令,无数据传输 |
| MMC_CMD_ADTC | 1 << 5 | [6:5] = 01 | 点对点命令,带数据传输 |
| MMC_CMD_BC | 2 << 5 | [6:5] = 10 | 广播命令,无响应 |
| MMC_CMD_BCR | 3 << 5 | [6:5] = 11 | 广播命令,带响应 |
8.2 响应类型(RSP类型)
| 类型 | 标志组合 | 长度 | CRC | OPCODE | BUSY |
|---|---|---|---|---|---|
| MMC_RSP_NONE | 0 | 0 | - | - | - |
| MMC_RSP_R1 | PRESENT|CRC|OPCODE | 48位 | ✓ | ✓ | ✗ |
| MMC_RSP_R1B | PRESENT|CRC|OPCODE|BUSY | 48位 | ✓ | ✓ | ✓ |
| MMC_RSP_R2 | PRESENT|136|CRC | 136位 | ✓ | ✗ | ✗ |
| MMC_RSP_R3 | PRESENT | 48位 | ✗ | ✗ | ✗ |
| MMC_RSP_R4 | PRESENT | 48位 | ✗ | ✗ | ✗ |
| MMC_RSP_R5 | PRESENT|CRC|OPCODE | 48位 | ✓ | ✓ | ✗ |
| MMC_RSP_R6 | PRESENT|CRC|OPCODE | 48位 | ✓ | ✓ | ✗ |
| MMC_RSP_R7 | PRESENT|CRC|OPCODE | 48位 | ✓ | ✓ | ✗ |
8.3 flags字段位域总结
c
flags[31:0] = {
[31:11] : 保留
[10] : SPI_BUSY
[9] : SPI_B4
[8] : SPI_S2
[7] : SPI_S1
[6:5] : CMD类型 (AC/ADTC/BC/BCR)
[4] : RSP_OPCODE
[3] : RSP_BUSY
[2] : RSP_CRC
[1] : RSP_136
[0] : RSP_PRESENT
}