目录
2.3.3 CLKPWRSAV(时钟动态开启/关闭以节省功耗)
7.1 通过判断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初始化
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如下图:
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个区域
SDIO的时钟频率 = SDIOCLK / (DIV[8:0] + 2),SDIOCLK一般情况下默认是使用48MHz,如下图中的红色圈部分。
根据SDIO规范,初始化时SDIO的默认时钟频率不能够超过400K。
DIV[0:8} = 48 * 1000 / 400 - 2 = 120 - 2 = 118(0x76)
2.3.2 CLKBYP(旁路时钟使能位)
决定DIV位是否有效, 为1时,SDIO的时钟就等于SDIOCLK,即48MHz
2.3.3 CLKPWRSAV(时钟动态开启/关闭以节省功耗)
2.3.4 CLKEDGE(时钟边沿选择位)
一般选择上升沿
2.4 设置总线位宽
对应时钟控制寄存器 (SDI O_CLKCTL)中的位11和位12
初始化的时候将SDIO默认设置为1位SDIO总线宽度。
2.5 使能SDIO的电源
电源控制寄存器(SDIO_PWRCTL)
SDIO_PWRCTL = 0x03;
2.6 使能SDIO时钟
时钟控制寄存器 (SDI O_CLKCTL)的位8
SDIO_CLKCTL |= ((uint32_t)1 << 8);
3 命令状态机
在对SDIO_CMDCTL 寄存器进行一次写操作并设置该寄存器的CSMEN 位为 1 后, 命令传输开始。SDIO_CMD 线发出48位数据,然后接收来自卡的响应(如果该命令需要响应的话),响应分为 48 位的短响应和 136 位的长响应。
4 SDIO命令
SDIO的命令是通过CMD线发送的,固定为48个位。
其中需要配置2个区域:command index、argument。7bit的CRC校验值不需要用户计算,GD32F450会自己填充这部分。
4.1 command index[45:40]
命令编号分为12个种类,
这部分的配置对应命令控制寄存器 (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
例程中这2个位一直设置为0,猜想这个命令状态机是芯片内部的一个状态转换,而程序本身根据状态寄存器判断命令是否发送结束,所以这2个位可以不用管。
4.4 等待命令发送结束
通过状态寄存器SDIO_STAT判断命令是否发送完成且正确。
当位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响应
card status参考SDIO规范文档中的Table 4-35: Card Status。
GD32F450只会把card status的32位保存在响应寄存器 (SDIO_RESP0)中。
5.2 R1b响应
R1b和R1响应在CMD线上是一样的,但是在数据线上传输额外可选的忙信号。
5.3 R2响应
R2响应是唯一的136bit的响应。其中[127:1]是有效数据,保存在4个响应寄存器 (SDIO_RESPx)中。CMD2和CMD10的响应是CID寄存器值,而CMD9是CSD寄存器值。
5.4 R3响应
ACMD41的响应,返回的是OCR寄存器值。
5.5 R6响应
CMD3的响应,设置RCA后确认是否设置成功。
5.6 R7响应
CMD8的响应,确认卡支持的电压。
6 配置数据传输参数
6.1 数据超时寄存器(SDIO_DATATO)
由 SDIO_CLK 计数。当 DSM 进入 WaitR 或 BUSY 状 态,该寄存器的值加载到内部计数器开始递减。DSM 超时并进入空闲状态,当计数 器的值减至 0 时设置 DTTMOUT 标志
6.2 数据长度寄存器 (SDIO_DATALEN)
当数据传输开始时,数据计数器加载到这个寄存器并开始递减,这个参数是按字节算。
6.3 数据控制寄存器 (SDIO_DATACTL)
对于SD卡,Transmod一直为0,即块传输模式