【MMC CMD 和 RSP 定义说明】

一、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
}
相关推荐
啵啵啵啵哲13 小时前
【输入法】Ubuntu 22.04 终极输入法方案:Fcitx5 + 雾凇拼音 (Flatpak版)
linux·运维·ubuntu
Y unes13 小时前
《uboot基础命令记录①》
linux·驱动开发·嵌入式硬件·mcu·ubuntu·uboot
渝妳学C13 小时前
深度解析Linux中编译器gcc/g++
linux·运维
姚青&13 小时前
二.文件处理命令-文件操作
linux
陌路2013 小时前
简写网络库(2)--封装socket类
linux·服务器·网络
JiMoKuangXiangQu13 小时前
Linux 内存案例:DDR 访问出错?
linux·内存·ddr ecc
Xの哲學14 小时前
从硬中断到 softirq:Linux 软中断机制的全景解剖
linux·服务器·网络·算法·边缘计算
lsp84ch8014 小时前
MacBookPro运行飞牛Nas,解决合盖亮屏
linux·网络·macbook·nas·飞牛
wdfk_prog14 小时前
[Linux]学习笔记系列 -- [fs]mnt_idmapping
linux·笔记·学习
optimistic_chen14 小时前
【Redis 系列】常用数据结构---Hash类型
linux·数据结构·redis·分布式·哈希算法