参考资料
https://linux.codingbelief.com/zh/storage/flash_memory/emmc/
资料光盘: 00_UserManual\参考资料\EMMC编程\JESD84-B50-1eMMCStandard.pdf
1.1 EMMC介绍 1.1.1 EMMC简介 eMMC (Embedded Multi Media Card)是MMC协会订立的嵌入式存储器标准规格,主要针对手机、数码相机、平板电脑等产品。eMMC主要是为了简化手机内存储器的设计,节省电路板的面积。eMMC是将NAND Flash、控制器和MMC标准接口封装到一块芯片上,如下图所示。
如下图所示,CPU和eMMC设备通过CLK、CMD、DATA[0-7]和RST信号脚互联。接口信号描述如下。
CLK:MMC总线的时钟线,由主机提供的信号。当时钟有效时才能传输命令和数据。在SDR模式下,时钟的上升沿为数据的采样时间。在DDR模式下,时钟的上下沿均进行数据的采样。不同的总线模式时钟的速率是不一样的。
CMD:双向传输的命令线,用于主机和设备的数据通信。当主机发送命令之后,设备会给主机应答,应答信号通过CMD线返回到主机。
RST:复位信号线。
DATA[0…7]:eMMC的双向数据总线,用于主机和设备之间的数据通信。DATA线是时分复用的,要么数据从主机传输到eMMC设备,要么从eMMC设备传输到主机。当用户上电或者复位的时候,仅能用DATA0传输数据。同时,用户根据自己的需要配置数据总线的位数。当用户选择4位时,eMMC设备配置DATA1-3的内部上拉,如果用户选择的是8位,那么同理会配置DATA1-7的上拉。
1.1.3 eMMC总线速度 eMMC5.0协议规定了5种总线数据模式如下表所示。兼容MMC模式、高速SDR模式和高速DDR模式可以兼容协议4.5版本之前的协议。
模式名数据速率模式IO电压总线位宽时钟速率最大数据传输速率兼容MMC模式SDR3/1.8/1.2V1、4、8bit0~26MHz26MHz高速SDR模式SDR3/1.8/1.2V1、4、8bit0~52MHz52MHz高速DDR模式DDR3/1.8/12V4、8bit0~52MHz104MHzHS200模式SDR1.8/12V4、8bit0~200MHz200MHzHS400模式DDR1.8/12V8bit0~200MHz400MHz 1.1.4 eMMC总线协议 eMMC总线可以挂载一个主设备和多个eMMC设备。总线上的所有通讯都由主机发起,主机一次只能与一个eMMC设备通讯。
系统在上电后,主机会给所有eMMC设备分配地址。当主机需要和某一个eMMC设备通讯时,会先根据RCA选中该eMMC设备,只有被选中的 eMMC设备才会应答主机的命令。
eMMC的通信是由单个或多个块组成的。它们分别是命令、应答、数据块,如下图所示。
读取eMMC数据的数据流如下图所示。如果主机发送的是读单个块的命令,那么eMMC设备只会发送一个块的数据,并且不用发送停止命令。
写入eMMC数据过程如下图所示。
如下图所示通信中除了带数据的命令,也有不带数据和不带应答的命令。
CMD有4中类型,分别为:不带应答的广播命令(br);带有应答的广播命令(bcr);点对点无数据传输(ac);点对点有数据传输(adtc)。
1.1.5.2 (2) 命令格式 如下图所示CMD是一个由起始位、传输位、命令索引、命令参数、CRC和结束位组成,一共有48位。
起始位固定为0。传输位表示数据传输的方向,1代表主机到eMMC设备。命令索引用占用了6个位,取值范围为0~63。命令参数是根据每个命令的功能要求提供相应的参数值。CRC7是起始位、传输位、命令索引、命令参数的内容的校验值。结束位固定为1。
1.1.5.3 (3) 命令分类 eMMC将56个命令分成如下表的12个class,每个class代表一类功能,包含所有命令的一个子集。设备支持哪些class,可以通过CSD寄存器的CSD[95:84]来查询,每一个位代表一个class,当某一位为1时代表支持该位对应class。
命令类别描述备注class 0basic基本命令class 1Obsolete废弃class 2block read块数据读相关命令,包括设置块长度、读取单块、读取多块class 3obsolete废弃class 4block write块数据写相关命令class 5erase擦除操作class 6write protection设置写保护class 7Lock device锁或者解锁设备class 8Application-specific特定应用命令class 9I/O mode写寄存器,设置系统进入中断模式class 10security protocols连续传输数据块class 11reserved预留 1.1.6 应答(Response)介绍 所有应答都是eMMC设备接收到主机的命令后在CMD信号线上发送,而应答的内容取决于应答的类型。如下图所示应答格式由起始位、传输位、数据位、CRC位和结束位组成。
eMMC协议中有6种应答类型,分别是R1、R1b、R2、R3、R4和R5。
- R1和R1b应答数据结构:
R1应答总长为48bit,其中[45:40]代表应答的命令索引,[39:8]表示设备的状态以及错误标记位。R1b的结构是在R1的基础上增加了一个Busy信号。
起始位传输位命令索引设备状态CRC结束位位置4746[45:40][39:8][7:1]0位宽1163271值“0”“0”xxCRC“1” 设备状态的含义如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MT82r3X3-1642060301308)(https://cdn.jsdelivr.net/gh/DongshanPI/HomeSite-Photos@main/IMX6ULL-BareMetal/13_EMMC_Program_image009.png)]
- R2应答数据结构:
R2应答主要返回设备CID或CSD寄存器的内容,CID寄存器分别对应CMD2和CMD10,CSD寄存器则是对应CMD9。
起始位传输位检查位数据CRC结束位位置135134[133:128][127:8][7:1]0位宽11612071值“0”“0”“111111”xCRC“1”- R3应答数据结构:
R3应答主要返回设备ORC寄存器的内容,只有下发CMD1时,设备才回复R3应答。
起始位传输位检查位ORC寄存器检查位结束位位置4746[45:40][39:8][7:1]0位宽1163271值“0”“0”“111111”x“1111111”“1”- R4应答数据结构:
R4应答主要用于写入和读出某个寄存器其中一个字节的数据。只有主机下发CMD39时,设备应答R4。
起始位传输位命令39参数CRC结束位位置4746[45:40][39:8][7:1]0位宽1163271值“0”“0”“100111”X“1111111”“1” 参数对应内容如下表所示。
[39:8]参数相对地址状态寄存器地址寄存器内容位宽16178- R5应答数据结构:
R5作为中断请求应答,其应答结构如下。
起始位传输位命令39参数CRC结束位位置4746[45:40][39:8][7:1]0位宽1163271值“0”“0”“100111”X“1111111”“1” 参数对应内容如下表所示。
[39:8]参数相对地址中断数据位宽1616 1.1.7 eMMC工作模式 如下表所示,EMMC有5种工作模式:开机模式、识别模式、中断模式、数据传输模式和无效模式。
模式描述开机模式(Boot mode)上电后,eMMC设备若收到带有0xF0F0F0F0参数的CMD0时,如果eMMC设备支持开机模式则进入开始模式,否则进入识别模式。识别模式(Card identification)上电后,开机模式结束或者不支持开机模式,eMMC设备就会进入测模式,并等待主机下发CMD3设置相对地址。中断模式(Interrupt mode)在此模式中不能进行数据传输操作,只能发出中断服务请求。数据传输模式(Data transfer mode)当主机为eMMC设备配置完RCA后,就会进入数据传输模式。无效模式(Inactive mode)当eMMC设备电压不符规定时就会进入此模式,也可以通过下发CMD1命令使eMMC设备进入无效模式 eMMC设备运行时,根据不同模式跳转到不同的工作状态,如下表所示。
设备状态操作模式总线模式Inactive State非活动模式开漏Pre-Idle State启动模式Pre-Boot StateIdle State设备识别模式Ready StateIdentification StateStand-by State数据传输模式上下拉Sleep StateTransfer StateBus-Test StateSending-data StateProgramming StateDisconnect StateBoot State启动模式Wait-IRQ State中断模式开漏 1.1.8 eMMC寄存器 如下表所示,总共有6种。它们可以得到设备的相关内容以及设置工作时的控制对象,在读写数据前的步骤操作相对应的寄存器实现。因此协议中明确定义所用寄存器的含义。
名称大小(Byte)描述CID16设备识别寄存器RCA2相关设备地址DSR2驱动等级寄存器CSD16存储设备相关信息OCR4操作状态寄存器EXT_CSD512扩展设备寄存器 1.1.9 eMMC初始化过程 eMMC设备的正常工作,必须完成初始化过程。在初始化过程中,主机会对EMMC设备进行识别,确定设备工作的电压范围和使用模式,向设备分配相对地址(RCA,一个系统可以支持多个eMMC设备)。设备初始化过程如下图所示。
电源上电后,eMMC设备进入空闲(Idle State)。虽然进入了空闲状态,但是设备的上电复位过程不一定完成,这时需要读取OCR的Busy位来判断设备的上电复位过程是否完成。
在空闲状态中只有CMD1和CMD58是合法命令。主机通过发送CMD1,读取eMMC设备的OCR寄存器,并进行电压匹配和通过BUSY位判断复位是否完成。当BUSY为1时,代表eMMC设备初始化完毕进入Ready State。
在Ready State中,主机下发CMD2命令后会收到CID寄存器的值,此时eMMC设备进入Identification State。接着主机发送CMD3命令,为eMMC设备配置RCA。配置完成后eMMC设备进入standby state。此时初始化过程结束。
1.1.10 数据传输模式 在数据传输模式下可实现对EMMC设备进行读写,擦除,总线测试等操作。此模式工作状态图如下所示。
IMX6ULL共2个独立的USDHC,主要特型如下:
1) 兼容MMC系统规范4.2/4.3/4.4/4.41/4.5版本;
2) 时钟频率最高可达208MHz;
3) 支持1位/4位/8位的SD、SDIO和MMC模式;
4) 在SDR(单数据速率)模式下使用4条并行数据线对SDIO卡进行高达832Mbps的数据传输;
5) 在DDR(双数据速率)模式下使用4条并行数据线对SDXC卡进行高达400Mbps的数据传输;
6) 在SDXC卡模式下使用4条并行数据线对SDXC卡进行高达832Mbps的数据传输;
7) 在SDXC卡模式下使用4条并行数据传输高达400Mbps的数据传输(双数据传输)支持单块/多块读写,支持1~4096字节的块大小,支持写操作的写保护开关,支持同步和异步中止,支持块间隙数据传输期间的暂停,支持SDIO读取等待和暂停恢复操作,支持自动CMD12 对于多块传输,主机可以在数据传输进行时启动非数据传输命令。
以上只是列举了部分的特性,详细的特征描述可以查看芯片手册《Chapter 58 Ultra Secured Digital Host Controller (uSDHC)》。
1.2.2 IMX6ULL USDHC寄存器介绍 IMX6ULL有两路USDHC,每一路各有29个寄存器,只要学会一路寄存器的使用,即可掌握另一路的使用。
USDHC的寄存器如下图所示,从图中可得知两路USDHC的寄存器各分配到两段连续的地址空间中。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RZmmpDQb-1642060301313)(https://cdn.jsdelivr.net/gh/DongshanPI/HomeSite-Photos@main/IMX6ULL-BareMetal/13_EMMC_Program_image014.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mWkQs1p8-1642060301314)(https://cdn.jsdelivr.net/gh/DongshanPI/HomeSite-Photos@main/IMX6ULL-BareMetal/13_EMMC_Program_image015.png)]
接下来介绍我们实验要用到的寄存器:
1.2.2.1 (1)uSDHC2_BLK_ATT uSDHC2_BLK_ATT寄存器为块的读写服务。BLKSIZE[12:0]用于设置读写块的大小,最大可以设置为4096字节,如果设置为0时表示没有数据传输。BLKCNT用于配置读写块的数量,最大可配置为65535个块。当在多个块读写时,每读写完一个块BLKCNT自动减一直到0停止。
uSDHC2_CMD_ARG是命令的参数寄存器,保存要下发命令的参数。
uSDHC2_CMD_XFR_TYP是命令传输类型寄存器。用于配置传输的命令编号、命令类型、数据传输、应答类型和校验使能等。
uSDHC2_CMD_RSP0-3是32位的命令应答寄存器。如下表所示系统根据应答类型,将eMMC设备应答的数据分别保存在相应的命令应答寄存器中。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tdiYf827-1642060301317)(第十三章 EMMC编程.assets/13_EMMC_Program_image019.png)]
1.2.2.5(5)uSDHC2_DATA_BUFF_ACC_PORT uSDHC2_DATA_BUFF_ACC_PORT是一个32位的数据缓存接口,这个寄存器是内部数据缓存器的一个读写口。通过这个数据缓存接口,就可以读取到数据缓存的数据。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YMw1jTsb-1642060301317)(第十三章 EMMC编程.assets/13_EMMC_Program_image020.png)]
1.2.2.6(6)uSDHC2_PRES_SETATE uSDHC2_PRES_SETATE是USDHC的状态寄存器。状态寄存器体现USDHC的命令传输、数据读写、时钟等的状态。我们主要关注CIHB、CDIHB、SDSTB、BREN、BWEN位。具体使用方法编程阶段会一一介绍。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2KXeuREj-1642060301318)(第十三章 EMMC编程.assets/13_EMMC_Program_image021.png)]
1.2.2.7 (7)uSDHC2_PROT_CTRL uSDHC2_PROT_CTRL是端口控制寄存器,主要是控制数据位宽、大小端配置等。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P70Wt5Z9-1642060301318)(第十三章 EMMC编程.assets/13_EMMC_Program_image022.png)]
1.2.2.8 (8)uSDHC2_SYS_CTRL uSDHC2_SYS_CTRL是系统控制寄存器,用于软件复位、时钟分频配置和超时时间等。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gbap7RNU-1642060301318)(第十三章 EMMC编程.assets/13_EMMC_Program_image023.png)]
1.2.2.9(9)uSDHC2_INT_STATUS uSDHC2_INT_STATUS是中断状态寄存器,命令传输完成、读写完成和传输错误都会在中断体现。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-upreBSQ9-1642060301319)(第十三章 EMMC编程.assets/13_EMMC_Program_image024.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ncPEFo33-1642060301319)(第十三章 EMMC编程.assets/13_EMMC_Program_image025.png)]
1.2.2.10(10)uSDHC2_INT_SIGNAL_EN 通过配置这个寄存器使能中断的状态。将这个寄存器某位置为1时则uSDHC2_INT_STATUS对应的状态使能。反则屏蔽该状态。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-amiGDL1I-1642060301319)(第十三章 EMMC编程.assets/13_EMMC_Program_image026.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5OzW9hhu-1642060301319)(第十三章 EMMC编程.assets/13_EMMC_Program_image027.png)]
1.2.2.11 (11)uSDHC2_WTMK_LVL 这个是读写水位寄存器。当缓存器的数据大于WR_WML或者RD_WML时,中断状态寄存器中的读写状态置1。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0cTuypDS-1642060301320)(第十三章 EMMC编程.assets/13_EMMC_Program_image028.png)]
1.2.2.12 (12)uSDHC2_MIX_CTRL uSDHC2_MIX_CTRL是混合控制寄存器。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J24ZRv8s-1642060301320)(第十三章 EMMC编程.assets/13_EMMC_Program_image029.png)]
1.3 EMMC编程 1.3.1 eMMC引脚配置 前两节介绍了eMMC的协议和IMX6ULL USDHC相关寄存器,接下来开始讲解EMMC驱动设计。编写驱动首先要配置引脚。为了正确配置引脚我们需要了解的是硬件的连接方式和相关引脚的配置寄存器。
(1)确定USDHC引脚
从下图可知,eMMC设备的引脚连接到IMX6-NAND的ALE、nRE、nWE和DATA0-7引脚上。查看IMX6UUL数据手册可知所使用的是USDHC2。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1QB4JHTW-1642060301320)(第十三章 EMMC编程.assets/13_EMMC_Program_image030.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5hrHiPCE-1642060301321)(第十三章 EMMC编程.assets/13_EMMC_Program_image031.png)]
(2)USDHC2相关引脚寄存器配置
1.3.1.1 步骤1:配置USDHC2相关引脚的复用功能 在手册《Chapter4 External Signals and Pin Multiplexing》中,可以找到USDHC2引脚所对应的复用模式,如下表所示。从表中可知USDHC2的相关引脚的复用模式应设置为ALT1模式。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ybc7Gj6Q-1642060301321)(https://cdn.jsdelivr.net/gh/DongshanPI/HomeSite-Photos@main/IMX6ULL-BareMetal/13_EMMC_Program_image032.png)]
- 配置GPIO4_IO10(USDHC2_RESET_B)复用功能:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mDviR0hi-1642060301321)(第十三章 EMMC编程.assets/13_EMMC_Program_image033.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5Rcy1OPL-1642060301321)(第十三章 EMMC编程.assets/13_EMMC_Program_image034.png)]
由上图可知IOMUXC_SW_MUX_CTL_PAD_NAND_ALE[MUX_MODE]应设为0x01。
- 配置GPIO4_IO00(USDHC2_CLK)复用功能:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r2rfAjEK-1642060301321)(第十三章 EMMC编程.assets/13_EMMC_Program_image035.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b45rPH8k-1642060301322)(第十三章 EMMC编程.assets/13_EMMC_Program_image036.png)]
由上图可知IOMUXC_SW_MUX_CTL_PAD_NAND_RE_B[MUX_MODE]应设为0x01。
- 配置GPIO4_IO01(USDHC2_CMD)复用功能:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LE5K0x5F-1642060301322)(第十三章 EMMC编程.assets/13_EMMC_Program_image037.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S1qsHfu2-1642060301322)(第十三章 EMMC编程.assets/13_EMMC_Program_image038.png)]
由上图可知IOMUXC_SW_MUX_CTL_PAD_NAND_WE_B[MUX_MODE]应设为0x01。
- 配置USDHC2_ DATA0-7的复用功能:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6AZOSO9M-1642060301322)(第十三章 EMMC编程.assets/13_EMMC_Program_image039.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8WRetLCs-1642060301323)(第十三章 EMMC编程.assets/13_EMMC_Program_image040.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3yAzoM4b-1642060301323)(第十三章 EMMC编程.assets/13_EMMC_Program_image041.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eLMFGVuM-1642060301323)(第十三章 EMMC编程.assets/13_EMMC_Program_image042.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hmmlLNcM-1642060301323)(第十三章 EMMC编程.assets/13_EMMC_Program_image043.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2SQeSJZn-1642060301324)(第十三章 EMMC编程.assets/13_EMMC_Program_image044.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JDrdvtY4-1642060301324)(第十三章 EMMC编程.assets/13_EMMC_Program_image045.png)]
由于DATA0-7都是ALT1所以IOMUXC_SW_MUX_CTL_PAD_NAND_DATA0、IOMUXC_SW_MUX_CTL_PAD_NAND_DATA1、IOMUXC_SW_MUX_CTL_PAD_NAND_DATA2、IOMUXC_SW_MUX_CTL_PAD_NAND_DATA3IOMUXC_SW_MUX_CTL_PAD_NAND_DATA4、IOMUXC_SW_MUX_CTL_PAD_NAND_DATA5、IOMUXC_SW_MUX_CTL_PAD_NAND_DATA6、IOMUXC_SW_MUX_CTL_PAD_NAND_DATA7均配置为0x01。
具体代码如下:
61 // 配置引脚复用功能
62 IOMUXC_SW_MUX_CTL_PAD_NAND_RE_B = (volatile unsigned int *)(0x20E0178);
63 IOMUXC_SW_MUX_CTL_PAD_NAND_WE_B = (volatile unsigned int *)(0x20E017C);
64 IOMUXC_SW_MUX_CTL_PAD_NAND_DATA0 = (volatile unsigned int *)(0x20E0180);
65 IOMUXC_SW_MUX_CTL_PAD_NAND_DATA1 = (volatile unsigned int *)(0x20E0184);
66 IOMUXC_SW_MUX_CTL_PAD_NAND_DATA2 = (volatile unsigned int *)(0x20E0188);
67 IOMUXC_SW_MUX_CTL_PAD_NAND_DATA3 = (volatile unsigned int *)(0x20E018C);
68 IOMUXC_SW_MUX_CTL_PAD_NAND_DATA4 = (volatile unsigned int *)(0x20E0190);
69 IOMUXC_SW_MUX_CTL_PAD_NAND_DATA5 = (volatile unsigned int *)(0x20E0194);
70 IOMUXC_SW_MUX_CTL_PAD_NAND_DATA6 = (volatile unsigned int *)(0x20E0198);
71 IOMUXC_SW_MUX_CTL_PAD_NAND_DATA7 = (volatile unsigned int *)(0x20E019C);
72 IOMUXC_SW_MUX_CTL_PAD_NAND_ALE = (volatile unsigned int *)(0x20E01A0);
73
74 *IOMUXC_SW_MUX_CTL_PAD_NAND_RE_B = 0x1U;
75 *IOMUXC_SW_MUX_CTL_PAD_NAND_WE_B = 0x1U;
76 *IOMUXC_SW_MUX_CTL_PAD_NAND_DATA0 = 0x1U;
77 *IOMUXC_SW_MUX_CTL_PAD_NAND_DATA1 = 0x1U;
78 *IOMUXC_SW_MUX_CTL_PAD_NAND_DATA2 = 0x1U;
79 *IOMUXC_SW_MUX_CTL_PAD_NAND_DATA3 = 0x1U;
80 *IOMUXC_SW_MUX_CTL_PAD_NAND_DATA4 = 0x1U;
81 *IOMUXC_SW_MUX_CTL_PAD_NAND_DATA5 = 0x1U;
82 *IOMUXC_SW_MUX_CTL_PAD_NAND_DATA6 = 0x1U;
83 *IOMUXC_SW_MUX_CTL_PAD_NAND_DATA7 = 0x1U;
84 *IOMUXC_SW_MUX_CTL_PAD_NAND_ALE = 0x1U;
1.3.1.2 步骤2:设置USDHC2相关引脚的输入源:
如下图IMX6中的功能模块(如:UART、USDHC)可能存在1个或多个可配置引脚,所以在配置完GPIO模式后还要设置输入源选择寄存器。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9pbZtuPd-1642060301324)(第十三章 EMMC编程.assets/13_EMMC_Program_image046.png)]
- USDHC2_CLK输入源寄存器设置:
由下图可知IOMUXC_USDHC2_CLK_SELECT_INPUT [DAISY]应设为0x2。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i07myik8-1642060301324)(第十三章 EMMC编程.assets/13_EMMC_Program_image047.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MFlkUFee-1642060301325)(第十三章 EMMC编程.assets/13_EMMC_Program_image048.png)]
- USDHC2_CMD输入源寄存器设置:
由下图可知IOMUXC_USDHC2_CMD_SELECT_INPUT [DAISY]应设为0x2。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ITJM1X1G-1642060301325)(第十三章 EMMC编程.assets/13_EMMC_Program_image049.png)]
- USDHC2_DATA0输入源寄存器设置:
由下图可知IOMUXC_USDHC2_DATA0_SELECT_INPUT [DAISY]应设为0x2。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lAuBnEei-1642060301325)(第十三章 EMMC编程.assets/13_EMMC_Program_image050.png)]
- USDHC2_DATA1输入源寄存器设置:
由下图可知IOMUXC_USDHC2_DATA1_SELECT_INPUT [DAISY]应设为0x2。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QfqhMe3A-1642060301325)(第十三章 EMMC编程.assets/13_EMMC_Program_image051.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G6KLqjGe-1642060301325)(第十三章 EMMC编程.assets/13_EMMC_Program_image052.png)]
- USDHC2_DATA2输入源寄存器设置:
由下图可知IOMUXC_USDHC2_DATA2_SELECT_INPUT [DAISY]应设为0x1。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w3y1tGWd-1642060301326)(第十三章 EMMC编程.assets/13_EMMC_Program_image053.png)]
- USDHC2_DATA3输入源寄存器设置:
由下图可知IOMUXC_USDHC2_DATA3_SELECT_INPUT [DAISY]应设为0x2。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kdER2YfM-1642060301326)(第十三章 EMMC编程.assets/13_EMMC_Program_image054.png)]
- USDHC2_DATA4-7输入源寄存器设置:
USDHC2_DATA4-7的DAISY都0x2,所以IOMUXC_USDHC2_DATA4_SELECT_INPUT [DAISY]、IOMUXC_USDHC2_DATA5_SELECT_INPUT [DAISY]、IOMUXC_USDHC2_DATA6_SELECT_INPUT [DAISY]、IOMUXC_USDHC2_DATA7_SELECT_INPUT [DAISY]应设为0x2。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ak6n7zEW-1642060301326)(第十三章 EMMC编程.assets/13_EMMC_Program_image055.png)]
代码如下:
86 // 配置引脚的输入源
87 IOMUXC_USDHC2_CLK_SELECT_INPUT = (volatile unsigned int *)(0x020E0670);
88 IOMUXC_USDHC2_CMD_SELECT_INPUT = (volatile unsigned int *)(0x020E0678);
89 IOMUXC_USDHC2_DATA0_SELECT_INPUT = (volatile unsigned int *)(0x020E067C);
90 IOMUXC_USDHC2_DATA1_SELECT_INPUT = (volatile unsigned int *)(0x020E0680);
91 IOMUXC_USDHC2_DATA2_SELECT_INPUT = (volatile unsigned int *)(0x020E0684);
92 IOMUXC_USDHC2_DATA3_SELECT_INPUT = (volatile unsigned int *)(0x020E0688);
93 IOMUXC_USDHC2_DATA4_SELECT_INPUT = (volatile unsigned int *)(0x020E068C);
94 IOMUXC_USDHC2_DATA5_SELECT_INPUT = (volatile unsigned int *)(0x020E0690);
95 IOMUXC_USDHC2_DATA6_SELECT_INPUT = (volatile unsigned int *)(0x020E0694);
96 IOMUXC_USDHC2_DATA7_SELECT_INPUT = (volatile unsigned int *)(0x020E0698);
97
98 *IOMUXC_USDHC2_CLK_SELECT_INPUT = 0x2U;
99 *IOMUXC_USDHC2_CMD_SELECT_INPUT = 0x2U;
100 *IOMUXC_USDHC2_DATA0_SELECT_INPUT = 0x2U;
101 *IOMUXC_USDHC2_DATA1_SELECT_INPUT = 0x2U;
102 *IOMUXC_USDHC2_DATA2_SELECT_INPUT = 0x1U;
103 *IOMUXC_USDHC2_DATA3_SELECT_INPUT = 0x2U;
104 *IOMUXC_USDHC2_DATA4_SELECT_INPUT = 0x1U;
105 *IOMUXC_USDHC2_DATA5_SELECT_INPUT = 0x1U;
106 *IOMUXC_USDHC2_DATA6_SELECT_INPUT = 0x1U;
107 *IOMUXC_USDHC2_DATA7_SELECT_INPUT = 0x1U;
1.3.1.3 步骤3:设置USDHC2相关引脚的输入输出参数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tKBZV50F-1642060301326)(第十三章 EMMC编程.assets/13_EMMC_Program_image056.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PtUKdCkP-1642060301327)(第十三章 EMMC编程.assets/13_EMMC_Program_image057.png)]
相关引脚的输入输出参数配置如上图红圈所示,所有引脚配置值为0x17059。
相关代码如下:
109 // 配置引脚的输入输出参数
110 IOMUXC_SW_PAD_CTL_PAD_NAND_RE_B = (volatile unsigned int *)(0x020E0404U);
111 IOMUXC_SW_PAD_CTL_PAD_NAND_WE_B = (volatile unsigned int *)(0x020E0408U);
112 IOMUXC_SW_PAD_CTL_PAD_NAND_DATA00 = (volatile unsigned int *)(0x020E040CU);
113 IOMUXC_SW_PAD_CTL_PAD_NAND_DATA01 = (volatile unsigned int *)(0x020E0410U);
114 IOMUXC_SW_PAD_CTL_PAD_NAND_DATA02 = (volatile unsigned int *)(0x020E0414U);
115 IOMUXC_SW_PAD_CTL_PAD_NAND_DATA03 = (volatile unsigned int *)(0x020E0418U);
116 IOMUXC_SW_PAD_CTL_PAD_NAND_DATA04 = (volatile unsigned int *)(0x020E041CU);
117 IOMUXC_SW_PAD_CTL_PAD_NAND_DATA05 = (volatile unsigned int *)(0x020E0420U);
118 IOMUXC_SW_PAD_CTL_PAD_NAND_DATA06 = (volatile unsigned int *)(0x020E0424U);
119 IOMUXC_SW_PAD_CTL_PAD_NAND_DATA07 = (volatile unsigned int *)(0x020E0428U);
120
121 *IOMUXC_SW_PAD_CTL_PAD_NAND_RE_B = 0x17059;
122 *IOMUXC_SW_PAD_CTL_PAD_NAND_WE_B = 0x17059;
123 *IOMUXC_SW_PAD_CTL_PAD_NAND_DATA00 = 0x17059;
124 *IOMUXC_SW_PAD_CTL_PAD_NAND_DATA01 = 0x17059;
125 *IOMUXC_SW_PAD_CTL_PAD_NAND_DATA02 = 0x17059;
126 *IOMUXC_SW_PAD_CTL_PAD_NAND_DATA03 = 0x17059;
127 *IOMUXC_SW_PAD_CTL_PAD_NAND_DATA04 = 0x17059;
128 *IOMUXC_SW_PAD_CTL_PAD_NAND_DATA05 = 0x17059;
129 *IOMUXC_SW_PAD_CTL_PAD_NAND_DATA06 = 0x17059;
130 *IOMUXC_SW_PAD_CTL_PAD_NAND_DATA07 = 0x17059;
1.3.2 时钟配置
配置完引脚后,我们还需要设置时钟源。为了正确设置USDHC2的时钟需要解决两个问题。第一是EMMC设备支持什么时钟速率,第二USDHC2的时钟是从哪里来。
1.3.2.1 步骤1:获得eMMC设备的时钟速率。查看核心板所用的eMMC设备手册《MTFC4GACAJC》得知,MTFC4GACAJC 支持HS200、HS400、SDR和DDR模式,最高时钟频率为52MHz。那么上电时MTFC4GACAJC 支持的时钟频率是多少呢?在MTFC4GACAJC手册的EXCSD表中HS_TIMING得知其始化值为00h。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mWWMATyq-1642060301327)(第十三章 EMMC编程.assets/13_EMMC_Program_image058.png)]
这个值代表什么意思呢?我们通过《eMMC5.0Spec_JESD84-B50》得知,HS_TIMING高字节代表驱动能力,低字节代表时钟速率。HS_TIMING为0时,代表时钟速率为兼容模式,即时钟速率范围为0~26MHz。本实验我们选择USDHC2时钟速率为400KHz。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AQJrBUra-1642060301327)(第十三章 EMMC编程.assets/13_EMMC_Program_image059.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yp3ovN8w-1642060301327)(第十三章 EMMC编程.assets/13_EMMC_Program_image060.png)]
11.3.2.2 步骤2:USDHC2的时钟配置在芯片应用手册《Chapter 18 Clock Controller Module》的时钟树图中可以看到USDHC2时钟源是PLL2的PFD0或PFD2。同时我们也可以看出,使能USDHC2时钟所要配置的寄存器为CSCDR1[USDHC2_POPF]、CSCMR1[USDHC2_CLK_SEL]和CCGR6[CG2]。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8p7oxp9p-1642060301328)(第十三章 EMMC编程.assets/13_EMMC_Program_image061.png)]
- 配置CSCMR1[USDHC2_CLK_SEL]:
如下图,USDHC2_CLK_SEL为0时时钟源是PLL2_PFD2,否则是PLL2_PFD0。本实验选择PLL2_PFD2,所以CSCMR1[USDHC2_CLK_SEL]使用默认值即可。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MlnCP61T-1642060301328)(第十三章 EMMC编程.assets/13_EMMC_Program_image062.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eBztYbaF-1642060301328)(第十三章 EMMC编程.assets/13_EMMC_Program_image063.png)]
- 配置CSCDR1[USDHC2_POPF]:
如下图USDHC2_POPF的值代表分频系数,范围为1~8。本实验采用2分频所以CSCDR1[USDHC2_POPF]选择默认值0x1即可。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9SW1lBm2-1642060301328)(第十三章 EMMC编程.assets/13_EMMC_Program_image064.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mPdQvwvx-1642060301329)(第十三章 EMMC编程.assets/13_EMMC_Program_image065.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zJxRuC0A-1642060301329)(第十三章 EMMC编程.assets/13_EMMC_Program_image066.png)]
- 配置CCGR6[CG2]:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-np4Kext9-1642060301329)(第十三章 EMMC编程.assets/13_EMMC_Program_image067.png)]
由上图CCM_CCGR6寄存器可知,CCM_CCGR6[CG2] 的默认值为11,11表示该模块时钟使能(参考《4.3.2 CCM用于设置是否向GPIO模块提供时钟》),所以这里采用初始值即可。
由时钟树图我们可知道此时USDHC2_CLK_ROOT = PLL2_PDF2 / 2。通过查询手册得知PLL2_PDF2初始值396MHz。USDHC2_CLK_ROOT的频率则为198MHz。
为了实现400KHz的时钟频率,我们还要配置USDHC2_SYS_CTRL寄存器中的SDCLKFS[15:8]和DVS[7:4],
- 配置USDHC2_SYS_CTRL:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-80G5ZA14-1642060301329)(第十三章 EMMC编程.assets/13_EMMC_Program_image068.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QzDyJM70-1642060301330)(第十三章 EMMC编程.assets/13_EMMC_Program_image069.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EDkfkWrA-1642060301330)(第十三章 EMMC编程.assets/13_EMMC_Program_image070.png)]
SDCLKFS是uSDHC时钟预分频系数,当在SDR模式时,分频值为1、2、4、8、16、32、64、128、256。当在
DDR模式时,分频值为SDR模式时的一倍。
DVS是uSDHC时钟分频系数,范围从1到16。
USDHC2_CLK的速率公式存在两种它们分别为:
SDR模式: USDHC2_CLK = USDHC2_CLK_ROOT / (SDCLKFS * DVS)
DDR模式: USDHC2_CLK = USDHC2_CLK_ROOT / (SDCLKFS * 2* DVS)
本实验我们的uSDHC_CLK设定为400KHz,eMMC上电后工作在SDR模式中,经过计算,选择SDCLKFS设置为40h,DVS设置为3。通过公式计算实际uSDHC_CLK频率为396KHz。
相关代码如下:
192 /* 设置时钟为400KHz. */
193 //Single Data Rate mode,默认使用PLL2_PFD2 = 396Mhz, usdhc2_clk_root = 396Mhz / 2 = 198Mhz
194 //usdhc2_clk = usdhc2_clk_root / (prescaler * divisor)
195 //SDCLKFS = 0x40 = 128分频
196 //DVS = 0x03 = 4分频
197 //usdhc2_clk = 198Mhz/(128*4) = 0.387Mhz
198 usdhc2_reg->SYS_CTRL &= ~((0xFF00) | (0xF0));
199 usdhc2_reg->SYS_CTRL |= (0x0040U mix_ctrl) & (0x20U | 0x2U | 0x10U | 0x8U ));
DDR_EN掩码为0x8U,DTDSEL的掩码为0x10,BCEN的掩码为0x2U,MSBSEL的掩码为0x20U。
第267行代码:将uSDHC2_MIX_CTRL的DDR_EN、DTDSEL、BCEN、MSBSEL设置为0。
第268行代码:将uSDHC2_MIX_CTRL设置为mix_ctrl的值。
配置完传输方式后,将命令参数写入uSDHC2_CMD_ARG寄存器。
270 usdhc2_reg->CMD_ARG = command->arg;
最后根据命令的要求配置uSDHC2_CMD_XFR_TYP寄存器的命令索引、应答类型、命令CRC校验使能、命令检查使能和数据传输使能。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-64EiP2oF-1642060301332)(第十三章 EMMC编程.assets/13_EMMC_Program_image079.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8qR59Vbe-1642060301332)(第十三章 EMMC编程.assets/13_EMMC_Program_image080.png)]
代码如下:
272 /* 配置命令参数 */
273 // CDMINX掩码:0x3F000000U
274 // DPSEL掩码:0x200000U
275 // CICEN掩码:0x100000U
276 // CCCEN掩码:0x80000U
277 // PSPTYP[1:0]掩码:0x30000U
278 usdhc2_reg->CMD_XFR_TYP &= ~(0x3F000000U | 0x200000U | 0x100000U | 0x80000U | 0x30000U);
279
280 usdhc2_reg->CMD_XFR_TYP = (((command->index INT_STATUS & 0x1U ) )
285 {
286 }
287
288 /* 清中断标记位 */
289 // CC位掩码:0x01
290 usdhc2_reg->INT_STATUS &= 0x01U ;
第284-286行代码:检查INT_STATUS寄存器的CC位是否为1,如果为1则进行后续操作,否则继续等待直到命令发送完毕。
第290行代码:清除INT_STATUS寄存器的CC位。
最后根据应答类型读取应答寄存器的值。IMX6将应答数据 的CRC部分去掉,其余部分保存到 uSDHC2_CMD_RSP0-3寄存器中。如下表所示,除R2应答是120bit,其他的应答都是32位并存储在uSDHC2_CMD_RSP0或uSDHC2_CMD_RSP3。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9ZaYKGOR-1642060301333)(第十三章 EMMC编程.assets/13_EMMC_Program_image082.png)]
代码如下:
295 /**********************************************************************
296 * 函数名称: USDHC_ReadResponse
297 * 功能描述: 读取Response
298 * 输入参数: USDHC_Command* command :USDHC命令结构体
299 * 输出参数: 无
300 * 返 回 值: 无
301 * 修改日期 版本号 修改人 修改内容
302 * -----------------------------------------------
303 * 2020/02/28 V1.0 LJZ 创建
304 ***********************************************************************/
305 void USDHC_ReadResponse(USDHC_Command *command)
306 {
307 unsigned int i;
308
309 if( command->response_type != ResponseTypeNone )
310 {
311 command->response[0] = usdhc2_reg->CMD_RSP0;
312
313 if( command->response_type == ResponseTypeR2 )
314 {
315 command->response[1] = usdhc2_reg->CMD_RSP1;
316 command->response[2] = usdhc2_reg->CMD_RSP2;
317 command->response[3] = usdhc2_reg->CMD_RSP3;
318
319 i = 4;
320
321 do
322 {
323 command->response[i - 1] response[i - 1] |= ((command->response[i - 2] & 0xFF000000U) >> 24U);
327 }
328 } while (i--);
329 }
330 }
331 }
第313-329代码:为了后续处理方便应答类型为R2时我们将uSDHC2_CMD_RSP0-3的数据左以7位。
1.3.4.2 步骤1:eMMC初始化发送命令的函数已经准备好了,现在我们编写程序发送第一个命令CMD0。在编程序之前先了解CMD0的信息。从下表可知,CMD0是无应答广播命令,根据参数的不同eMMC进入不同的状态。
类型参数应答无应答广播0x00000000无无应答广播0xF0F0F0F0无-0xFFFFFFFA无本步骤中需要eMMC进入IDLE状态进行复位,所以参数的值为0x00000000。(这里应该怎么说)MIX_CTRL的值应为0x0。CMD_XFR_TYP也设置为0。应答类型为无应答。代码如下:
16 command.index = 0;
17 command.arg = 0;
18 command.mix_ctrl = 0;
19 command.xfr_typ = 0;
20 command.response_type = ResponseTypeNone;
21
22 //发送CMD0
23 USDHC_SendCommand(&command);
根据13.1.9的状态图,此时需要发送CMD1读取eMMC的OCR寄存器,通过第31位判断eMMC是否复位完毕。CMD1的描述如下:
类型参数应答类型有应答广播0R3相关代码如下:
25 for( i = 0; i
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?