GD32450i-EVAL学习笔记 13 - SDIO

目录

1 IO初始化

2 初始化

2.1 使能RCU

2.2 复位SDIO

2.3 时钟配置

2.3.1 DIV[0:8](时钟分频)

2.3.2 CLKBYP(旁路时钟使能位)

2.3.3 CLKPWRSAV(时钟动态开启/关闭以节省功耗)

2.3.4 CLKEDGE(时钟边沿选择位)

2.4 设置总线位宽

2.5 使能SDIO的电源

2.6 使能SDIO时钟

3 命令状态机

4 SDIO命令

4.1 command index[45:40]

4.2 argument[39:8]

4.3 设置等待模式

4.4 等待命令发送结束

5 响应

5.1 R1响应

5.2 R1b响应

5.3 R2响应

5.4 R3响应

5.5 R6响应

5.6 R7响应

6  配置数据传输参数

6.1 数据超时寄存器(SDIO_DATATO)

6.2 数据长度寄存器 (SDIO_DATALEN)

6.3 数据控制寄存器 (SDIO_DATACTL)

7 读数据

7.1 通过判断SDIO_STAT是否数据出错或者块操作结束

7.2 通过判断SDIO_STAT是否数据有效,读入数据


GD32F450的SDIO特性:

# MMC 与多媒体卡系统规格书 V4.2 及之前的版本全兼容。有三种不同的数据总线模式: 1 位 ( 默认 ) 、 4 位和 8 位; # SD 卡: 与 SD 存储卡规格版本 2.0 全兼容;   # SD I/O 与 SD I/O 卡规格版本 2.0 全兼容,有两种不同的数据总线模式: 1 位 ( 默认 ) 和 4 位; # CE-ATA 与 CE-ATA 数字协议版本 1.1 全兼容; # 48MHz 数据传输频率和 8 位数据传输模式; # 中断和 DMA 请求; # 完成信号使能和失能(CE-ATA) 。 注意: SDIO 在同一时间仅支持一个 SD 、 SD I/O 、 MMC4.2 或 CE-ATA 设备,但可支持多个 MMC4.1 或以前版本的卡

1 IO初始化

GD32450i-EVAL学习笔记 13 - SDIO

SDIO_CK: GPIOB2、GPIOC12,对应AF12。

SDIO_CMD: GPIOA6、GPIOD2,对应AF12。

SDIO_D0: GPIOB4、GPIOC8,对应AF12。

SDIO_D1: GPIOB0、GPIOC9、GPIOA8,对应AF12。

SDIO_D2: GPIOB1、GPIOA9、GPIOC10,对应AF12。

SDIO_D3: GPIOC11,对应AF12。

SDIO_D4: GPIOB8,对应AF12。

SDIO_D5: GPIOB9,对应AF12。

SDIO_D6: GPIOC6,对应AF12。

SDIO_D7: GPIOB10、GPIOC7,对应AF12。

GD32450i-EVAL使用的GPIO如下图:

GD32450i-EVAL学习笔记 13 - SDIO

2 初始化

2.1 使能RCU

RCU_APB2EN |= (uint32_t)1 << 11;

2.2 复位SDIO

RCU_APB2RST |= (uint32_t)1 << 11;
RCU_APB2RST &= ~(uint32_t)((uint32_t)1 << 11);

2.3 时钟配置

对应时钟控制寄存器 (SDI O_CLKCTL)

2.3.1 DIV[0:8](时钟分频)

时钟分频分为2个区域

GD32450i-EVAL学习笔记 13 - SDIO

GD32450i-EVAL学习笔记 13 - SDIO

SDIO的时钟频率 = SDIOCLK / (DIV[8:0] + 2),SDIOCLK一般情况下默认是使用48MHz,如下图中的红色圈部分。

GD32450i-EVAL学习笔记 13 - SDIO

根据SDIO规范,初始化时SDIO的默认时钟频率不能够超过400K。

DIV[0:8} = 48 * 1000 / 400 - 2 = 120 - 2 = 118(0x76)

2.3.2 CLKBYP(旁路时钟使能位)

决定DIV位是否有效, 为1时,SDIO的时钟就等于SDIOCLK,即48MHz

GD32450i-EVAL学习笔记 13 - SDIO

2.3.3 CLKPWRSAV(时钟动态开启/关闭以节省功耗)

GD32450i-EVAL学习笔记 13 - SDIO

2.3.4 CLKEDGE(时钟边沿选择位)

GD32450i-EVAL学习笔记 13 - SDIO

一般选择上升沿

2.4 设置总线位宽

对应时钟控制寄存器 (SDI O_CLKCTL)中的位11和位12

GD32450i-EVAL学习笔记 13 - SDIO

初始化的时候将SDIO默认设置为1位SDIO总线宽度。

2.5 使能SDIO的电源

电源控制寄存器(SDIO_PWRCTL)

GD32450i-EVAL学习笔记 13 - SDIO

SDIO_PWRCTL = 0x03;

2.6 使能SDIO时钟

时钟控制寄存器 (SDI O_CLKCTL)的位8

GD32450i-EVAL学习笔记 13 - SDIO

SDIO_CLKCTL |= ((uint32_t)1 << 8);

3 命令状态机

在对SDIO_CMDCTL 寄存器进行一次写操作并设置该寄存器的CSMEN 位为 1 后, 命令传输开始。SDIO_CMD 线发出48位数据,然后接收来自卡的响应(如果该命令需要响应的话),响应分为 48 位的短响应和 136 位的长响应。

4 SDIO命令

SDIO的命令是通过CMD线发送的,固定为48个位。

GD32450i-EVAL学习笔记 13 - SDIO

其中需要配置2个区域:command index、argument。7bit的CRC校验值不需要用户计算,GD32F450会自己填充这部分。

4.1 command index[45:40]

命令编号分为12个种类,

GD32450i-EVAL学习笔记 13 - SDIO

这部分的配置对应命令控制寄存器 (SDIO_CMD CTL)的CMDIDX[5:0]。

4.2 argument[39:8]

32位的参数区域,其具体的含义是根据command index定义的,可以将command index理解为函数,而argument就是函数的参数了。

这部分的配置对应命令参数寄存器 (SDIO_CMDARME)

4.3 设置等待模式

这部分的配置对应命令控制寄存器 (SDIO_CMD CTL)的位8和位9

GD32450i-EVAL学习笔记 13 - SDIO

例程中这2个位一直设置为0,猜想这个命令状态机是芯片内部的一个状态转换,而程序本身根据状态寄存器判断命令是否发送结束,所以这2个位可以不用管。

4.4 等待命令发送结束

通过状态寄存器SDIO_STAT判断命令是否发送完成且正确。

GD32450i-EVAL学习笔记 13 - SDIO

GD32450i-EVAL学习笔记 13 - SDIO

GD32450i-EVAL学习笔记 13 - SDIO

GD32450i-EVAL学习笔记 13 - SDIO

当位0和为2置位就表示命令发送出现错误,而位6才表示有响应的命令发送成功且响应已经接收,位7则在无响应的命令中判断命令是否已经发送完成。

5 响应

命令的响应分3种:无响应、短响应、长响应。短响应是48bit长,长响应是136bit长。

enum
{
    SDIO_CMD_RESPONSE_NO = 0,
    SDIO_CMD_RESPONSE_SHORT,
    SDIO_CMD_RESPONSE_LONG = 3,
};

SDIO定义了8种类型的Response,分别命名为R1、R1b、R2、R3、R4、R5、R6、R7, 其中SD存储卡用到了R1、R1b、R2、R3、R6、R7。相应的命令对应相应的响应,例如CMD13对应R1,CMD2对应R2。只有R2是长响应。

GD32F450将响应值保存在响应寄存器 (SDIO_RESPx x=0..3)中。

5.1 R1响应

GD32450i-EVAL学习笔记 13 - SDIO

card status参考SDIO规范文档中的Table 4-35: Card Status。

GD32F450只会把card status的32位保存在响应寄存器 (SDIO_RESP0)中。

5.2 R1b响应

R1b和R1响应在CMD线上是一样的,但是在数据线上传输额外可选的忙信号。

5.3 R2响应

GD32450i-EVAL学习笔记 13 - SDIO

R2响应是唯一的136bit的响应。其中[127:1]是有效数据,保存在4个响应寄存器 (SDIO_RESPx)中。CMD2和CMD10的响应是CID寄存器值,而CMD9是CSD寄存器值。

5.4 R3响应

GD32450i-EVAL学习笔记 13 - SDIO

ACMD41的响应,返回的是OCR寄存器值。

5.5 R6响应

GD32450i-EVAL学习笔记 13 - SDIO

CMD3的响应,设置RCA后确认是否设置成功。

5.6 R7响应

GD32450i-EVAL学习笔记 13 - SDIO

CMD8的响应,确认卡支持的电压。

GD32450i-EVAL学习笔记 13 - SDIO

6  配置数据传输参数

6.1 数据超时寄存器(SDIO_DATATO

由 SDIO_CLK 计数。当 DSM 进入 WaitR 或 BUSY 状 态,该寄存器的值加载到内部计数器开始递减。DSM 超时并进入空闲状态,当计数 器的值减至 0 时设置 DTTMOUT 标志

6.2 数据长度寄存器 (SDIO_DATALEN)

当数据传输开始时,数据计数器加载到这个寄存器并开始递减,这个参数是按字节算。

6.3 数据控制寄存器 (SDIO_DATACTL)

GD32450i-EVAL学习笔记 13 - SDIO

GD32450i-EVAL学习笔记 13 - SDIO

 对于SD卡,Transmod一直为0,即块传输模式

7 读数据

7.1 通过判断SDIO_STAT是否数据出错或者块操作结束

GD32450i-EVAL学习笔记 13 - SDIO

GD32450i-EVAL学习笔记 13 - SDIOGD32450i-EVAL学习笔记 13 - SDIO

GD32450i-EVAL学习笔记 13 - SDIO

GD32450i-EVAL学习笔记 13 - SDIO

7.2 通过判断SDIO_STAT是否数据有效,读入数据

上一篇:Nordic Collegiate Programming Contest 2020 D.Damsindistress (dp)


下一篇:今天星期几