MMC控制器,能读写MMC卡或者SD卡。
每个MMC控制器包括:
1 支持MMC或者SD卡
2 支持MMC/SD协议或SPI协议
3 可供未来扩展的面向软件的实现
4 为MMC控制器的操作提供可编程频率
5 为控制MMC和SD卡之间发送定时的时钟,提供可编程频率
1 MMC控制器的任务
如上图,MMC在CPU或者DMA控制,和一个或者多个存储卡之间发送数据。CPU或DMA扩展器可以读写MMC控制器的控制和状态寄存器。需要的时候,CPU或DMA控制器可以存储或者恢复DSP存储器或其他外设寄存器里的数据。
遵循控制器的本地协议或基于SPI协议进行通信。本地协议使用1条双向数据线(MMC),或4条并行的数据线(SD)。SPI协议使用两条串行的数据线,一条用来存储数据到卡上,一条用来从卡上恢复数据。
2 MMC控制器引脚
当连接的是MMC卡时,只使用DAT0数据线,而连接的是SD卡时,则使用DAT0~3数据线。
3 功能时钟和存储时钟
在MMC模块里,必须置位功能时钟和存储时钟的工作频率
功能时钟决定了MMC控制器的工作频率。DSP时钟发生器从一个外部时钟源接收一个信号,产生CPU时钟,MMC控制器里的分频器将其分配,产生功能时钟。通过初始化功能时钟MMCFCLKn的FDIV段,就可得到分频值,得到的功能时钟频率为 CPU时钟频率/(FDIV+1)。
存储时钟是MMC控制器CLK引脚所传递的时钟信号,该时钟控制MMC控制器与所连接的MMC卡之间的通信速率。存储时钟是对工作时钟分频产生的,分频值由MMCCLKx寄存器中的CDIV决定。
存储时钟=工作时钟/2(CDIV+1)
DSP通过CPU或DMA控制器读写MMC控制器的数据接收寄存器(MMCDRR)和数据发送寄存器(MMCDXR),读写都是以16位为单位的。而存储卡是8位的设备,一次只能传输一个字节,因此数据的读写必须遵照一定规则。
当接收数据时,如果数据接收寄存器收到两个字节,MMC控制器将产生一个数据接收就绪事件。当要接收奇数字节数据,最后一个字节将被装载到接收寄存器的低位字节中并产生一个数据接收就绪信号。
在发送数据时,如果发送寄存器中的两个字节已经被发送,则将产生一个数据发送就绪事件。如果奇数个字节需要发送,那么最后一个字节将靠右对齐,而将高位字节补0,当最后一个字节发送之后将引发一个数据发送就绪事件。
4 MMC/SD模式
该模式又称本地模式。
MMC/SD模式下CMD引脚主要用来传递MMC控制器对存储卡的控制命令和参数,并传送存储卡对命令的回复;
数据线传送读写的数据,而CLK则被控制器用来传送给存储卡的时钟信号。该模式下控制器可以连接多个存储卡,控制器将为这些卡分配不同的地址。下面给出MMC/SD模式的读写时序。
1.MMC/SD模式写
接下来介绍MMC/SD写中的各部分的功能:
1 WR CMD:批量写命令,6字节长,由DSP发给存储卡;
2 CMD RSP:写命令回复。是存储卡发给DSP批量写回执,通知DSP已经收到批量写命令;
3 DAT BLK:数据块。是DSP向存储卡写的数据,该数据块包括在开始有起始位,结束时则有两个字节的CRC校验和一个结束位;
4 CRC STAT:CRC状态。存储卡发给DSP的一个字节的错误校验状态信息,如果校验正确则数据被存储卡接受,错误则数据被丢弃,CRC状态的内容也需要添加起始位和结束位;
5 BSY:忙。CRC状态信息之后将跟随一串为低的数据流,标志着存储卡处在繁忙状态,直到数据被存到存储卡的闪存存储器中。
以上数据也是成功的写次序。
2.MMC/SD模式读
接下来介绍MMC/SD读中的各部分的功能:
1 RD CMD:批量读命令,6字节长,由DSP发给存储卡;
2 CMD RSP:读命令回复。是存储卡发给DSP批量读回执,通知DSP已经收到批量读命令;
3 DAT BLK:数据块。是DSP从存储卡读的数据,该数据块包括在开始有起始位,结束时则有两个字节的CRC校验和一个结束位。
以上也是成功的读次序
3.卡识别操作
在MMC控制器开始数据传送之前,首先要识别在总线上一共连接有多少块卡,并配置它们。所谓识别就是控制器发出ALL_SEND_CID广播命令,控制器读取存储卡发回的独一无二的卡标识号(CID),控制器再向存储卡分配一个地址(RCA)用来标识这块存储卡。一次只能有一块卡回复ALL_SEND_CID命令,如果没有回复则说明所有卡已经被识别和配置。 RCA远短于CID,在以后包含某块卡所有的命令里,控制器使用RCA识别卡身份。
卡识别操作的过程如下:
1)通过命令寄存器(MMCCMD)发出GO_IDLE_STATE广播命令,使所有卡进入静止状态;
2)发出ALL_SEND_CID广播命令,通知所有卡进行识别操作;
3)等待卡回应,如果有卡进行回应则进行第4步,否则停止;
4)从回应寄存器(MMCRSP7~0)中读取CID,并通过SET_RELATIVE_ADDR命令为存储卡分配一个相应的地址;
5)返回第3步。
4.单块写操作
该操作用来向存储卡写单块数据,数据块的长度必须为512个字节,操作过程如下:
1)向参数寄存器MMCARG写入要进行写的卡的相关地址,地址的高位写入MMCARGH,低位写入MMCARGL;
2)通过命令寄存器发出SELECT/DESELECT_CARD广播命令,该命令用来选择/不选某块卡;
3)向参数寄存器写入目标地址;
4)向数据传送寄存器写入所传送的数据块中的第一个字节;
5)向存储卡发出WRITE_BLOCK命令;
6)用状态寄存器0检测错误,在判断字节发送成功后,如果数据没有全部写完则进入第7步,如果写完了则停止;
7)写入数据块的下一个字节,并返回第6步。
5.单块读操作
单块读操作是从存储卡中读取单独的数据块,操作过程如下:
1)向参数寄存器写入卡的相应地址;
2)通过命令寄存器发出SELECT/DESELECT_CARD广播命令,该命令用来选择/不选某块卡;
3)向参数寄存器写入目标地址;
4)如果块的长度同先前操作中块的长度不同,则发出SET_BLOCKLEN命令改变块的长度;
5)发出READ_SINGLE_BLOCK命令;
6)用状态寄存器0检测错误,在判断字节被成功的接收后,如果数据没有全部接收完则进入第7步,如果接收完了则停止;
7)从数据接收寄存器中读取新的数据字节,并返回第6步。
6.多块读操作
多块读操作的每块数据的长度必须保持一致,操作过程如下:
1)向参数寄存器写入卡的相应地址;
2)如果块的长度同先前操作中块的长度不同,则发出SET_BLOCKLEN命令改变块的长度,数据块的长度必须是512字节;
3)发出READ_MULT_BLOCKS命令;
4)用状态寄存器0检测错误,在判断字节被成功的接收后,如果数据没有全部接收则进入第5步,如果数据接收完了则进入第6步;
5)从数据接收寄存器中读取新的数据字节,并返回第4步;
6)发出STOP_TRANSMISSION命令。
7.MMC/SD模式初始化
初始化应按照如下步骤进行:
1)使MMC控制寄存器MMCCTL中的CMDRST和DATRST位进入复位状态,并在其他位中写入数值;
2)写其他寄存器完成配置;
3)清除CMDRST和DATRST位使控制器脱离复位状态,应注意不改变第一步中写入的其他数值;
4)使能CLK引脚,向存储卡送出时钟信号。
MMC控制寄存器
位
字段
数值
说明
8
DMAEN
0
1
禁止DMA事件
使能DMA事件
7~6
DATEG
00
01
10
11
禁止DAT2边沿检测
DAT3上升沿检测
DAT3下降沿检测
DAT3上升和下降沿都进行检测
5
SPIEN
0
1
MMC/SD模式
SPI模式
2
WIDTH
0
1
MMC卡(使用DAT0)
SD卡(使用DAT0~3)
1
CMDRST
0
1
MMC控制器的命令逻辑使能
MMC控制器的命令逻辑在复位状态
0
DATRST
0
1
MMC控制器的数字逻辑使能
MMC控制器的数字逻辑在复位状态
初始化时钟控制寄存器MMCFCLK和MMCCLK将决定MMC控制器的工作时钟和存储时钟,参见下面两个表。其中FDIV的范围是0~255,而CDIV的范围是0~15。
MMCFCLK寄存器
位
字段
数值
说明
8
IDLEEN
0
1
MMC控制器不能被停止;
如果PERI=1,则IDLE命令后MMC控制器进入静止状态
7~0
FDIV
0~255
工作时钟分频数
MMCCLK寄存器
位
字段
数值
说明
4
CLKEN
0
1
CLK信号被禁止,该引脚的信号为低;
CLK信号使能
3~0
CDIV
0~15
存储时钟分频数
接下来初始化中断使能寄存器,该寄存器用来决定MMC向CPU所发送的中断申请,这些位为0时禁止该中断,为1时使能该中断。MMC控制器进行通信时可能会出现超时问题,可以通过设置超时寄存器来解决这一问题,MMCTOR寄存器用来确定存储卡响应的超时周期,周期的长度从0到255;MMCTOD确定读取数据的超时周期,这个范围从0到65535。
数据块寄存器包括字节长度寄存器MMCBLEN和发送块数量寄存器MMCNBLK,其中字节长度的范围从1~512,而块的数量从1~65535,当MMCNBLK的值为0时,则块的数量为无穷大。
8.行为监测
MMC控制器运行时应监测其运行状态,以便根据这些状态进行相应的操作,这些状态可以通过MMC状态寄存器进行检测。这些可监测的状态包括DAT3边缘监测、接收数据就绪、发送数据就绪、数据错误、回复CRC错误、读取数据CRC错误、写数据CRC错误、回复超时、读取数据超时、命令/回复执行、忙状态、数据传输状态、DAT3状态、传输数据空、接收数据空、时钟停止状态等。
5 SPI模式
要注意的是,MMC/SD控制器选择SPI协议的话,MMC/SD卡也要选择SPI协议。
从图中可以看到DAT3信号和GPIO信号都作为MMC/SD卡的片选信号;DAT0信号作为串行数据输入信号(DATIN),用来接收数据和回复信号;CMD信号作为串行数据输出信号(DATOUT),用来传递命令和数据;CLK是提供定时传输的时钟信号。
SPI模式不支持连续或多块读写操作,因此在使用SPI模式时只能采用单块读写操作。
1.SPI模式写操作
SPI写首先由控制器发出写命令,存储卡接到命令后返回一个应答信息表示接到命令,得到回执后控制器向卡传送数据块,卡再返回一个回执表示已经接到数据,而在数据被写到卡上的闪存存储器之前卡都将处于忙状态。下面给出SPI写时序。
2.SPI模式读操作
SPI读首先由控制器向卡发出读命令,卡返回回执通知收到命令,接下来卡送出数据块以及数据校验。下面是SPI读时序。
3.SPI单块写操作
SPI模式的单块写操作只支持512字节长,下面是单块写操作的流程。
(1)将控制寄存器的片选使能位(CSEN)置成1,使片选信号为低(如果用GPIO作为片选信号,则写GPIO寄存器);
(2)将目标起始地址写到参数寄存器;
(3)写数据块的第一个字节到数据发送寄存器MMCDXR;
(4)通过MMC命令寄存器发出WRITE_BLOCK命令;
(5)用状态寄存器0检测错误并判断字节是否被成功发送,如果上一个字节已经发送,而整个数据块没有发送完则进入第6步,否则停止运行,并清除CSEN位;
(7)写下一个字节到数据发送寄存器并返回第5步。
4.SPI单块读操作
SPI读操作中块的长度从1~512字节,控制器和卡之间定义的长度必须一致。
(1)将控制寄存器的片选使能位(CSEN)置成1,使片选信号为低(如果用GPIO作为片选信号,则写GPIO寄存器);
(2)将源数据的起始地址写到参数寄存器;
(3)如果块的长度同上一次操作块的长度不一致,则发出SET_BLOCKLEN命令调整块长度;
(4)发出READ_SINGLE_BLOCK命令;
(5)用状态寄存器0检测错误并判断字节是否被成功接收,如果已经收到新字节,而整个数据块没有接收完则进入第6步,否则停止运行,并清除CSEN位;
(6)从数据接收寄存器MMDCRR读收到的新字节,并返回第5步。
6 MMC控制器的应用
应用MMC控制器芯片支持函数应在头文件中包含csl_mmc.h文件。
为了完成MMC控制器的设置,首先定义配置结构:
MMC_Config myMMCCfg = {
0x000F, /* MMCCTL */
0x0F00, /* MMCFCLKCTL */
0x0001, /* MMCCLK */
0x0FA0, /* MMCIm */
0x0500, /* MMCTOR */
0x0500, /* MMCTOD */
0x0200, /* MMCBLEN */
0x0001 /* MMCNBLK */
};
调用MMC_open( )函数打开MMC设备:
MMC_Handle myMmC;
myMmc = MMC_open(MMC_DEV0);
调用MMC_config( )配置MMC控制器:
MMC_config(myMMC, &myMMCCfg);
在完成MMC设备配置后可用MMC_read( )函数读取数据
Uint16 mybuf[512];
MMC_read(myMmc, 0, mybuf, 512);
如果要MMC控制器操作结束,可调用MMC_close()函数关闭MMC控制器:
MMC_close(myMmc);