📄 emi.c
字号:
#include "ub4020evb.h"
#include "intc.h"
#include "emitest.h"
#define TWOK_PAGE
//==========================================
//==========reset value check===============
U32 RESET_CHECK(void)
{
U32 flag=0;
//for boot,the actual value;
if(*(RP)EMI_CSACONF != 0x089e9ea1 ) flag=1;
if(*(RP)EMI_CSBCONF != 0x09656559 ) flag=1;
if(*(RP)EMI_CSCCONF != 0x0A656551 ) flag=1;
if(*(RP)EMI_CSDCONF != 0x0B656551 ) flag=1;
if(*(RP)EMI_CSECONF != 0x8c000001 ) flag=1;
if(*(RP)EMI_CSFCONF != 0x8d000001 ) flag=1;
if(*(RP)EMI_SDCONF1 != 0x0d105126 ) flag=1;
// if(*(RP)EMIADDR_SDCONF2 != 0x00001860 ) flag=1; //????????the reset value was 0x80001860 for short,and then will be 0x00001860
if(*(RP)EMI_REMAPCONF != 0x00000003 ) flag=1;
if(*(RP)EMI_NAND_ADDR1 != 0x00000000 ) flag=1;
if(*(RP)EMI_NAND_COM != 0x00000000 ) flag=1;
if(*(RP)EMI_NAND_STA != 0x00000000 ) flag=1;
//
if(*(RP)EMI_ERR_ADDR1 != 0x00000000 ) flag=1;
if(*(RP)EMI_ERR_ADDR2 != 0x00000000 ) flag=1;
if(*(RP)EMI_NAND_CONF1 != 0x06202857 ) flag=1;
if(*(RP)EMI_NAND_INTR != 0x00000000 ) flag=1;
if(*(RP)EMI_NAND_ECC != 0x00000000 ) flag=1;
if(*(RP)EMI_NAND_IDLE != 0x00000001 ) flag=1;
if(*(RP)EMI_NAND_CONF2 != 0x00114353 ) flag=1;
if(*(RP)EMI_NAND_ADDR2 != 0x00000000 ) flag=1;
if(*(RP)EMI_NAND_DATA != 0x00000000 ) flag=1;
return(flag);
}
//==========================================
//==========initial EMI=====================
void INI_EMI(void)
{
// *(RP)EMIADDR_CSACONF = 0x0da6a6a1 ;//CSACONF has been initialled in boot
// *(RP)EMI_CSDCONF = 0x8ba6a6a1 ;
#ifdef TWOK_PAGE //2K/page, 4 bytes address
*(RP)EMI_NAND_CONF1 = 0x06302857 ; //4 address
//Trr 10 cycles
//Tclh 2 cycles
//Talh 2 cycles
//Twh 3 cycles
//Read_width 10 cycles
//Writ_width 10 cycles
*(RP)EMI_NAND_CONF2 = 0x00914353;
#endif
}
//===========================================
//==========basic data transfer==============
//transfer the data in src_addr to dest_addr
#define SINGLE_TIMES 20
U32 BASIC_DATA_TRAN(U32 src_addr,U32 dest_addr)
{
U32 i;
U32 flag;
U32 addr=0;
U8 tmp8;
U16 tmp16;
U32 tmp32;
//to transfer with CPU, 8bit, single
for(i=1;i<=SINGLE_TIMES;i++)
{
tmp8=*(RP8)(src_addr+addr);
*(RP8)(dest_addr+addr)=tmp8;
addr++;
}
//to transfer with CPU, 16bit, single
for(i=1;i<=SINGLE_TIMES;i++)
{
tmp16=*(RP16)(src_addr+addr);
*(RP16)(dest_addr+addr)=tmp16;
addr=addr+2;
}
//to transfer with CPU, 16bit, single
for(i=1;i<=SINGLE_TIMES;i++)
{
tmp32=*(RP)(src_addr+addr);
*(RP)(dest_addr+addr)=tmp32;
addr=addr+4;
}
//to transfer with DMA, 4burst*16bit->8burst*8bit,total 4*2byte*4
//DMA_TRAN(src_addr,dest_addr,src_burst,src_size,dest_burst,dest_size,total_size) )
// DMA_TRAN(src_addr+addr,dest_addr+addr,4,16,8,8,4);
DMA_TRAN_ADDR(dest_addr+addr,src_addr+addr);
DMA_TRAN_CON(4,16,8,16);
addr=addr+32;
//to transfer with DMA, 16burst*8bit->4burst*32bit,total 16*1byte*2
DMA_TRAN_ADDR(dest_addr+addr,src_addr+addr);
DMA_TRAN_CON(16,8,4,32);
addr=addr+32;
//to transfer with DMA, 8burst*32bit->16burst*16bit,total 8*4byte*2
DMA_TRAN_ADDR(dest_addr+addr,src_addr+addr);
DMA_TRAN_CON(8,32,16,16);
addr=addr+64;
addr=addr>>2;
flag=COMPARE_MEM(src_addr,dest_addr,addr);
return(flag);
}
//sub function to set dma registers
void DMA_TRAN_ADDR(U32 dest_addr,U32 src_addr)
{
*(RP)DMAC_C0SRCADDR = src_addr ;
*(RP)DMAC_C0DESTADD = dest_addr;
}
void DMA_TRAN_CON(U32 src_burst,U32 src_size,U32 dest_burst,U32 total_size)
{
U32 tmp=0;
U32 dest_size;
tmp=total_size<<14 ;
tmp=tmp|0x00003000 ;//set SI and DI =1
dest_size=(src_burst*src_size)/dest_burst;
switch(dest_size)
{
case 8 : dest_size=0;break;
case 16: dest_size=1;break;
case 32: dest_size=2;break;
}
tmp=tmp|(dest_size<<9);
switch(src_size)
{
case 8 : src_size=0;break;
case 16: src_size=1;break;
case 32: src_size=2;break;
}
tmp=tmp|(src_size<<6);
switch(dest_burst)
{
case 4 : dest_burst=3;break;
case 8 : dest_burst=5;break;
case 16: dest_burst=7;break;
}
tmp=tmp|(dest_burst<<3);
switch(src_burst)
{
case 4 : src_burst=3;break;
case 8 : src_burst=5;break;
case 16: src_burst=7;break;
}
tmp=tmp|src_burst;
*(RP)DMAC_C0CONTROL = tmp;
*(RP)DMAC_C0CONFIGURATION = 1;//enable the channel
return;
}
//compare the data in src_addr with the data in dest_addr for the
//length, return 0 if all are identical, return 1 if one or more
//data are different.
U32 COMPARE_MEM(U32 src_addr, U32 dest_addr,U32 length)//length with the unit of word
{
U32 i;
U32 flag=E_OK;
U32 a,b;
for(i=0;i<length;i++)
{
// a=*(RP)(src_addr+(i<<2)) ;
// b=*(RP)(dest_addr+(i<<2)) ;
// if(a!=b )
if(*(RP)(src_addr+(i<<2))!=*(RP)(dest_addr+(i<<2)))
{
flag=E_HA;
break;
}
}
return flag;
}
//=======================================
//=======NAND FLASH BASIC OPERATION======
U32 NAND_WRITE(U32 src_addr,U32 nand_page)
{
U32 i,j,NTM = 0x0;
//added for test nand basic transfer in nand booting condition
/* *(RP)DMAC_INTTCCLEAR=0x1;
while((*(RP)DMAC_INTERRORSTATUS)&0x1==0x1)
{
for(j = 0x0; j < 0xa; j++);
}
*(RP)DMAC_INTTCCLEAR=0x0;*/
//end of add
#ifdef TWOK_PAGE
*(RP)EMI_NAND_ADDR1 = (U32)(nand_page<<16);
*(RP)DMAC_C0CONTROL = 0x0084149B ; //word-word burst=4 size=512words+16words
#else
*(RP)EMI_NAND_ADDR1 = (U32)(nand_page<<8);
*(RP)DMAC_C0CONTROL = 0x0021149B ; //word-word burst=4 size=128words+4words
#endif
*(RP)DMAC_C0SRCADDR = src_addr ;
*(RP)DMAC_C0DESTADD = EMI_NAND_DATA ;
*(RP)DMAC_C0CONFIGURATION = 0x300b ; //enable DMA channel
*(RP)EMI_NAND_COM = NAND_CMD_SEQIN ;
i = *(RP)DMAC_INTTCSTATUS; //judge Nand flash compish actions by IDLE register
while((i&0x1) != 0x1) //not yet, then wait another period of time
{
for(j = 0x0; j < 0x20; j++);
NTM++;
if(NTM == 0x5) break;
i = *(RP)DMAC_INTTCSTATUS;
}
if(NTM >= 0x5) return E_HA; //still time out? then return error!
else
{
*(RP)DMAC_INTTCCLEAR=0x1;
while((*(RP)DMAC_INTERRORSTATUS)&0x1==0x1)
{
for(j = 0x0; j < 0xa; j++);
}
*(RP)DMAC_INTTCCLEAR=0x0;
return E_OK; //OK! return happy!
}
}
U32 NAND_READ(U32 dest_addr,U32 nand_page)
{
U32 i,j,NTM = 0x0;
#ifdef TWOK_PAGE
*(RP)EMI_NAND_ADDR1 = (U32)(nand_page<<16);
*(RP)DMAC_C0CONTROL = 0x0084249b ; //word-word burst=4 size=512words+16words
#else
*(RP)EMI_NAND_ADDR1 = (U32)(nand_page<<8);
*(RP)DMAC_C0CONTROL = 0x0021249b ; //word-word burst=4 size=128words+4words
#endif
*(RP)DMAC_C0SRCADDR = EMI_NAND_DATA ;
*(RP)DMAC_C0DESTADD = dest_addr ;
*(RP)DMAC_C0CONFIGURATION = 0x31d ; //enable DMA channel
*(RP)EMI_NAND_COM = NAND_CMD_READ0 ;
i = *(RP)EMI_NAND_IDLE; //judge Nand flash compish actions by IDLE register
while((i&0x1) != 0x1) //not yet, then wait another period of time
{
for(j = 0; j < 0x20; j++);
NTM++;
if(NTM == 0x5) break;
i = *(RP)EMI_NAND_IDLE;
}
if(NTM >= 0x5) return E_HA; //still time out? then return error!
return E_OK; //OK! return happy!
}
U32 NAND_ERASE(U32 nand_page)
{
U32 i,j,NTM = 0x0;
#ifdef TWOK_PAGE
*(RP)EMI_NAND_ADDR1 = (U32)(nand_page<<16);
#else
*(RP)EMI_NAND_ADDR1 = (U32)(nand_page<<8);
#endif
*(RP)EMI_NAND_COM = NAND_CMD_ERASE ;
i = *(RP)EMI_NAND_IDLE; //judge Nand flash compish actions by IDLE register
while((i&0x1) != 0x1)
{
for(j = 0x0; j < 0x20; j++); //not yet, then wait another period of time
NTM++;
if(NTM == 0x5) break;
i = *(RP)EMI_NAND_IDLE;
}
if(NTM >= 0x5) return E_HA; //still time out? then return error!
return E_OK; //OK! return happy!
}
U32 NAND_READ_ID(void)
{
U32 i,j,NTM = 0x0;
*(RP)EMI_NAND_COM = NAND_CMD_READID ;
i = *(RP)EMI_NAND_IDLE; //judge Nand flash compish actions by IDLE register
while((i&0x1) != 0x1)
{
for(j = 0x0; j < 0x20; j++); //not yet, then wait another period of time
NTM++;
if(NTM == 0x5) break;
i = *(RP)EMI_NAND_IDLE;
}
if(NTM >= 0x5) return E_HA; //still time out? then return error!
return E_OK; //OK! return happy!
}
U32 NAND_READ_STATUS(void)
{
U32 i,j,NTM = 0x0;
*(RP)EMI_NAND_COM = NAND_CMD_STATUS ;
i = *(RP)EMI_NAND_IDLE; //judge Nand flash compish actions by IDLE register
while((i&0x1) != 0x1)
{
for(j = 0x0; j < 0x20; j++); //not yet, then wait another period of time
NTM++;
if(NTM == 0x5) break;
i = *(RP)EMI_NAND_IDLE;
}
if(NTM >= 0x5) return E_HA; //still time out? then return error!
return E_OK; //OK! return happy!
}
void int_serv_dma(void)
{
U32 result=0x20060000;
U32 j;
#ifdef REMAPESRAM
*(RP)(result+0x24)=0x10;
*(RP)DMAC_INTTCCLEAR=0x1;
while((*(RP)DMAC_INTERRORSTATUS)&0x1==0x1)
{
for(j = 0x0; j < 0xa; j++);
}
*(RP)DMAC_INTTCCLEAR=0x0;
#endif
return ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -