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.

[参考译文] TMS320F28388D:EMIF 获取意外数据。

Guru**** 2460850 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1495557/tms320f28388d-emif-getting-unexpected-data

器件型号:TMS320F28388D

工具/软件:

尊敬的专家:

我的客户在 F28388D 上使用 SDRAM IS42R86400F。 它们正在写入数据并读回以检查 SDRAM 是否正常运行。 但是、他们发现从1025kb 开始的读回数据不正确、如下图所示。

如果他们在表达式窗口中手动写入和读取、则读回的数据是正确的。 仅当它们通过循环写入和读取时才会发生错误。 是否知道此处的问题可能是什么?

以下是它们的设置:

CMD setting:

SDRAM           : origin = 0x80000000, length = 0x02000000  //512Mb, 8M*16bit*4banks

buffer defination

#pragma DATA_SECTION(".sdram_data");

__attribute__((far)) volatile uint32_t extSDRAMBuf[MEM_BUFFER_PAGE][MEM_BUFFER_SIZE];

mapfile:

SDRAM                 80000000   02000000  02000000  00000000  RWIX

和 syscfg 文件

emif11.$name                                    = "myEMIF10";
emif11.useCase                                  = "CUSTOM";
emif11.enableCS2                                = false;
emif11.enableCS3                                = false;
emif11.enableCS4                                = false;
emif11.cs0Narrow                                = "EMIF_SYNC_NARROW_MODE_TRUE";
emif11.useInterfacePins                         = ["EMIF1_A0","EMIF1_A1","EMIF1_A10","EMIF1_A11","EMIF1_A12","EMIF1_A2","EMIF1_A3","EMIF1_A4","EMIF1_A5","EMIF1_A6","EMIF1_A7","EMIF1_A8","EMIF1_A9","EMIF1_BA0","EMIF1_BA1","EMIF1_CAS","EMIF1_CLK","EMIF1_CS0n","EMIF1_D0","EMIF1_D1","EMIF1_D10","EMIF1_D11","EMIF1_D12","EMIF1_D13","EMIF1_D14","EMIF1_D15","EMIF1_D2","EMIF1_D3","EMIF1_D4","EMIF1_D5","EMIF1_D6","EMIF1_D7","EMIF1_D8","EMIF1_D9","EMIF1_DQM0","EMIF1_DQM1","EMIF1_RAS","EMIF1_SDCKE","EMIF1_WEn"];
emif11.cs0CAWidth                               = "EMIF_SYNC_COLUMN_WIDTH_10";
emif11.cs0AddrMSB                               = "EM1A12";
emif11.selController                            = "EMIF_CONTROLLER_CPU1_G";
emif11.enableSyncSelfrefresh                    = true;
emif11.cs0Refresh                               = 750;
emif11.cs0tRFC                                  = 6;
emif11.cs0tRP                                   = 2;
emif11.cs0tRAS                                  = 5;
emif11.cs0tWR                                   = 2;
emif11.cs0tRRD                                  = 2;
emif11.emif1.$assign                            = "EMIF1";
emif11.emif1.emif1_cs0nPin.$assign              = "GPIO32";
emif11.emif1.emif1_sdckePin.$assign             = "GPIO29";
emif11.emif1.emif1_clkPin.$assign               = "GPIO30";
emif11.emif1.emif1_wenPin.$assign               = "GPIO31";
emif11.emif1.emif1_casPin.$assign               = "GPIO86";
emif11.emif1.emif1_rasPin.$assign               = "GPIO87";
emif11.emif1.emif1_dqm0Pin.$assign              = "GPIO88";
emif11.emif1.emif1_dqm1Pin.$assign              = "GPIO89";
emif11.emif1.emif1_ba0Pin.$assign               = "GPIO33";
emif11.emif1.emif1_ba1Pin.$assign               = "GPIO34";
emif11.emif1.emif1_a0Pin.$assign                = "GPIO35";
emif11.emif1.emif1_a1Pin.$assign                = "GPIO39";
emif11.emif1.emif1_a2Pin.$assign                = "GPIO40";
emif11.emif1.emif1_a3Pin.$assign                = "GPIO38";
emif11.emif1.emif1_a4Pin.$assign                = "GPIO44";
emif11.emif1.emif1_a5Pin.$assign                = "GPIO45";
emif11.emif1.emif1_a6Pin.$assign                = "GPIO46";
emif11.emif1.emif1_a7Pin.$assign                = "GPIO47";
emif11.emif1.emif1_a8Pin.$assign                = "GPIO48";
emif11.emif1.emif1_a9Pin.$assign                = "GPIO49";
emif11.emif1.emif1_a10Pin.$assign               = "GPIO50";
emif11.emif1.emif1_a11Pin.$assign               = "GPIO51";
emif11.emif1.emif1_a12Pin.$assign               = "GPIO52";
emif11.emif1.emif1_d0Pin.$assign                = "GPIO85";
emif11.emif1.emif1_d1Pin.$assign                = "GPIO83";
emif11.emif1.emif1_d2Pin.$assign                = "GPIO82";
emif11.emif1.emif1_d3Pin.$assign                = "GPIO81";
emif11.emif1.emif1_d4Pin.$assign                = "GPIO80";
emif11.emif1.emif1_d5Pin.$assign                = "GPIO79";
emif11.emif1.emif1_d6Pin.$assign                = "GPIO78";
emif11.emif1.emif1_d7Pin.$assign                = "GPIO77";
emif11.emif1.emif1_d8Pin.$assign                = "GPIO76";
emif11.emif1.emif1_d9Pin.$assign                = "GPIO75";
emif11.emif1.emif1_d10Pin.$assign               = "GPIO74";
emif11.emif1.emif1_d11Pin.$assign               = "GPIO73";
emif11.emif1.emif1_d12Pin.$assignAllowConflicts = "GPIO72";
emif11.emif1.emif1_d13Pin.$assign               = "GPIO71";
emif11.emif1.emif1_d14Pin.$assign               = "GPIO70";
emif11.emif1.emif1_d15Pin.$assign               = "GPIO69";
emif11.ba0Qual.padConfig                        = "PULLUP";
emif11.ba1Qual.padConfig                        = "PULLUP";
emif11.d0Qual.padConfig                         = "PULLUP";
emif11.d1Qual.padConfig                         = "PULLUP";
emif11.d10Qual.padConfig                        = "PULLUP";
emif11.d11Qual.padConfig                        = "PULLUP";
emif11.d12Qual.padConfig                        = "PULLUP";
emif11.d13Qual.padConfig                        = "PULLUP";
emif11.d14Qual.padConfig                        = "PULLUP";
emif11.d15Qual.padConfig                        = "PULLUP";
emif11.d2Qual.padConfig                         = "PULLUP";
emif11.d3Qual.padConfig                         = "PULLUP";
emif11.d4Qual.padConfig                         = "PULLUP";
emif11.d5Qual.padConfig                         = "PULLUP";
emif11.d6Qual.padConfig                         = "PULLUP";
emif11.d7Qual.padConfig                         = "PULLUP";
emif11.d8Qual.padConfig                         = "PULLUP";
emif11.d9Qual.padConfig                         = "PULLUP";
emif11.dqm0Qual.padConfig                       = "PULLUP";
emif11.dqm1Qual.padConfig                       = "PULLUP";

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Hang、

    这看起来像是时序问题。 您是否使用 SDRAM 存储器数据表中的数据正确地对 SDTIMER 寄存器进行编程?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 QJ:

    我是遇到此问题的客户。

    您意味着 SD 计时器寄存器低于 reg? 我们根据数据表对它们进行了配置。


    emif11.enableSyncSelfrefresh                    = true;
    emif11.cs0Refresh                               = 750;
    emif11.cs0tRFC                                  = 6;
    emif11.cs0tRP                                   = 2;
    emif11.cs0tRAS                                  = 5;
    emif11.cs0tWR                                   = 2;
    emif11.cs0tRRD                                  = 2;


    BTW、测试代码为:

    uint16_t readWriteSyncMemory(uint32_t memSize)
    {
        uint32_t memWdl;
        
        //
        // Fill far memory buffer with data.
        //
        
        for(i=0; i < 0x400; i++)
        {
            for(j=0; j < Seg_Len; j++)
            {
                memWdl = 0x0;
                for(k=0; k < memSize; k++)
                {
                    extSDRAMBuf[i<<5+j][k] = memWdl;
                    memWdl += 0x00050001;
                }
            }
            vTaskDelay(1);
        }
    
        //
        // Read far memory buffer into local buffer and verify data.
        //
        for (i = 0; i < 0x400; i++)
        {
            for (j = 0; j < Seg_Len; j++)
            {
                memWdl = 0x0;
                for (k = 0; k < memSize; k++)
                {
                    localRAMBuf[k] = extSDRAMBuf[i<<5+j][k];
    
                    //
                    // Return error if read data is incorrect.
                    //
                    if (localRAMBuf[k] != memWdl)
                    {
                        return (k?k:1);
                    }
                    memWdl += 0x00050001;
                }
            }
            vTaskDelay(1);
        }
        return(0);
    }

    我们先将它放在 freeRTOS 任务中(;;)、代码是指 TI 的示例 SDRAM 程序。

    此问题对我们至关重要、期待尽快获得反馈、谢谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    e2e.ti.com/.../C1348819_5F000C54656BA85201608F963A67585BD6538551585B2800_SDRAM_29005F00_IS42S16320F_2D00_7TLI_5F00C4893C68664E5F00_WJ11347.PDF

    请查找 SDRAM 数据表。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    顺便说一下、在此之前、我们还尝试通过将时间寄存器增加1或2来修改时间寄存器、但测试结果是相同的。 数据损坏似乎始终是从1025Kb 开始的同一地址。 我们添加一个离线 SDRAM 数据单个16位读取/写入命令、测试结果适用于这些空间。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    即使数据损坏、SDRAM 测试也会在测试代码中通过、表示 返回中没有条目(k?k:1);最后返回0、因此我不确定是由内存复制还是堆栈损坏引起的问题。

    我将选中"写入具有相同常量数据值的所有 SDRAM 空间"以解决该问题。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Dongdong:

    如何使用时序参数试用 SDK EMIF_ex3_16bit_SRAM_FAR 示例?  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
        
            //
            // Configure SDRAM control registers
            //
            // Need to be programmed based on SDRAM Data-Sheet.
            //T_RFC = 60ns = 0x6
            //T_RP  = 18ns = 0x1
            //T_RCD = 18ns = 0x1
            //T_WR  = 1CLK + 6 ns = 0x1
            //T_RAS = 42ns = 0x4
            //T_RC  = 60ns = 0x6
            //T_RRD = 12ns = 0x1
            //
            Emif1Regs.SDRAM_TR.all = 0x31114610;
    
            //
            //Txsr = 70ns = 0x7
            //
            Emif1Regs.SDR_EXT_TMNG.all = 0x7;
    已尝试此示例时间设置、结果相同、失败。
    还尝试复制相同的常量数据、 相同的结果、失败。
    目前我们没有使用 memcpy_fast_far (),而只是直接复制数据,不确定它是否会对这种情况产生影响。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    当我们更改下面的代码(第10行到第11行、写入指针内容而不是数据数组内容、实际上是相同的地址)时、测试正常。 所有数据写入和读取 都是正确的。
        volatile uint32_t memWdl;
        volatile uint32_t *pmemWdl = extSDRAMBuf[0];
    
        //
        // Fill far memory buffer with data.
    	@@ -124,16 +125,18 @@ uint16_t readWriteSyncMemory(uint32_t memSize)
                memWdl = 0x0;
                for(k=0; k < memSize; k++)
                {
                    // extSDRAMBuf[i<<5+j][k] = memWdl;
                    *pmemWdl++ = memWdl;
                    memWdl += 0x00050001;
                }
            }
            vTaskDelay(1);
        }
    我们定义的数据缓冲区非常大(涵盖所有 SDRAM 空间)、我们不知道这为什么会导致问题、请帮助澄清。
    //
    // Buffer in far memory.
    //
    #pragma DATA_SECTION(".sdram_data");
    __attribute__((far)) volatile uint32_t extSDRAMBuf[MEM_BUFFER_PAGE][MEM_BUFFER_SIZE];
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、  

    F2837x 器件上的 EMIF1的 SDRAM 地址为0x80000000、高于22位地址(far 存储器)。  应使用属性___attribute__((far))来声明 far 数据对象。 此属性使编译器能够使用32位地址。

    请参阅随附的应用手册:

    使用 C/C++访问 TMS320F2837x/2807x 微控制器上的外部 SDRAM

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我们定义的数据缓冲区非常大(涵盖所有 SDRAM 空间)、我们不知道为什么这会导致麻烦、请帮助澄清。

    数组大小可能超过 SDRAM 存储器的上限。 代码中"i"的最大值为0x400 < 5 = 0x8000、如果 MEM_BUFFER_SIZE=0x500 (示例中使用)、数组大小为0x8000*0x500 = 0x280.0000、这大于 存储器大小(在 cmd 文件中定义的0x20.0000)。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    //total SDRAM size is 8M * 16bit * 4 banks
    #define MEM_BUFFER_SIZE 0x200  //1K words
    #define MEM_BUFFER_PAGE (uint16_t)(0x400 * 8 * 4) //8K * 4 banks

     extSDRAMBuf 总大小为0x8000*0x200 = 0x100 0000、每个单元为32位、因此它是0x200 0000个字、与.cmd 中定义的相同。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Dongdong:

    请仔细检查您的代码:

    对于(I=0;I < 0x 400 ; I++)

    对于(j=0;j < Seg_Len; J++)

         memWdl = 0x0;
         对于(k=0;k < memsize ;k++)
         {
             extSDRAMBuf[ i<<5+j][k ]= memWdl;
             memWdl += 0x00050001;
          }
    }

    }

    如果 i=0x400、j=1、amd memSize=0x200 (MEM_BUFFER_SIZE)、则地址位于(0x400 << 5 + 2)* 0x200 * 4 (字节)= 0x8002*0x200 *4= 0x400_1000 (字节)

    0R 0x200_0800 16位字

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 QJ:

    `i`不会变为0x400、只有0x3FF、Seg_Len max 为0x20、因此 j max 为0x1F、在您的公式中、地址为 (0x3FF << 5 + 0x1F)* 0x200 * 2 (字)= 0x1FF 0C00、处于有效范围内。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Dongdong:

    我想您已经使用指针而不是数组解决了问题、对吧?  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Yang:

    已就我的测试向您发送 Webex 消息。

    我使用 AS4C4M16SA SDRAM (4Mx16位)进行了测试。 写入和回读整个内存工作正常。 附件是我修改后的代码。 列地址根据 SDRAM 数据表进行更新:

    e2e.ti.com/.../8080.emif_5F00_ex3_5F00_16bit_5F00_sdram_5F00_far.c

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是的、我们解决了此问题。

    该问题由操作员优先级引起 、当更改为i<<5+j(i<<5)+j解决此问题时、 测试正常。

    因为+优先级高于<<

    无论如何都要感谢!  

    此主题可以关闭。