📄 onenand.c
字号:
#if SMCLK66MHZ // @66.7MHz
pSmcRegs->rSmbWstRdr = 4; // read wait state. [4:0] min 3 @ 50MHz, min 4 @ 66MHz
pSmcRegs->rSmbWstWrr = 4; // write wait state. [4:0] min 3 @ 50MHz, min 4 @ 66MHz
pSmcRegs->rSmbWstOenr = 3; // OE assertion delay. [3:0] min 2 @ 50MHz, min 3 @ 66MHz
pSmcRegs->rSmbWstWenr = 3; // WE assertion delay. [3:0] min 2 @ 50MHz, min 3 @ 66MHz
#else // @50MHz
pSmcRegs->rSmbWstRdr = 3; // read wait state. [4:0] min 3 @ 50MHz, min 4 @ 66MHz
pSmcRegs->rSmbWstWrr = 3; // write wait state. [4:0] min 3 @ 50MHz, min 4 @ 66MHz
pSmcRegs->rSmbWstOenr = 2; // OE assertion delay. [3:0] min 2 @ 50MHz, min 3 @ 66MHz
pSmcRegs->rSmbWstWenr = 2; // WE assertion delay. [3:0] min 2 @ 50MHz, min 3 @ 66MHz
#endif
break;
}
sysconfig1=rOND_SYS_CONFIG1;
printf("rOND_SYS_CONFIG1 = 0x%x \n", sysconfig1);
printf("rSMBCR%d = 0x%x \n", nBank, pSmcRegs->rSmbCr);
printf("rSMBWSTRDR%d = 0x%x\n", nBank, pSmcRegs->rSmbWstRdr);
printf("rSMBWSTWRR%d = 0x%x\n", nBank, pSmcRegs->rSmbWstWrr);
printf("rSMBWSTOENR%d = 0x%x\n", nBank, pSmcRegs->rSmbWstOenr);
printf("rSMBWSTWENR%d = 0x%x\n\n", nBank, pSmcRegs->rSmbWstWenr);
}
void OneNAND_Burst_Read( void)
{
U16 block=0;
U16 page=0;
U32 i;
U32 *Addr;
printf("\nOneNAND block read\n");
printf("Enter block # to read : ");
block = GetIntNum();
printf("Enter page # to read : ");
page = GetIntNum();
if (OND_page_load(block,page)==0) {
memcpy( (U32 *)(_NONCACHE_STARTADDRESS+0x01000000), (U32 *)__OND_DataRAM0_BASE, DATABUFFERSIZE);
Addr=(U32 *)(_NONCACHE_STARTADDRESS+0x01000000);
for(i=0;i<DATABUFFERSIZE;i+=sizeof(U32)) {
if ((i&0x1f)==0)
printf("\n%08x : ",i);
printf("%08x ",*Addr++);
}
putchar('\n');
}
}
// start line to be added by junon 2007.02.09
volatile unsigned char div_factor = 0;
void __irq DmaCopyDone(void)
{
rSUBSRCPND = BIT_SUB_DMA5|BIT_SUB_DMA0;
ClearPending(BIT_DMA);
dma_copy_done = 1;
// printf("d");
}
// use channel 5
void dma_init(U32 tsz, U32 dsz)
{
DMA_REGS *pDMA = NULL;
pDMA=(void *)(DMA_REG_BASE + 5*DMA_REG_OFFSET); // ch 5
pISR_DMA=(int)DmaCopyDone;
rINTMSK&=~(BIT_DMA);
rINTSUBMSK&=~(BIT_SUB_DMA5);
pDMA->rDiSrcc=(0<<1)|(0<<0); // AHB, INC
pDMA->rDiDstc=(0<<2)|(0<<1)|(0<<0); // AHB, INC
pDMA->rDCon=(1<<31)|(1<<30)|(1<<29)|(tsz<<28)|(1<<27)|(1<<24)|(1<<22)|(dsz<<20);
//HS|AHB|InterruptEn|TransferSize|WholeServ|RelaodOff|DataSize|TransferCount
pDMA->rDmaReqSel=0; //S/W request mode
switch(dsz)
{
case 0 : // byte
div_factor = ((tsz?4:1)*1);
break;
case 1 : // halfword
div_factor = ((tsz?4:1)*2);
break;
case 2 : // word
div_factor = ((tsz?4:1)*4);
break;
default :
printf("DMA setting err, check code\n");
break;
}
}
void dma_memcpy(U32 s_addr, U32 d_addr, U32 tot_sz) // max size = 0xfffff
{
U32 tc = 0;
DMA_REGS *pDMA = NULL;
pDMA = (void *)(DMA_REG_BASE + 5*DMA_REG_OFFSET); // ch 5
tc = tot_sz / div_factor;
pDMA->rDiSrc = s_addr;
pDMA->rDiDst = d_addr;
pDMA->rDCon = (pDMA->rDCon & ~(0xfffff)) | (tc);
pDMA->rDMaskTrig = (1<<1)|1; //DMA on, SW_TRIG
//printf(" Con=0x%x ", pDMA->rDCon);
}
void OneNAND_Performance_Test(void)
{
U16 c_block=0;
U32 c_size=0;
U32 i;
U32 *SrcAddr, *DstAddr;
U32 t_cnt=1;
U8 d_correct=0;
U8 dma_burst;
U8 dma_tw;
// SMC parameter value setting
SMC_Config4OneNAND(OND_BANK);
printf("\nrOND_SYS_CONFIG1 = 0x%x \n", rOND_SYS_CONFIG1);
printf("rOND_DBUFSIZE = 0x%x \n", rOND_DBUFSIZE);
printf("rOND_BBUFSIZE = 0x%x \n", rOND_BBUFSIZE);
printf("rOND_BUFAMOUNT = 0x%x \n", rOND_BUFAMOUNT);
// Default test block variable setting
printf("\n Enter start block # to write [D:700, unit=block] : ");
c_block = GetIntNum();
if ( (c_block == (U16)(-1)) || (c_block<1) )
c_block = 700; // start block
printf(" Enter data size # to write [D:2MB, MAX:10MB, unit=Byte] : ");
c_size = GetIntNum();
if ( (c_size == (U32)(-1)) || (c_size<2048) )
c_size = 0x200000; // 16 blocks = 2MB
SrcAddr = (U32 *)(_NONCACHE_STARTADDRESS+0x00300000);
printf(" Start block : %d, Data size : %d Bytes\n", c_block, c_size);
// General DMA burst setting
printf(" Do you want to use dma? Yes(y) or No(n) : ");
if (getchar()=='y')
{
g_use_dma = 1;
printf("\n Enter dma transfer data width [D:4byte] (0)1byte, (1)2byte, (2)4byte : ");
dma_tw = (U8)GetIntNum();
if (dma_tw > 2) dma_tw = 2;
printf(" Enter dma burst size [D:4-burst] (0)single, (1)4-burst : ");
dma_burst = (U8)GetIntNum();
if (dma_burst > 1) dma_burst = 1;
dma_init(dma_burst, dma_tw);
}
// fill buffer data
for (i=0; i<c_size ;i+=4)
*SrcAddr++ = 0x12345678;
SrcAddr = (U32 *)(_NONCACHE_STARTADDRESS+0x00300000);
DstAddr = (U32 *)(_NONCACHE_STARTADDRESS+0x01000000);
// write test by block unit(internally page unit), Write-While-Program Operation
//StartStopwatch();
OND_write( SrcAddr, c_size, c_block);
//t_cnt = EndStopwatch();
printf("\n %d Bytes WRITE time by block unit : %d us", c_size, t_cnt);
printf("\n %.3f Byte/sec\n", (float)c_size/(float)t_cnt*1000000 );
getchar();
// read test by block unit(internally page unit), Read-While-Load Operation
//StartStopwatch();
OND_read( DstAddr, c_size, c_block);
//t_cnt = EndStopwatch();
printf("\n %d Bytes READ time by block unit : %d us", c_size, t_cnt);
printf("\n %.3f Byte/sec\n", (float)c_size/(float)t_cnt*1000000 );
// change to display.h ==> #define LCD_FRAME_BUFFER 0 // for SMC test temporary...
// Display_RgbIf(); // display.h modified..
// verify data
for (i=0; i<c_size ;i+=4)
if (*SrcAddr++ != *DstAddr++)
d_correct = 1;
if(d_correct == 1)
printf("\n Copied data error!! \n\n");
else printf("\n Copied data OK!! \n\n");
}
void BurstWrite_Test(void)
{
U32 sel_sync = 2;
U32 sel_burst = 4;
U32 burst_mode = 1;
U32 mux_mode = 0;
U16 sysconfig1;
U32 *SrcAddr, *DstAddr, i;
dma_copy_done =0;
SrcAddr = (U32 *)(_NONCACHE_STARTADDRESS+0x00300000);
DstAddr = (U32 *)(_NONCACHE_STARTADDRESS+0x01000000);
for (i=0; i<0x800 ;i+=4)
*SrcAddr++ = 0x12345678;
//rSMBONETYPER |= (1<<0); // muxed mode
// ensure that ther are no memory transfers.
rCLKDIV0 = (rCLKDIV0 & ~(1<<3)) | (1<<3); // select HALFHCLK : 0=HCLK, 1=HCLK/2
rSMCCR = (rSMCCR & ~(3<<1)) | (1<<1)|(1); // SMC MemClkRatio setting should be equal HALFHCLK of CLKDIV0
// defualt setting for reading correct rOND_SYS_CONFIG1
rSMBWSTRDR0 = 3; // read wait state. [4:0] 1 ~ 10. only 4 @ 50MHz(Mux). sync burst only 4
rSMBWSTWRR0= 3; // write wait state. [4:0] 1 ~ 10. min 3 @ 50MHz
rSMBWSTOENR0 = 2; // OE assertion delay. [3:0] 1 ~ 2. min 3 @ 50MHz
rSMBWSTWENR0= 2; // WE assertion delay. [3:0] 1 ~ 3. min 3 @ 50MHz
rSMBCR0 = (rSMBCR0 & ~((0xf<<8)|(0xf<<16)|(1<<14)|0x3))
|(0<<18)|(1<<17)|(1<<16)// set SSMC write
|(0<<10)|(1<<9)|(0<<8) // set SSMC as read burst.
|(0<<14)|(0<<1)|(1); // caution! SMWAIT polarity setting. now active low.
//rSMBCR0 = rSMBCR0 & ~(3<<4) | (1<<15)|(1<<7)|(1<<4)|(1<<2)|(1);
rSMBWSTBRDR5= 0;
/*
pISR_DMA=(int)DmaCopyDone;
rINTMSK&=~(BIT_DMA);
rINTSUBMSK&=~(BIT_SUB_DMA0);
*/
rDISRC0=0x31300000;
rDISRCC0=(0<<1)|(0<<0); // AHB, INC
rDIDST0=__OND_DataRAM0_BASE;
//rDIDST0=0x31500000;
rDIDSTC0=(0<<1)|(0<<0); // AHB, INC
rDCON0=(1<<31)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(1<<22)|(1<<20)|(0x100);
//HS|AHB|InterruptEn|TransferSize|WholeServ|RelaodOff|DataSize|TransferCount
rDMAREQSEL0=0; //S/W request mode
rDMASKTRIG0=(1<<1)|1; //DMA on, SW_TRIG
//while(!dma_copy_done);
while(!(rDSTAT0&0xfffff));
printf("\nTransfer Done\n");
}
void NonburstWrite_Test(void)
{
U32 sel_sync = 2;
U32 sel_burst = 4;
U32 burst_mode = 1;
U32 mux_mode = 0;
U16 sysconfig1;
U32 *SrcAddr, *DstAddr, i;
dma_copy_done =0;
SrcAddr = (U32 *)(_NONCACHE_STARTADDRESS+0x00300000);
DstAddr = (U32 *)(_NONCACHE_STARTADDRESS+0x01000000);
for (i=0; i<0x800 ;i+=4)
*SrcAddr++ = 0x12345678;
//rSMBONETYPER |= (1<<0); // muxed mode
// ensure that ther are no memory transfers.
rCLKDIV0 = (rCLKDIV0 & ~(1<<3)) | (1<<3); // select HALFHCLK : 0=HCLK, 1=HCLK/2
rSMCCR = (rSMCCR & ~(3<<1)) | (1<<1)|(1); // SMC MemClkRatio setting should be equal HALFHCLK of CLKDIV0
// defualt setting for reading correct rOND_SYS_CONFIG1
/*
rSMBWSTRDR0 = 3; // read wait state. [4:0] 1 ~ 10. only 4 @ 50MHz(Mux). sync burst only 4
rSMBWSTWRR0= 8; // write wait state. [4:0] 1 ~ 10. min 3 @ 50MHz
rSMBWSTOENR0 = 2; // OE assertion delay. [3:0] 1 ~ 2. min 3 @ 50MHz
rSMBWSTWENR0= 5; // WE assertion delay. [3:0] 1 ~ 3. min 3 @ 50MHz
*/
rSMBCR0 = (rSMBCR0 & ~((0xf<<8)|(0xf<<16)|(1<<14)|0x3))
|(0<<18)|(1<<17)|(0<<16)// set SSMC write
|(0<<10)|(0<<9)|(0<<8) // set SSMC as read burst.
|(0<<14)|(0<<1)|(1); // caution! SMWAIT polarity setting. now active low.
//rSMBCR0 = rSMBCR0 & ~(0xfffff) |(0x3<<22)|(0<<17)| (0<<15)|(0<<9)|(0<<7)|(1<<4)|(1<<2)|(1);
//rSMBWSTBRDR5= 0;
/*
pISR_DMA=(int)DmaCopyDone;
rINTMSK&=~(BIT_DMA);
rINTSUBMSK&=~(BIT_SUB_DMA0);
*/
rDISRC0=0x31300000;
rDISRCC0=(0<<1)|(0<<0); // AHB, INC
rDIDST0=__OND_DataRAM0_BASE;
//rDIDST0=0x31500000;
rDIDSTC0=(0<<1)|(0<<0); // AHB, INC
rDCON0=(1<<31)|(1<<30)|(1<<29)|(0<<28)|(1<<27)|(0<<22)|(1<<20)|(0x100);
//HS|AHB|InterruptEn|TransferSize|WholeServ|RelaodOff|DataSize|TransferCount
rDMAREQSEL0=0; //S/W request mode
rDMASKTRIG0=(1<<1)|1; //DMA on, SW_TRIG
//while(!dma_copy_done);
while(!(rDSTAT0&0xfffff));
printf("\nTransfer Done\n");
}
// end line to be added by junon 2007.02.09
void NonburstWrite_Test_UsingnWait_timing(void)
{
U32 sel_sync = 2;
U32 sel_burst = 4;
U32 burst_mode = 1;
U32 mux_mode = 0;
U16 sysconfig1;
U32 *SrcAddr, *DstAddr, i;
dma_copy_done =0;
rSMBCR0 |= (1<<7)|(1<<2);
rSMBCR1 |= (1<<7)| (1<<2);
rSMBCR2 |= (1<<7)|(1<<2);
rSMBCR3 |= (1<<7)|(1<<2);
rSMBCR4 |= (1<<7)|(1<<2);
rSMBCR5 |= (1<<7)|(1<<2);
SrcAddr = (U32 *)(_NONCACHE_STARTADDRESS+0x00300000);
DstAddr = (U32 *)(_NONCACHE_STARTADDRESS+0x01000000);
for (i=0; i<0x800 ;i+=4)
*SrcAddr++ = 0x12345678;
//rSMBONETYPER |= (1<<0); // muxed mode
// ensure that ther are no memory transfers.
rCLKDIV0 = (rCLKDIV0 & ~(1<<3)) | (1<<3); // select HALFHCLK : 0=HCLK, 1=HCLK/2
rSMCCR = (rSMCCR & ~(3<<1)) | (1<<1)|(1); // SMC MemClkRatio setting should be equal HALFHCLK of CLKDIV0
// defualt setting for reading correct rOND_SYS_CONFIG1
/*
rSMBWSTRDR0 = 3; // read wait state. [4:0] 1 ~ 10. only 4 @ 50MHz(Mux). sync burst only 4
rSMBWSTWRR0= 8; // write wait state. [4:0] 1 ~ 10. min 3 @ 50MHz
rSMBWSTOENR0 = 2; // OE assertion delay. [3:0] 1 ~ 2. min 3 @ 50MHz
rSMBWSTWENR0= 5; // WE assertion delay. [3:0] 1 ~ 3. min 3 @ 50MHz
*/
rSMBCR0 = (rSMBCR0 & ~((0xf<<8)|(0xf<<16)|(1<<14)|0x3))
|(0<<22)|(0<<18)|(1<<17)|(0<<16)|(1<<15)// set SSMC write
|(0<<10)|(0<<9)|(0<<8)|(1<<7) // set SSMC as read burst.
|(1<<4)|(1<<2)|(0<<1)|(1); // caution! SMWAIT polarity setting. now active low.
//rSMBCR0 = rSMBCR0 & ~(0xfffff) |(0x3<<22)|(0<<17)| (0<<15)|(0<<9)|(0<<7)|(1<<4)|(1<<2)|(1);
//rSMBWSTBRDR5= 0;
/*
pISR_DMA=(int)DmaCopyDone;
rINTMSK&=~(BIT_DMA);
rINTSUBMSK&=~(BIT_SUB_DMA0);
*/
rDISRC0=0x31300000;
rDISRCC0=(0<<1)|(0<<0); // AHB, INC
rDIDST0=__OND_DataRAM0_BASE;
//rDIDST0=0x31500000;
rDIDSTC0=(0<<1)|(0<<0); // AHB, INC
rDCON0=(1<<31)|(1<<30)|(1<<29)|(0<<28)|(1<<27)|(0<<22)|(1<<20)|(0x100);
//HS|AHB|InterruptEn|TransferSize|WholeServ|RelaodOff|DataSize|TransferCount
rDMAREQSEL0=0; //S/W request mode
rDMASKTRIG0=(1<<1)|1; //DMA on, SW_TRIG
//while(!dma_copy_done);
while(!(rDSTAT0&0xfffff));
printf("\nTransfer Done\n");
}
void OneNAND_ReadAddr_checkAddr0( void)
{
int i;
rSMBCR0 = (rSMBCR0 & ~((3<<22)|(3<<4))) | (0<<22)|(1<<15)|(1<<7)|(1<<4)|(1<<2)|(0);
if(!(rSMBSR0&0x1))
i= (*(volatile U16 *)(__OND_BASEADDR + 0x2));
if(!(rSMBSR0&0x1))
i= (*(volatile U16 *)(__OND_BASEADDR + 0x2));
if(!(rSMBSR0&0x1))
i= (*(volatile U16 *)(__OND_BASEADDR + 0x2));
if(!(rSMBSR0&0x1))
i= (*(volatile U16 *)(__OND_BASEADDR + 0x2));
if(!(rSMBSR0&0x1))
i= (*(volatile U16 *)(__OND_BASEADDR + 0x2));
printf("0x0 : 0x%02x\n",(*(volatile U16 *)(__OND_BASEADDR + 0x2)));
printf("0x2 : 0x%02x\n",(*(volatile U16 *)(__OND_BASEADDR + 0x0)));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -