This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
我尝试使用 TMS320F28379D 和外部 SDRAM 存储器(2M 字 x 32位 x 4组 - AS4C8M32S-6TIN)设置定制板、EMIF1设置 EMIF1CLK = CPU1SYSCLK/2、CPU1SYSCLK = 200MHz。
我还将 emif1_32BIG_SDRAM_cpu01示例代码调整为我的自定义应用程序。
我看到的问题是、所有数据似乎都被镜像到外部存储器的所有地址、而不是像示例代码执行的那样在每个存储器位置增加1。
如果我将 CPU1SYSCLK 减少至100MHz、将 EMIF1时钟减少至50MHz、我可以使应用正常运行。
我修改了代码以执行文档中建议的两种初始化方法(SPRUHM8I、25.5.5.5 SDRAM 配置过程)、但这两种方法似乎都具有相同的结果。
是否有人可以检查我的外部 SDRAM 设置是否正常、并帮助使该接口在100MHz 的 EMIF1下正常工作?
请参阅下面的程序 B 使用的代码。此外、我已将内存浏览器行为附加到以50MHz (工作正常)和100MHz (具有镜像数据)运行的 EMIF1代码。
//---------------------------------- //包括 //----------------- #include "F2837xD_DEVICE.h" #include "F2837xD_examples.h" #include "GPIO.h" #include "EMIF1.h" //定义 // #define TEST_PASS 0xABCDABCD #define TEST_FAIL 0xDEADDEEAD #define SDRAM_CS0_START_ADDR 0x8000000 #define SDRAM_CS0_SIZE 0x00800000 // // Globals // UINT16 ErrCount = 0; UINT32 test_status; UINT32 ii; void Emif1Config (void) { char 勘误表_local; TEST_STATUS = TEST_FAIL; EALLOW; // //为 CPU1抓取 EMIF1 // EMIF1ConfigRegs.EMIF1MSEL.ALL = 0x93A5CE71; if (emif1ConfigRegs.EMIF1MSEL.all!= 0x1) { ErrCount++; } // //禁用访问保护(CPU_Fetch、CPU_WR/DMA_WR) // EMIF1ConfigRegs.EMIF1ACCPRT0.ALL = 0x0; if (emif1ConfigRegs.EMIF1ACCPRT0.ALL!= 0x0) { ErrCount++; } // //提交与保护相关的配置。 直到该位保持不变 //设置 EMIF1ACCPROT0寄存器的内容不能更改。 // EMIF1ConfigRegs.EMIF1COMMIT.ALL = 0x1; if (emif1ConfigRegs.EMIF1COMMIT.ALL!= 0x1) { ErrCount++; } // //锁定配置,使 EMIF1COMMIT 寄存器不能更改 //任何更多。 // EMIF1ConfigRegs.EMIF1LOCK.ALL = 0x1; if (emif1ConfigRegs.EMIF1LOCK.ALL!= 1) { ErrCount++; } EDIS; InitEsaTrdEmif1Gpio();
//将内存置于自刷新模式以更改频率 emif1Regs.SDRAM_CR.bit.SR = 0x1; //配置为在半速率上运行 EMIF1 (EMIF1CLK = CPU1SYSCLK/2) // EALLOW; ClkCfgRegs.PERCLKDIVSEL.bit.EMIF1CLKDIV = 0x1; EDIS;
//释放自刷新模式 emif1Regs.SDRAM_CR.bit.SR = 0x0; //配置 SDRAM 控制寄存器 //需要根据 SDRAM 数据表进行编程。 //T_RFC = 60ns = 0x6 //T_RP = 18ns = 0x1 //T_RCD = 18ns = 0x1 //T_WR = 12ns = 0x1 //T_RAS = 42ns = 0x4 //T_RC = 60ns = 0x6 //T_RRD = 12ns = 0x1 emif1Regs.SDRAM_TR.bit.T_RFC = 0x6; emif1Regs.SDRAM_TR.bit.T_RP = 0x1; emif1Regs.SDRAM_TR.bit.T_RCD = 0x1; emif1Regs.SDRAM_TR.bit.T_WR = 0x1; emif1Regs.SDRAM_TR.bit.T_RAS = 0x4; emif1Regs.SDRAM_TR.bit.T_RC = 0x6; emif1Regs.SDRAM_TR.bit.T_RRD = 0x1; //Txsr = 61.5ns = 0x6 EMif1Regs.SDR_EXT_TMNG.bit.T_XS = 0x6; //Tref = 64ms (15.6us*4096)对于4096行、RR = 64m*100M/4096 = 1562.5 (0x61B) //Emif1Regs.SDRAM_RCR.ALL = 0x61B;
//过程2配置 emif1Regs.SDRAM_RCR.bit.refresh_rate = 0x9C5; //pagesize=1 (每行元素数)、IBANK = 2 (4组)、CL = 3、NM = 0 (32位) //Emif1Regs.SDRAM_CR.all = 0x00000720; emif1Regs.SDRAM_CR.bit.SR = 0x0; emif1Regs.SDRAM_CR.bit.nm = 0; emif1Regs.SDRAM_CR.bit.CL = 0x3; EMif1Regs.SDRAM_CR.bit.bit_11_9_LOCK = 0x1; EMif1Regs.SDRAM_CR.bit.IBANK = 0x2; EMIF1Regs.SDRAM_CR.bit.PAGESIGE = 0x3;
//添加延迟以满足 SDRAM 加电限制 DELAY_US (200);
//配置 SDRAM 数据表刷新率 emif1Regs.SDRAM_RCR.bit.refresh_rate = 0x61b; // //添加一些额外的延迟 // for (ii = 0;ii < 123;ii +){} //基本读/写检查。 ErrCount_Local = SDRAM_READ_WRITE (SDRAM_CS0_START_ADDR、SDRAM_CS0_SIZE); ErrCount = ErrCount + ErrCount_LOCAL; //运行不同的地址步行检查 ErrCount_Local = SDRAM_addr_walk (SDRAM_CS0_START_ADDR、15); ErrCount = ErrCount + ErrCount_LOCAL; //运行不同的数据步行检查 ErrCount_Local = SDRAM_DATA_Walk (SDRAM_CS0_START_ADDR、SDRAM_CS0_SIZE); ErrCount = ErrCount + ErrCount_LOCAL; //运行不同的数据大小检查 ErrCount_Local = SDRAM_DATA_SIZE (SDRAM_CS0_START_ADDR、4); ErrCount = ErrCount + ErrCount_LOCAL; 如果(ErrCount = 0x0) { test_status = test_pass; } } // // SDRAM_DATA_Walk -此函数为 SDRAM RD & WR 执行步行0 & 1 // char SDRAM_DATA_walk (uint32 start_addr、uint32 mem_size) { uint32 xm_p、XMEM_p; unsigned long SDRAM_rdl; unsigned long SDRAM_wdl; int i; int k; int m; xm_p = start_addr; 对于(i=0;i < mem_size;i=i+64) { 对于(m=0;m < 2;m++) { XMEM_p = xM_p; // //写入循环 // SDRAM_wdl = 0x0001; 对于(k=0;k < 32;k++) { 如果(m=0) { __addr32_write_uint32 (XMEM_p、SDRAM_wdl); } 其他 { __addr32_write_uint32 (XMEM_p、~SDRAM_wdl); } XMEM_p = XMEM_p+2; SDRAM_wdl = SDRAM_wdl<<1; } // //读取循环 // XMEM_p = xM_p; SDRAM_wdl = 0x0001; 对于(k=0;k < 32;k++) { SDRAM_rdl =__addr32_read_uint32 (XMEM_p); 如果(m==1) { SDRAM_rdl =~SDRAM_rdl; } if (SDRAM_rdl!= SDRAM_wdl) { 返回(1); } XMEM_p = XMEM_p+2; SDRAM_wdl=SDRAM_wdl<<1; } } XM_p = XMEM_p; } return (0); } // SDRAM_addr_walk -此函数对每个地址位执行切换。 // 在这种情况下、假定内存为4MB。 // ma = BA[1:0] row[11:0] COL[7:0] // char SDRAM_addr_walk (uint32 start_addr、uint32 addr_size) { uint32 XMEM_p; unsigned long SDRAM_rdl; unsigned long SDRAM_wdl; int i; 无符号长 x 移位; 无符号长整型 xshift2; // //写入循环 // xshift = 0x00000001; SDRAM_wdl = 0x5678abcd; 对于(i=0;i < addr_size;i++) { xshift 2 =((xshift+1)<1); XMEM_p = start_addr + xshift2; __addr32_write_uint32 (XMEM_p、SDRAM_wdl); SDRAM_wdl = SDRAM_wdl+0x111111; xshift = xshift<<1; } // //读取循环 // xshift = 0x00000001; SDRAM_wdl = 0x5678abcd; for (i=0;i < addr_size;i++) { xshift 2 =((xshift+1)<1); XMEM_p= start_addr + xshift2; SDRAM_rdl =__addr32_read_uint32 (XMEM_p); if (SDRAM_rdl!= SDRAM_wdl) { 返回(1); } xshift = xshift <<1; SDRAM_wdl = SDRAM_wdl + 0x11111111; } return (0); } // SDRAM_DATA_SIZE -此函数执行不同的数据类型 // (HALFWORD/WORD)访问。 // char SDRAM_DATA_SIZE (uint32 start_addr、uint32 mem_size) { 无符号短整型 SDRAM_RDS; unsigned long SDRAM_rdl; 无符号短整型 SDRAM_WDS; unsigned long SDRAM_wdl; int i; uint32 XMEM_p; // //写数据短整型 // XMEM_p = start_addr; SDRAM_WDS = 0x0605; 对于(i=0;i < 2;i++) { __addr32_write_uint16 (XMEM_p、SDRAM_WDS); XMEM_p++; SDRAM_WDS += 0x0202; } // //长写数据 // SDRAM_wdl = 0x0C0B0A09; 对于(i=0;i < 2;i++) { __addr32_write_uint32 (XMEM_p、SDRAM_wdl); XMEM_p = XMEM_p+2; SDRAM_wdl += 0x04040404; } // //读取数据短整型 // XMEM_p = start_addr; SDRAM_WDS=0x0605; 对于(i=0;i < 6;i++) { SDRAM_RDS =__addr32_read_uint16 (XMEM_p); if (SDRAM_RDS!= SDRAM_WDS) { 返回(1); } XMEM_p++; SDRAM_WDS += 0x0202; } // //长读数据 // XMEM_p = start_addr; SDRAM_wdl=0x08070605; 对于(i=0;i<3;i++) { SDRAM_rdl =__addr32_read_uint32 (XMEM_p); if (SDRAM_rdl!= SDRAM_wdl) { 返回(1); } XMEM_p = XMEM_p+2; SDRAM_wdl += 0x04040404; } return (0); } // SDRAM_READ_WRITE -此函数执行简单的读/写访问 // 存储器。 // char SDRAM_READ_WRITE (uint32 start_addr、uint32 mem_size) { unsigned long mem_rdl; unsigned long mem_wdl; uint32 XMEM_p; uint32 i; // //写入数据 // XMEM_p = start_addr; // //填充存储器 // MEM_wdl = 0x01234567; 对于(i=0;i < mem_size;i++) { __addr32_write_uint32 (XMEM_p、mem_wdl); XMEM_p = XMEM_p+2; MEM_wdl += 0x11111111; } // //验证内存 // MEM_wdl = 0x01234567; XMEM_p = start_addr; 对于(i=0;i < mem_size;i++) { MEM_rdl =__addr32_read_uint32 (XMEM_p); if (mem_rdl!= mem_wdl) { 返回(1); } XMEM_p = XMEM_p+2; MEM_wdl += 0x11111111; } 返回(0); }
恩里克
您可以使用此配置工具检查 EMIF 设置:~\C2000Ware_XXXX\boards\TIDesigns\F28379D_EMIF_DC\C2000-EMIF_ConfigurationTool.xlsx
本 应用手册 提供了一些使用和调试建议。 这里还有其他相关示例:~\C2000Ware_XXXX\device_support\f2837xd\examples\CPU1\EMIF_dc__*
Tommy
Tommy、
我已经使用了电子表格来验证所有寄存器配置。 它们看起来都是正确的。
此外、请阅读应用手册。 您的建议。 在 DE 代码和接口方面看不到任何问题。
您能否详细了解一下该代码?
EMIF 实际上可以运行为100MHz 吗?
恩里克。
[报价用户="Henrique Chaves">我已经使用电子表格来验证所有寄存器配置。 它们看起来都是正确的。
此外、请阅读应用手册。 您的建议。 DE 代码和接口不能出现任何问题。[/quot]
您是否在以100MHz 运行时尝试降低 SDRAM 时序参数的速度? 可能只有一个或两个参数具有计时灵敏度。
[报价用户="Henrique Chaves"]您能否详细了解代码?
由于您能够以50MHz 的频率运行、并且您可以使用内存浏览器观察问题、因此 EMIF 配置之外的代码可能不太相关。 如果您使用内存浏览器手动更改内存位置的内容、会发生什么情况?
[引用用户="Henrique Chaves"] EMIF 是否可以真正以100MHz 运行?[/引用]
是的。 您是否通过观察 XCLKOUT 或 EMIF 时钟来确认 SYSCLK 真正以200MHz 运行?
a)您是否在以100MHz 运行时尝试降低 SDRAM 时序参数的速度? 可能只有一个或两个参数具有计时灵敏度。
是的、我一直在努力将所有计时寄存器(但不是 AppNote 中提到的 refresh_rate)增加到最大值、但仍然看到相同的响应。 下面是我为执行此测试而更改的内容:
emif1Regs.SDRAM_TR.bit.T_RFC = 0xF; emif1Regs.SDRAM_TR.bit.T_RP = 0x7; emif1Regs.SDRAM_TR.bit.T_RCD = 0x7; emif1Regs.SDRAM_TR.bit.T_WR = 0x7; emif1Regs.SDRAM_TR.bit.T_RAS = 0xF; emif1Regs.SDRAM_TR.bit.T_RC = 0xF; emif1Regs.SDRAM_TR.bit.T_RRD = 0x7; EMif1Regs.SDR_EXT_TMNG.bit.T_XS = 0x1F;
B)由于您能够以50MHz 的频率运行、并且您可以使用内存浏览器观察到问题、因此 EMIF 配置之外的代码可能不太相关。 如果您使用内存浏览器手动更改内存位置的内容、会发生什么情况?
当我使用内存浏览器手动更改内存位置的内容时、会发生以下情况:我更改的数据被镜像到所有内存位置(与我先前发送的第二次打印的行为相同)。
c)是的。 您是否通过观察 XCLKOUT 或 EMIF 时钟来确认 SYSCLK 真正以200MHz 运行?
是的、我可以确认使用 PWM 输出、并且我已经验证了 EMIF 时钟。 请看一下它以50MHz 和100MHz 的频率运行。
为了调试这个操作、可以执行什么操作?
恩里克
理想情况下、SDRAM 时钟应为方波。 对于100MHz 示波器脉冲、它看起来是正弦波。 您能否查看示波器是否正在对通道应用低通滤波器、或者通过查看干净的信号源来验证其运行情况? 如果没有更好地定义信号、SDRAM 将难以解释其指令。
这是在 F28379引脚还是 SDRAM 引脚附近探测的? SDRAM 上的信号就越重要。 最好检查几个其他信号以及它们与 SDRAM 时钟的对齐程度。
Tommy
Tommy、
波形看起来是正弦波、因为我的示波器带宽限制为100MHz。 我已经仔细检查了28379D controlCARD 中测量同一信号的情况。 测量结果接近 SDRAM。 它们之间的距离约为3厘米。 最长的迹线约为5cm。
您还需要其他哪些信号? 我正在为 SDKE、CS0、RAS、CAS 和 WE 设置测量。
恩里克。
Tommy、您好!
我正在帮助 Henrique 解决这个问题、我们意识到、即使在100MHz 频率下、到 SDRAM 的写入过程也能很好地工作。 我们用100MHz 做了很多文章、然后以50MHz 的频率读取所有数据、数据没有错误。 如果我们使用100MHz 来查看或确认写入的数据、结果是针对28379D 中从0x800000000到0x8FFFFFFF 的所有可能位置(是的、即使在映射0x800000000到0x80800000 - 8Mbx32bits 的存储器范围之外)的镜像情况、具有最后写入的值。 这个问题似乎只涉及在所有位置都有镜像数据的图片中显示的读取部分。
有人想知道我们可以观察到什么存储器引脚、或者在何处更改参数、以便对存储器进行正确的读取过程?
在前面所示的用于测试存储器的算法中、我们会进行写作和读数、比较数据等、以便在所需频率(100MHz)下进一步使用该外设。
我们有两种相同的硬件设置、它们在不同的工作区中工作、但两者的上述行为是相同的。 28379D 和 SDRAM 的定制板应尽可能靠近同一 PCB 中的处理器... 我们再次检查了已路由的轨道、现在我们正在丢弃布局问题。
我们将对其他制造商的存储器和其他晶体振荡器基频执行相同的测试。 对于具有上述结果的测试、我们将使用一个外部10MHz 振荡器用于 DSP... 我们将获取20MHz 和25MHz 振荡器、以便在内部乘以较低的数字。
此时、我们将假设、除了使用了一些错误的参数外、在将 PLL 频率或存储器内部结构读数相乘时、还会产生一些特殊的影响... 这对您来说是可能的还是可以接受的? 您以前见过吗?
您是否有一个使用28379D 和 SDRAM 的实例在 EMIF 总线的100Mhz 下工作正常? 如果是、使用什么器件型号存储器?
谢谢
泰勒
...当我要求一些在您知道的实际项目中运行的 SDRAM 时,我将讨论32位的内存配置。
我们发现一些德州的 SDRAM 开发套件采用16位结构、如果我没有错、示例适用于120MHz 处理器中使用的 EMIF 总线中的60MHz。
在该时钟速率下、我们的定制板在写入和读取时没有错误。 实际上、在 EMIF1总线中、配置正确操作的限制是63、75Mhz (在125MHz 下为28379D、远远超出我们的200MHz 需求)。 如果时钟速率在 EMIF 中增加超过63、75Mhz、则内存浏览器或其中的变量中的读数开始变得越来越不稳定或错误、直到在 EMIF1频率以100Mhz 工作之前实现该模式显示。
此致
泰勒
[引用用户="Taylor Wisceck)]我正在帮助 Henrique 解决这个问题,我们意识到即使在100MHz 下也能很好地完成 SDRAM 的写入过程。 我们用100MHz 做了很多文章、然后以50MHz 的频率读取所有数据、数据没有错误。
这是一个很好的观察结果、因为您可以减少对写入和读取操作之间差异的关注。 除了我们之外、看起来这两个命令的大部分真值表都是相同的。 当然、数据+ DQM 信号现在由 SDRAM 而不是 EMIF 驱动。 因此、我建议在50MHz 下读取时观察示波器上的不同信号、并将它们与100MHz 下的读取进行比较、以查看信号完整性是否存在差异。
[引用 USER="Taylor Wisceck ]\n 我们现在假设、除了使用了一些错误的参数外、在将 PLL 频率或存储器内部结构读数相乘时、还会产生一些特殊的影响... 这对您来说是可能的还是可以接受的? 您以前见过吗?[/引述]
您可以使用 EMIF CLK 信号表示 EMIF 模块所见的内部时钟。 如果引脚上的时钟看起来很干净、则很可能在内部正常。
[引用 USER="Taylor Wisceck ]EMIF 总线中使用28379D 和 SDRAM 的实例是否在100Mhz 下运行良好? 如果是、则使用什么器件型号存储器?
是的、我已经将 Henrique 指向 EMIF 配置工具、该工具与以100MHz 运行的参考设计位于同一目录中、我还指向了在该参考设计上运行的示例:
您可以使用此配置工具检查 EMIF 设置:~\C2000Ware_XXXX\boards\TIDesigns\F28379D_EMIF_DC\C2000-EMIF_ConfigurationTool.xlsx
本 应用手册 提供了一些使用和调试建议。 这里还有其他相关示例:~\C2000Ware_XXXX\device_support\f2837xd\examples\CPU1\EMIF_dc__*
使用的器件型号为 AS4C16M16SA 和 IS42S16160J。 这些是16位 SDRAM、但只要 EMIF 配置正确、与32位 SDRAM 的区别就可以忽略不计。
AppNote 中也有吞吐量基准。
Tommy、
感谢您的回复。 Henrique 昨天在内部使用 GPIO 配置部分尝试了另一种内存测试算法。 它在100MHz EMIF 总线中非常适合写作和读数。 之后、我将相同的 GPIO 配置放入我们的第一个存储器测试算法中、最终效果良好。 因此、我们得出结论、C2000ware 提供的第一个使用的算法中只分配了一些错误的 GPIO EMIF 配置。 我们将发现 EMIF GPIO 设置的差异、以确认和了解之前暴露的行为... 可能有一些内部上拉电阻缺失/损坏或覆盖多路复用器配置或类似的情况会导致与时钟速率相关的可插入式 sympton。。。 现在只是为了澄清。
感谢您的支持。
此致。
您好!
显然 、我在所有数据引脚中都缺少用于异步的鉴定周期配置。
解决了问题。 不过、我仍然不明白为什么它在50MHz 配置下运行正常。
恩里克
很高兴您现在可以使用它。 当外部信号锁存时、鉴定级有可能插入数字延迟、具体取决于外部信号满足 GPIO 设置时间的程度。 在50MHz 时、设置时序更容易满足、因此不会发生延迟。
Tommy