TMS320C6455的EMIF外部存储器接口

DSP6455的EMIFA模块

前言:

     C6455的EMIFA可以访问多种外部存储器,比如:SRAM,ROM,FLASH等等。当然,也包括FPGA。本文的重点就是介绍使用EMIFA接口与FPGA建立无缝连接以及和FLASH的连接。


1.EMIF接口信号图

TMS320C6455的EMIF外部存储器接口_第1张图片

部分管脚说明:

•AED[63:0]        64位数据总线
•AEA[19:0]        20位地址总线(Optional)
•ACE2               片选信号(低有效)
•ACE3               片选信号(低有效)
•AECLKOUT     时钟信号
•ASWE              写使能(低有效)
•ASRE               读使能(低有效)


2.EMIF片选信号及映射情况

TMS320C6455的EMIF外部存储器接口_第2张图片

TMS320C6455的EMIF外部存储器接口_第3张图片

从图中可以看出:

•EMIFA共支持4个外部存储器,例如把CE2分配给FPGA,CE3分配给FLASH。
•每个外部存储器的寻址空间大小是8MB。FPGA20根地址线即2的20次方,也就是1MB,此外由于数据总线是64位的,故对应的寻址空间是8MB(但是在这里FLASH我们配置的是8位内存位宽,所以此处是4M寻址空间)


在读取FPGA内部RAM数据时告诉EDMA要读取的数据的基地址是0xA0000000,以及读取的数据的长度即可。
在读取FLASH数据时告诉EDMA要读取的数据的基地址是0xB0000000,以及读取的数据的长度即可。


3.EMIF与 FPGA和FLASH连接原理图

EMIF:

FPGA:

FLASH:


4.配置EMIFA的寄存器

        主要配置寄存器是CEnCFG。该寄存器有两套完全不同的配置,分别对应于同步存储器模式和异步存储器模式。由于FPGA内部RAM工作于同步模式,故我们来看一下同步模式下该寄存器的配置。FLASH则是采用异步模式。


    (1)异步模式的外部存储器(高亮部分)FLASH配置

TMS320C6455的EMIF外部存储器接口_第4张图片

TMS320C6455的EMIF外部存储器接口_第5张图片


    (2)同步模式的外部存储器(高亮部分)FPGA配置

TMS320C6455的EMIF外部存储器接口_第6张图片

TMS320C6455的EMIF外部存储器接口_第7张图片



5.代码编写

        配置EMIFA模块时,主要的步骤如下:

(1) 使能设备EMIFA模块
(2) 配置CEnCFG寄存器
(3) 初始化EMIFA模块


#define EMIFA_BASE_ADDR (0x70000000)

#define EMIFA_MIDR     (*(int*)(EMIFA_BASE_ADDR + 0x00000000))
#define EMIFA_STAT     (*(int*)(EMIFA_BASE_ADDR + 0x00000004))
#define EMIFA_BPRIO    (*(int*)(EMIFA_BASE_ADDR + 0x00000020))
#define EMIFA_CE2CFG   (*(int*)(EMIFA_BASE_ADDR + 0x00000080))
#define EMIFA_CE3CFG   (*(int*)(EMIFA_BASE_ADDR + 0x00000084))
#define EMIFA_CE4CFG   (*(int*)(EMIFA_BASE_ADDR + 0x00000088))
#define EMIFA_CE5CFG   (*(int*)(EMIFA_BASE_ADDR + 0x0000008C))
#define EMIFA_AWCC     (*(int*)(EMIFA_BASE_ADDR + 0x000000A0))

void init_emif(void)
{
	/* Enable the async EMIF and the DDR2 Memory Controller */
	*(int *)(0x02AC002C) = 0x00000003;  // PERCFG1 = 0x02AC002C

	/* Configure async EMIF */
	//EMIFA_CE2CFG = 0x80240122; /* 32-bit sync, 10 cycle read/write strobe   for fpga A0000000 - A07FFFFF */
	EMIFA_CE2CFG = 0x8000000A; /* 32-bit sync, write latency 0 read latency 2  */
	EMIFA_CE3CFG = 0x00240120; /* 8-bit async, 10 cycle read/write strobe  for norflash */

	//EMIFA_CE4CFG = 0x00240122; /* 32-bit async, 10 cycle read/write strobe for fpga*/
	
	//EMIFA_CE4CFG = 0x00240121; /* 16-bit Async,  read/write strobe for fpga*/
   	//EMIFA_CE5CFG = 0x80240122; /* 32-bit async, 10 cycle read/write strobe */

	EMIFA_BPRIO  = 0x000000FE; /* Enable priority based starvation control SPRU971A sec. 7.2 */
	EMIFA_AWCC   = 0x000002FF; //TA 2 clock,
}

代码说明:

TMS320C6455的EMIF外部存储器接口_第8张图片

TMS320C6455的EMIF外部存储器接口_第9张图片

FPGA:

#define EMIF_FPGA_BASE_ADDR    0xA0000000

void WriteFpga(Uint32 addr,Uint32 data)
{


	*((Uint32*) (EMIF_FPGA_BASE_ADDR + addr))  = data;

}

Uint32 ReadFpga(Uint32 addr)
{

	Uint32 reData = 0;

	reData = *((Uint32*) (EMIF_FPGA_BASE_ADDR + addr));
	return reData;

}

Uint32 emif_test(Uint32 addr, Uint8 *data, Uint32 len)
{
	int num;
	Uint32 readData;
	Uint32 startData = 0x11111111;
	Uint32 writeData;

	for(num = 0; num < 256 / 4; num++)
	{
		writeData = startData + num;
		WriteFpga(num * 4, writeData);
		readData =ReadFpga(num * 4);
		if(readData != writeData)
		{
			printf("write = %X read = %X\n", writeData, readData);
		}
	}
	printf("emif test OK! \n");

	return 0;
}


FLASH:

#define FLASH_BASE                   0xB0000000
#define FLASH_RESET                         0xF0
#define FLASH_CMD_AA                        0xAA
#define FLASH_CMD_55                        0x55
#define FLASH_PROGRAM                       0xA0
#define FLASH_PROGRAM_BUFFER                0x29
#define FLASH_ERASE                         0x80
#define FLASH_ERASE_CHIP                    0x10
#define FLASH_ERASE_SECTOR                  0x30
#define FLASH_ERASE_SUSPEND                 0xB0
#define FLASH_ERASE_RESUME                  0x10


int norflash_erase( Uint32 start, Uint32 length )
{
    Uint16 i;
    Uint8 *pdata;
    Uint32 sector_base,end;

	

    end = start + length - 1;                   // Calculate end of rang

  /* Walk through each sector, erase any sectors within range */
    sector_base = FLASH_BASE;
    for (i = 0; i < FLASH_SECTORS; i++)
    {
        if ( ( ( sector_base >= start ) || ( sector_end[i] >= start ) ) &&
             ( ( sector_base <= end )   || ( sector_end[i] <= end ) ) )
        {
            /* Start sector erase sequence */
            FLASH_CTL555 = FLASH_CMD_AA;
            FLASH_CTL2AA = FLASH_CMD_55 ;
            FLASH_CTL555 = FLASH_ERASE;
            FLASH_CTL555 = FLASH_CMD_AA;
            FLASH_CTL2AA = FLASH_CMD_55 ;

            /* Start erase at sector address */
            pdata = (Uint8 *)sector_base;
            *pdata = FLASH_ERASE_SECTOR;

            /* Wait for erase to complete */
            while (1)
                if (*pdata & 0x80)
                    break;

            /* Put back in read mode */
            *((Uint8 *)FLASH_BASE) = FLASH_RESET;
        }

        /* Advance to next sector */
        sector_base = sector_end[i] + 1;
    }
    *((Uint8 *)FLASH_BASE) = FLASH_RESET;
    return 0;
}

int norflash_write( Uint8* src, Uint32 dst, Uint32 length )
{
    Uint32 i;
    Uint8* psrc8;
    Uint8* pdst8;
    volatile Uint8* addr8  = ( Uint8* )FLASH_BASE;
    /*
     *  Align to 8 or 8 bits
     */
    psrc8 = ( Uint8* )src;
    pdst8 = ( Uint8* )dst;

     for ( i = 0 ; i < length ; i ++ )
     {
         /* Program one 8-bit word */
         FLASH_CTL555 = FLASH_CMD_AA;
         FLASH_CTL2AA = FLASH_CMD_55;
         FLASH_CTL555 = FLASH_PROGRAM;
         *pdst8 = *psrc8;

         /* Wait for programming to complete */
         // Wait for operation to complete
         while(1)
             if (*pdst8 == *psrc8)
                 break;
         pdst8++;
         psrc8++;
     }
     
    *addr8 = FLASH_RESET;
    return 0;
}

int norflash_read( Uint32 src, Uint8* dst, Uint32 length )
{
    Uint32 i;
    Uint8* psrc8 = ( Uint8* )src;
    Uint8* pdst8 = ( Uint8* )dst;

    /*
     *  Set to Read Mode
     */
    FLASH_BASE_PTR8 = FLASH_RESET;

    /*
     *  Read Data to Buffer
     */
    for ( i = 0 ; i < length ; i ++ )
        *pdst8++ = *psrc8++;

    return 0;
}

int norflash_test(Uint32 dstAddr, Uint32 length, Uint8 start)
{
	int retVal;
    Uint32 num;
	Uint32 wLen;
    Uint8 data;
    Uint8 *testData = NULL;
	
	testData = (Uint8*)malloc(1024);
	if(testData == NULL)
	{
		printf("malloc is error!\n");
		return -1;
	}

	for(num = 0; num < 1024; num++)
	{
		testData[num] = start + num;
	}

	norflash_erase(dstAddr, length);

	while(length > 0)
	{
		wLen = length > 1024 ? 1024 : length;
		length -= wLen;
		retVal = norflash_write(testData, dstAddr, wLen);
		if(retVal != 0)
		{
			printf("nor flash write is error!\n");
			return -1;
		}

		memset(testData, 0, wLen);

		retVal = norflash_read(dstAddr, testData, wLen);
		if(retVal != 0)
		{
			printf("nor flash write is error!\n");
			return -1;
		}

		
		for(num = 0; num < wLen; num++)
		{
			data = start + num;
			if(testData[num] != data)
			{
				printf("nor flash test is error!\n");
				return -1;
			}
		}

		dstAddr += wLen;
	}
	

	printf("nor flash test is ok!\n");
	return 0;
	
}



FLASH代码说明:

        参看:http://blog.csdn.net/mdqaq/article/details/53606900

 
  












你可能感兴趣的:(TMS320C6455的EMIF外部存储器接口)