Thread 中讨论的其他器件:controlSUITE
Code Composer 存储器窗口是否会通过存储器窗口中的 EMIF 正确地读取存储器并将其写入外部 SDRAM? IE:如果我向0x8000000写入一个值、它是否会正确地将数据写入/读取到外部 SDRAM 中? 还是只能通过正确编码访问外部 SDRAM?
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.
Code Composer 存储器窗口是否会通过存储器窗口中的 EMIF 正确地读取存储器并将其写入外部 SDRAM? IE:如果我向0x8000000写入一个值、它是否会正确地将数据写入/读取到外部 SDRAM 中? 还是只能通过正确编码访问外部 SDRAM?
简单来说、 www.ti.com/.../spruhm8f.pdf 中的第7.2节...当我们为 EMIF1配置 GPIO 时、输入/输出以及输入和输出线路是固定的、对吧? 我们不必指定为输入或输出...
但是、从第25.2节中可以看出、如果我们在外部没有设置上拉电阻器、我仍然需要将输入鉴定设置为异步并向输入线路添加上拉电阻器... 对吧?
在 EMIF1的情况下、唯一的输入线路是数据 I/O 线路。 我是否必须明确地将这些设置为异步? 或者它们的功能是否已硬编码(内置在硬件中)到 EMIF 中?
Rob、
[引用]只是为了说明: www.ti.com/.../spruhm8f.pdf 中的第7.2节...当我们为 EMIF1配置 GPIO 时、输入/输出以及输入和输出线路是固定的、对吧? 我们不必指定为输入或输出... [/报价]
没错。 当任何引脚被选为外设功能时、您没有设置输入/输出。
[引用]但是、从第25.2节中可以看出、如果我们在外部没有设置上拉电阻器、我仍然需要将输入鉴定设置为异步并向输入线路添加上拉电阻器... 对吧? [/报价]
这也是正确的。 如果您使用的是 controlSUITE 中的 pinmux 函数、则它会处理此问题。
Vivek Singh
我们有机会进一步了解这一点... 目前、我们看到了 RAS/CAS 和控制信号的写入周期、但我们正在写入的数据不会出现在数据总线上? 我们正在调查硬件原因、但从软件角度来看、我称之为配置:
CPUGPIO_SetupPinMux (&theCPU->the CPUGPIO、85、GPIO_MUS_CPU2、2);
它只会调用:
void CPUGPIO_SetupPinMux (CPUGPIO * CPUGPIO、unsigned long 引脚、unsigned long CPU、unsigned long 外设){
CPU1
GPIO_SetupPinMux (引脚、CPU、外设);
#endif
}
然后、它只会调用您提供的 TI 版本的剪切和粘贴。
问题似乎只是不在数据线上输入数据... 因此我可以读取所有零(因为数据线实际上是全零...)
我们正在调查 SDRAM 是否以某种方式将总线驱动为低电平、但如果只是配置错误、TI 器件端会提供任何输入。
谢谢。
这是您昨天向我通报的所有内容的当前样子。
是的、假设我在 CPU1上设置 GPIO、您的回答正确。
首先、我能说明:
为了设置 SDRAM_TR 寄存器中的时序值、T_RP、T_RC 等、手动设置会以时钟周期进行编程。 如果数据表中列出的值为18ns、外部时钟为100MHz 或10ns、我们输入的值是否为2? IE:将18舍入至20、然后除以10ns、得到2?
而且他们都说-1…… 那么、在上面的示例中、我会对1进行编程吗?
那么、如果计时为60ns、那么这将是6个时钟周期、但由于-1、我们应该输入5? 对吧?
下一步:
这是我观察到的、在所有权设置中、文档状态00 = CPU1、但 CPU2可以抓取、01、CPU1拥有 EMIF、02 CPU2拥有 EMIF1和11 CPU1、但 CPU2可以抓取...
我观察到、如果我尝试在 CPU1上设置此值、让 CPU2拥有它... 它不做任何事情... 但是、如果我通过在 CPU2上设置相同的寄存器来"抓取" EMIF、那么 CPU2会获取它... 此外、如果我在 CPU1上设置了该寄存器、并将其设置为 CPU1、则 CPU2无法获取它...
重点是... 是否不清楚我在 CPU2上必须设置该寄存器、以"获取" EMIF 的所有权... 您的所有其他所有权(内存等) 我已经对 CPU1执行过操作、想、我将其设置为让 CPU2拥有它... 但在这种情况下、您似乎必须从 CPU2中抓取(即设置所有权)...
您能确认这是正确的行为吗?
因此、我基本上需要将这条线放置在 CPU2中、以使其获得 EMIF1的所有权。
EMIF1ConfigRegs.EMIF1MSEL.ALL = 0x93a5ce72;
这解决了一个问题、我现在可以设置 CPU2中的所有寄存器并观察它们的正确设置。
在进一步测试后、它的性能会更好、但我需要对如何设置时钟和-1的时序寄存器进行验证的答案。 另请注意、在 WR One 上、它会显示"for SDR"、而在其他所有器件上、它会显示:
WR
对于 SDR、这等于中的 EMxCLK 周期的最小数量
到预充电的最后一次写入传输减1。
RC (以及所有其他遵循此格式)
从激活到激活减去的 EMxCLK 周期的最小数量
一个。
"对于 SDR"是什么意思?
摘要;
是采用器件数据表中以 ns 为单位的时序值、在本例中除以100MHz 还是10ns 时钟、然后针对所有这些值减去一个?
我已经可以告诉您、如果我这么做、我看不到正确的写入总线周期... 如果我做以上的事,我会看到 Ras,然后是 CAS,然后我们… 因此、我需要清楚如何设置它们。 谢谢。
非常感谢您的支持、它帮助我更快地找到问题。
尊敬的 Rob:
很高兴知道它工作正常。 正如定义 EMIF1MSEL 寄存器位中提到的、EMIF 的控制需要由单个主器件获取。 这与其他主所有权控制不同。
寄存器设置、您的理解是正确的。 所有值都以周期为单位、您需要以 EMIF 时钟周期的倍数舍入数字、然后减1以获得配置值。 "表25-27中给出了一个示例。 EMIF 的 SDRAM_TR 场计算"。 请参阅相同的内容。
[引用] RC (以及所有其他人都遵循此格式)
从激活到激活减去的 EMxCLK 周期的最小数量
一个。
"对于 SDR"是什么意思? [/报价]
SDR 用于 SDRAM 设置(不适用于 DDR)。
此致、
Vivek Singh
感谢您迄今提供的帮助。
遗憾的是、它仍然无法完全正常工作。
我需要请您深入了解 TI 器件可能出现的问题。
我可以在示波器上捕获自动初始化序列、按照25.3.5.4中的说明、该序列看起来非常完美
为了实现这一点、我需要更改的只是 EMIF 的所有权(将其移至 CPU2)。
我已通过该示例验证、我正在为所选存储器正确设置寄存器。
emif1Regs.SDRAM_TR.bit.T_RAS = 4;
emif1Regs.SDRAM_TR.bit.T_RC = 5;
emif1Regs.SDRAM_TR.bit.T_RCD = 1;
emif1Regs.SDRAM_TR.bit.T_RFC = 5;
emif1Regs.SDRAM_TR.bit.T_RP = 1;
emif1Regs.SDRAM_TR.bit.T_RRD = 1;
emif1Regs.SDRAM_TR.bit.T_WR = 1;
EMif1Regs.SDR_EXT_TMNG.bit.T_XS = 6;
现在、当我在代码中写入一些数据时、我会看到 Code Composer 窗口在所有地址0x8000000及更高的地址更新了该数据、不过是完整的32位。
但是,我当前执行一个示例测试: (其中 MatrixUI->ArrayUI[0]= 0x8000000
对于(;;){
MatrixUI->ArrayUI[0]= 2882342889;//十六进制0xabcd0fe9
MatrixUI->ArrayUI[1]= 0;
MatrixUI->ArrayUI[2]= 1;
MatrixUI->ArrayUI[3]= 2;
MatrixUI->ArrayUI[4]= 3;
values[0]= MatrixUI->ArrayUI[0];
values[1]= MatrixUI->ArrayUI[1];
values[2]= MatrixUI->ArrayUI[2];
values[3]= MatrixUI->ArrayUI[3];
values[4]= MatrixUI->ArrayUI[4];
i = MatrixUI->ArrayUI[0];
if (i =2882342889){
asm (" ESTOP0");
值[0]= I;
}
MatrixUI->ArrayUI[0]= 47;
i = MatrixUI->ArrayUI[3];
如果(i ==2){
asm (" ESTOP0");
值[3]= I;
}
}
如果它正确读取数据、则在以全速运行时应该会达到 ESTOP0、并且它永远不会...
我根据您关于数据总线将保存写入的最后一个值的陈述来安排测试... 当然、如果我将上述程序更改为包含以下内容:
MatrixUI->ArrayUI[whateverIndex]= somenumber;
i = MatrixUI->ArrayUI[whateverIndex];
如果(i == somenumber){
asm (" ESTOP0");
然后它当然起作用、因为某些数字是我最后一次写入总线的数据... IE:它符合 ESTOP0、
因此、这就是我构建上述代码以不测试刚刚写入的值的原因... 测试它是否真的在读取它...
现在、当我查看示波器上的写入周期时、它看起来并不完全正确。 主要是先发生 Ras、然后是 cas、然后是我们... 但我们应该在 cas 正确的同时发生呢? 在 CAS 线路之后、我们开始减少1个时钟周期、因此延迟了1个周期...
那么问题是、对于我为时序编程的值、为什么 TI 器件显然会产生略微扰动的写入周期...
这与调试器有什么关系吗?
此外、使用这些设置、当我使用 Code Composer 存储器窗口进行写入时、我仍然看到16位复制、而不是32位复制、当我使用代码进行写入时、我看到...
关于以下方面的任何想法:
为什么 我们可以延迟写入周期、
2. 为什么我基本上只能读取总线上最后放置的内容? (我认为这是因为写入周期不正确、所以它实际上不会写入存储器、 虽然我没有检查读取周期、但我想肯定有问题、因为如果正确、它应该读取 SDRAM 中存储的任何内容、并相应地驱动总线...
3. 是否可能我要求它超过某些最大/最小限制、所以 EMIF 无法生成正确的周期、因为我"超出范围"
谢谢。
谢谢 Vivek。
我查看了您的 F2837xD_EMIF.c 文件、需要提出一些澄清问题。
我终于能够读取和写入 SDRAM、我可以在代码中以及通过 code composer memory 窗口执行此操作... 但以下事项需要进行分层:
在 F2837xD_EMIF.c 版本200下(我尚未开始使用210版本)有一个函数 setup_emif1_pinmux_SDRAM_32位
在此函数中、您按原样设置 GPIO 引脚、调用 GPIO_SetupPinMux ...
这与我所做的相同、除了... 您调用 GPIO_SetupPinMus (94...
分层1:
为什么设置引脚94? 在表7-8中、引脚94现在具有 EMIF 特定的功能... 实际上、在我们的电路板上、我们为 GPIO94...
因此、我只需要澄清引脚94用于该示例应用中的其他用途、与 EMIF1无关。
分层2:
然后、您继续为数据线路和 EM1DQM0-3线路调用 GPIO_SetupPinOptions。。。 您可以将它们设置为具有上拉和异步模式的输入(0是输入、0x31是与上拉异步)
我觉得这有点令人困惑。 第25.2节确实指出、我们应该将输入设置为异步、并讨论如何设置上拉电阻... 但是数据线是 I/O、而 EM1DQM0-3是作为输出列出的? 那么、澄清是: 我怎么可能知道如何像在该样片中那样设置这些参数呢? 由于方向寄存器是输入或输出、而不是输入和输出、因此从这个角度来看、这有点令人困惑... 由于 EM1DQM0-3被列为输出、为什么要将它们设置为具有上拉和异步的输入? (引脚88-91)
层化3:
在示波器上、我现在看到 WI 脉冲低电平与 CAS 同时、它的宽度持续更长的时间...
查看同一文件如何为其特定部分设置计时寄存器(EMIF_32IT_SDRAM.c)...
//
//配置 SDRAM 控制寄存器
//
//需要根据 SDRAM 数据表进行编程。
//T_RFC = 60ns = 0x6
//T_RP = 18ns = 0x1
//T_RCD = 18ns = 0x1
//T_WR = 1CLK + 6ns = 0x1
//T_RAS = 42ns = 0x4
//T_RC = 60ns = 0x6
//T_RRD = 12ns = 0x1
根据我们讨论过的内容、我认为 T_RFC 应该设置为5或60ns/10ns 时钟= 6 -1 = 5、但在这里、他将其设置为6?
T_WR 为何要加上1clk? 该特定于本示例中使用的器件... 如果是、没关系、
重点是 T_RC 和 T_RFC 通过1个时钟以不同的方式进行设置、而我所理解的是... 计算这两者的正确方法是什么?
分层4:
设置了保护寄存器? 我假设由于 One 寄存器看起来像 Set once 功能、这里的想法是将这些设置锁定在器件中、这很可能是因为一旦分配了 SDRAM、您就不会希望它意外更改... 因此、我们不必对其进行设置、它只是可选的。
//
//为 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++;
}
层化5:
我看到 WI 脉冲在 CAS 收到读取请求后变为低电平... 时序图显示它保持高电平? 虽然这似乎不会引起任何问题、但问题更多是该器件为什么会在读取周期中生成低电平? 这是否与写入周期上的视在双宽度脉冲有关? 这是否与我看到的寄存器差异(T_RC 和 T_RFC)的设置相关、以便导致双宽度脉冲的任何因素也可能是我们在读取周期中看到第二个周期的原因?
谢谢。
尊敬的 Rob:
很高兴知道您已使其正常工作。
[引述]
分层1:
为什么设置引脚94? 在表7-8中、引脚94现在具有 EMIF 特定的功能... 实际上、在我们的电路板上、我们为 GPIO94... [/报价]
无需 GPIO94。 您可以将其用于所需的任何其他函数。
[引述]密化2:[/引述]
正如我在前面的一篇文章中提到的、GPIO 寄存器的输入选择与引脚是否用作 EMIF 无关。 因此该部件是冗余的。
[引述]密化3:[/引述]
由于该数字是60、 我们应该对值5或更高的值进行编程。 在这种情况下、我们已经对6进行了编程、这是可以的、 但即使是5也应该起作用。
[引述]
分层4:
设置了保护寄存器? 我假设由于 One 寄存器看起来像 Set once 功能、这里的想法是将这些设置锁定在器件中、这很可能是因为一旦分配了 SDRAM、您就不会希望它意外更改... 因此、我们不必对其进行设置、它只是可选的。 [/报价]
没错。 这是可选配置。
[引用]分层5:我看到 We 脉冲在 CAS 收到读取请求后变为低电平... 时序图显示它保持高电平? 虽然这似乎不会引起任何问题、但问题更多是该器件为什么会在读取周期中生成低电平? 这是否与写入周期上的视在双宽度脉冲有关? 这是否与我看到的寄存器差异(T_RC 和 T_RFC)的设置相关、以便导致双宽度脉冲的任何因素也可能是我们在读取周期中看到第二个周期的原因? [/报价]
我认为这是读取后的突发终止命令(写入也是如此)。 请注意,对于 SDRAM,最大突发量为1次访问(16位 SDRAM 设备的32位访问除外,其中将为2),因此每次访问后都将出现突发终止命令。
此致、
Vivek Singh