编程器读取EMMC出现数据错误

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编程器读取EMMC出现数据错误相关的知识,希望对你有一定的参考价值。

参考技术A 原因是编程器没有找到EMMC。
1、先确认主板上面飞线的点是否找对。
2、自己的焊点焊的是否存在问题。
3、主板EMMC芯片的供电是否正常。
4、主芯片的晶振知否短路并已经接地。
5、软件里面的设置VCCIO电压是否调整的对。
6、主板EMMC有没有损坏。

13_EMMC编程

第十三章 EMMC编程(有误)

​ 参考资料

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标准接口封装到一块芯片上,如下图所示。

1.1.2 EMMC硬件连接

​ 如下图所示,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~52MHz104MHz
HS200模式SDR1.8/12V4、8bit0~200MHz200MHz
HS400模式DDR1.8/12V8bit0~200MHz400MHz

1.1.4 eMMC总线协议

​ eMMC总线可以挂载一个主设备和多个eMMC设备。总线上的所有通讯都由主机发起,主机一次只能与一个eMMC设备通讯。

​ 系统在上电后,主机会给所有eMMC设备分配地址。当主机需要和某一个eMMC设备通讯时,会先根据RCA选中该eMMC设备,只有被选中的 eMMC设备才会应答主机的命令。

​ eMMC的通信是由单个或多个块组成的。它们分别是命令、应答、数据块,如下图所示。

​ 读取eMMC数据的数据流如下图所示。如果主机发送的是读单个块的命令,那么eMMC设备只会发送一个块的数据,并且不用发送停止命令。

​ 写入eMMC数据过程如下图所示。

​ 如下图所示通信中除了带数据的命令,也有不带数据和不带应答的命令。

1.1.5 命令(CMD)介绍

1.1.5.1 (1) 命令类型

​ CMD有4中类型,分别为:不带应答的广播命令(br);带有应答的广播命令(bcr);点对点无数据传输(ac);点对点有数据传输(adtc)。

1.1.5.2 (2) 命令格式

​ 如下图所示CMD是一个由起始位、传输位、命令索引、命令参数、CRC和结束位组成,一共有48位。

起始位传输位命令索引命令参数CRC结束位
位置4746[45:40][39:8][7:1]0
“0”“1”xxx“1”

​ 起始位固定为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 State
Idle State设备识别模式
Ready State
Identification State
Stand-by State数据传输模式上下拉
Sleep State
Transfer State
Bus-Test State
Sending-data State
Programming State
Disconnect State
Boot 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设备进行读写,擦除,总线测试等操作。此模式工作状态图如下所示。

1.2 IMX6ULL EMMC寄存器介绍

1.2.1 IMX6ULL USDHC模块介绍

​ 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停止。

1.2.2.2 (2)uSDHC2_CMD_ARG

​ uSDHC2_CMD_ARG是命令的参数寄存器,保存要下发命令的参数。

1.2.2.3(3)uSDHC2_CMD_XFR_TYP

​ uSDHC2_CMD_XFR_TYP是命令传输类型寄存器。用于配置传输的命令编号、命令类型、数据传输、应答类型和校验使能等。

1.2.2.4 (4)uSDHC2_CMD_RSP0-3

​ 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 	u

以上是关于编程器读取EMMC出现数据错误的主要内容,如果未能解决你的问题,请参考以下文章

emmc烧录器原理

c语言编程中字符串复制函数编程程序出现错误,这是怎么回事?

emmc user 区怎么读取

GO并发编程的数据竞争问题

linux下应用mysql数据库c编程,出现段错误求解!

并发编程基础3