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.

使用EMIF对FPGA地址进行访问,存在以下问题

Other Parts Discussed in Thread: HALCOGEN

问题1,调用HALCoGen中自动生成的emif_SDRAMInit函数,无法实现数据写入。当将该函数中的内容替换为在论坛中找到的一个资料中的初始化函数后,就可以写入,所以问题可能是由初始化引起的。

问题2,同样使用HALCoGen生成的代码emif_ASYNC1Init,想对异步外设进行访问。但是针对地址0x60004000(ASYNC1对应的地址为0x60000000-0x63fffff)的写入无法从IAR对应的地址中看到。

部分程序如下:

#define  DIGITAL_BOARD_ADDR        0x60004000

/*向该地址写数据,在IAR下无法看到,但是可以通过读数据将其获取查看(如temp所示)*/
for(int i = 0;i<8;i++)
{
(*((uint16 *)(DIGITAL_BOARD_ADDR+i))) = i;//向地址段中写入数据
temp = (*((uint16 *)(DIGITAL_BOARD_ADDR+i)));//将其读出
}

现在问题是:我通过temp可以观测到数据的实时变化(0到7),但是在相应的地址空间中却无法看到。初步怀疑是emif_ASYNC1Init设置不对。


求解答,谢谢

  • 你好。

    问题1:你有比较过Halcogen生成的函数与你在论坛中找到的函数有什么差别吗?如果方便,请把它们贴上来。

    问题2:你用Async1操作的Flash还是SRAM。感觉Flash的写入没有那么简单。怀疑实际并没有写入Flash中。建议把代码改为以下的进行测试。

    for(int i = 0;i<8;i++)
    {
    (*((uint16 *)(DIGITAL_BOARD_ADDR+i))) = i;//向地址段中写入数据
    }

    for(int i = 0;i<8;i++)
    {
    temp = (*((uint16 *)(DIGITAL_BOARD_ADDR+i)));//将其读出
    }

  • 论坛代码:

      /* USER CODE BEGIN (2) */
      /* USER CODE END */
      /* SDRAM Initialization*/
      unsigned int i;
      unsigned int refresh_rate;
      refresh_rate = 80*64000/4096;
      /*
      EMIF_SDCR = 0x20011100;      // 31st is Self Refresh bit
      EMIF_SDCR = 0xA0391720;      // 31st is Self Refresh bit
      EMIF_SDCR = 0x20000000;    // power enabled
      EMIF_SDCR &= 0xFFFEEEFF;
      EMIF_SDTIMR = 0x19112308;
      EMIF_SDRCR = refresh_rate; // Refresh rate = ( freq * 64ms / 4096 )
      */
      /* EMIF Pin Mux */
      muxInit();
      emifREG->SDCR   |= 1U <<31U ;
      emifREG->SDTIMR   = 0x31113510;
      /*  | ( 7 << 25 )           // tRTC [66 ns]
      | ( 2 << 22 )           // tRP  [20 ns]
      | ( 2 << 19 )           // tRCD [20 ns]
      | ( 1 << 16 )           // tWR  [15 ns]
      | ( 4 << 11 )           // tRAS [44 ns]
      | ( 7 <<  6 )           // tRC  [66 ns]
      | ( 1 <<  3 )           // tRRD [15 ns]
      | ( 1 <<  0 );          // tWTR [15 ns] */
      
      emifREG->SDSRETR  = 0x00000006;
      emifREG->SDRCR = 0x4E2; /*78 MHz*/
      emifREG->SDCR   = 0x4720;
      /*  | ( 0 << 31 )           // self refresh
      | ( 0 << 30 )           // power down
      | ( 0 << 29 )           // perform refreshes during pwdn
      | ( 0 << 23 )           // partial array self refresh: 0 is for 4 baks          [3]
      | ( 0 << 20 )           // row size, 3 is for 12 rows
      | ( 0 << 19 )           // ibank position
      | ( 0 << 17 )           // SDRAM drive strength
      | ( 0 << 16 )           // bit[25:17] lock, can be written only when this bit is set to 1
      | ( 0 << 14 )           // narrow mode
      | ( 0 << 13 )           // disable DDR DLL
      | ( 0 << 12 )           // bit[13] lock
      | ( 0 << 9 )            // CAS latency
      | ( 0 << 8 )            // bit[11:9] lock
      | ( 0 << 4 )            // ibank, 2 is for 4 banks
      | ( 0 << 3 )            // ebank, 0 is for CS0
      | ( 0 << 0 );            // page size, 0 for 256-word  */
      
      i = *(int*) 0x80000000;
      
      emifREG->SDRCR  = 0x5FF; //refresh_rate; // Refresh rate = ( freq * 64ms / 4096 )	
      
      /* USER CODE BEGIN (3) */
      /* USER CODE END */

    HALCoGen代码:

       uint32 buffer;
    
       emifREG->SDTIMR  = (uint32)((uint32)0U << 27U)|
                          (uint32)((uint32)0U << 24U)|
                          (uint32)((uint32)0U << 23U)|
                          (uint32)((uint32)0U << 20U)|
                          (uint32)((uint32)0U << 19U)|
                          (uint32)((uint32)0U << 16U)|
                          (uint32)((uint32)0U << 12U)|
                          (uint32)((uint32)0U << 8U)|
                          (uint32)((uint32)0U << 7U)|
                          (uint32)((uint32)0U << 4U)|
                          (uint32)((uint32)0U << 3U);
    
     /* configure refresh rate*/
       emifREG->SDSRETR = (uint32)0U;  
       emifREG->SDRCR   = 2000U;	
    
    /**  -general clearing of register
    *    -for NM for setting 16 bit data bus
    *    -cas latency
    *    -BIT11_9CLOCK to allow the cl field to be written
    *    -selecting the banks
    *    -setting the pagesize
    */   
        emifREG->SDCR   = (uint32)((uint32)0U << 31U)|                               	
                          (uint32)((uint32)1U << 14U)|                               	
                          (uint32)((uint32)0U << 9U)|  	
                          (uint32)((uint32)1U << 8U)|                                	
                          (uint32)((uint32)0U << 4U)|              	
                          (uint32)((uint32)elements_256);         	
    /* wait for a read to happen*/
       buffer           = *PTR;                                	
       buffer           = buffer;
       emifREG->SDRCR   = 0U;	
    
    /* USER CODE BEGIN (3) */
    /* USER CODE END */

    谢谢你的回复

  • 你好,

    从代码看起来,论坛上的代码多了muxInit,引脚复用的实始化。如果用Halcogen生成的代码,在EMIF初始化之前,你有初始化引脚复位吗?

  • 我在初始化之前加了,会不会是里面一些速率设置的问题呢

  • 有可能。

    你可以测一下不同程序下EMIF的引脚信号(如时钟),对比一下EMIF的相关寄存器值。