📄 l1_storage.c
字号:
/*++
Copyright (c) 2001 Sunplus Technology Co., Ltd.
Module Name:
L1_Storage.c
Abstract:
Storage related function
Environment:
Keil C51 Compiler
Revision History:
11/30/2001 WZH created
--*/
//=============================================================================
//Header file
//=============================================================================
#include "general.h"
#include "main.h"
#if (SD)
#include "sdvar.h" //ada@0218
#include "dosvar.h"
#endif
#if (MMC)
#include "mmcvar.h" //ada@0218
#include "dosvar.h"
#endif
//=============================================================================
//Symbol
//=============================================================================
//-----------------------------------------------------------------------------
//Constant
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Variable
//-----------------------------------------------------------------------------
#if (SD)
xdata UCHAR SD_OCR[4];
xdata UCHAR SD_RCA[2];
xdata UCHAR SD_CID[16];
xdata UCHAR SD_CSD[16];
#endif
#if (MMC)
xdata UCHAR MMC_OCR[4];
xdata UCHAR MMC_RCA[2];
xdata UCHAR MMC_CID[16];
xdata UCHAR MMC_CSD[16];
#endif
//patch4.5@richie@msdc plug out exception
#include "uiflow.h"
//=============================================================================
//Program
//=============================================================================
//-----------------------------------------------------------------------------
//L1_NANDtoDRAM
//-----------------------------------------------------------------------------
UCHAR L1_NANDtoDRAM(ULONG DRAMAddr, ULONG NANDAddr, ULONG nByte) USING_0
{
UCHAR error;
ULONG i;
ULONG bndry;
UCHAR MarkerID,DeviceID;
USHORT pagesize,blocksize;
UCHAR pagebit,blockbit;
//PRINT_L1(" L1_NANDtoDRAM: Enter\n");
L2_NANDInit(1,1);
#if (SMC)
L2_FlashMode(0x01, 0x02, 0x00);
#endif
#if (CFAIDE)
L2_FlashMode(0x01, 0x03, 0x00);
#endif
#if (CFAMEM)
L2_FlashMode(0x01, 0x04, 0x00);
#endif
#if (SD)
L2_FlashMode(0x01, 0x05, 0x00);
#endif
#if (MMC)
L2_FlashMode(0x01, 0x06, 0x00);
#endif
L1_ReadNandID(&MarkerID, &DeviceID);
//PRINT_L1(" L1_NANDtoDRAM: Nand flash Marker code=%bx, Device code = %bx\n ",MarkerID,DeviceID);
if((MarkerID==0xec) && (DeviceID==0xe6)) {
pagesize =512; // one page = (512 + 16) bytes
pagebit = 9;
blocksize = 8192; // one block = (8192 + 256) bytes
blockbit =13;
#if (SMC)
L2_FlashMode(0x01, 0x02, 0x01);
#endif
#if (CFAIDE)
L2_FlashMode(0x01, 0x03, 0x01);
#endif
#if (CFAMEM)
L2_FlashMode(0x01, 0x04, 0x01);
#endif
#if (SD)
L2_FlashMode(0x01, 0x05, 0x01);
#endif
#if (MMC)
L2_FlashMode(0x01, 0x06, 0x01);
#endif
}
else if((MarkerID==0xec) && (DeviceID==0xea)) {
pagesize =256; // one page = (256 + 8) bytes
pagebit = 8;
blocksize = 4096; // one block = (4096 + 128) bytes
blockbit =12;
#if (SMC)
L2_FlashMode(0x01, 0x02, 0x00);
#endif
#if (CFAIDE)
L2_FlashMode(0x01, 0x03, 0x00);
#endif
#if (CFAMEM)
L2_FlashMode(0x01, 0x04, 0x00);
#endif
#if (SD)
L2_FlashMode(0x01, 0x05, 0x00);
#endif
#if (MMC)
L2_FlashMode(0x01, 0x06, 0x00);
#endif
}
else {
#if (SMC)
L2_FlashMode(0x02, 0x01,0x01);
#endif
#if (CFAIDE)
L2_FlashMode(0x03, 0x01,0x01);
#endif
#if (CFAMEM)
L2_FlashMode(0x04, 0x01,0x01);
#endif
#if (SD)
L2_FlashMode(0x05, 0x01,0x01);
#endif
#if (MMC)
L2_FlashMode(0x06, 0x01,0x01);
#endif
//PRINT_L1(" L1_NANDtoDRAM: Error device\n",pagesize);
return 0x01;
}
//PRINT_L1(" L1_NANDtoDRAM: Page size = %d\n",pagesize);
/*
if((nByte%blocksize)==0)
bndry = (nByte >> blockbit) << blockbit;
else bndry = ((nByte >> blockbit)+1) << blockbit;
for(i=0; i<bndry; i=i+blocksize) {
// Read One Page command
L2_SetDRAMDMA(DRAMAddr+i/2);
error = L1_DMARdNAND(0, 8, NANDAddr+i, 16, pagesize);
if(error!=0) {
//PRINT_L1("ECC error at address = %lx\n", (NANDAddr+i));
break;
}
}
*/
if((nByte%pagesize)==0)
bndry = (nByte >> pagebit) << pagebit;
else bndry = ((nByte >> pagebit)+1) << pagebit;
for(i=0; i<bndry; i=i+pagesize) {
// Read One Page command
L2_SetDRAMDMA(DRAMAddr+i/2);
error = L1_DMARdNAND(0, 8, NANDAddr+i, 1, pagesize);
if(error!=0) {
//PRINT_L1("ECC error at address = %lx\n", (NANDAddr+i));
break;
}
}
#if (SMC)
L2_FlashMode(0x02, 0x01,0x01);
#endif
#if (CFAIDE)
L2_FlashMode(0x03, 0x01,0x01);
#endif
#if (CFAMEM)
L2_FlashMode(0x04, 0x01,0x01);
#endif
#if (SD)
L2_FlashMode(0x05, 0x01,0x01);
#endif
#if (MMC)
L2_FlashMode(0x06, 0x01,0x01);
#endif
//PRINT_L1(" L1_NANDtoDRAM: Exit\n");
return 0x00;
}
//-----------------------------------------------------------------------------
//L1_DRAMtoNAND
//-----------------------------------------------------------------------------
UCHAR L1_DRAMtoNAND(ULONG DRAMAddr, ULONG NANDAddr, ULONG nByte) USING_0
{
UCHAR error;
ULONG i;
ULONG bndry;
UCHAR MarkerID,DeviceID;
USHORT pagesize,blocksize;
UCHAR pagebit,blockbit;
//PRINT_L1(" L1_DRAMtoNAND: Enter\n");
//PRINT_L1(" L1_DRAMtoNAND: DRAMAddr=%lx, NANDAddr=%lx, nByte=%lx\n",DRAMAddr,NANDAddr,nByte);
L2_NANDInit(1,1);
#if (SMC)
L2_FlashMode(0x01, 0x02, 0x00);
#endif
#if (CFAIDE)
L2_FlashMode(0x01, 0x03, 0x00);
#endif
#if (CFAMEM)
L2_FlashMode(0x01, 0x04, 0x00);
#endif
#if (SD)
L2_FlashMode(0x01, 0x05, 0x00);
#endif
#if (MMC)
L2_FlashMode(0x01, 0x06, 0x00);
#endif
L1_ReadNandID(&MarkerID, &DeviceID);
if((MarkerID==0xec) && (DeviceID==0xe6)) {
pagesize =512; // one page = (512 + 16) bytes
pagebit = 9;
blocksize = 8192; // one block = (8192 + 256) bytes
blockbit =13;
#if (SMC)
L2_FlashMode(0x01, 0x02, 0x01);
#endif
#if (CFAIDE)
L2_FlashMode(0x01, 0x03, 0x01);
#endif
#if (CFAMEM)
L2_FlashMode(0x01, 0x04, 0x01);
#endif
#if (SD)
L2_FlashMode(0x01, 0x05, 0x01);
#endif
#if (MMC)
L2_FlashMode(0x01, 0x06, 0x01);
#endif
}
else if((MarkerID==0xec) && (DeviceID==0xea)) {
pagesize =256; // one page = (256 + 8) bytes
pagebit = 8;
blocksize = 4096; // one block = (4096 + 128) bytes
blockbit =12;
#if (SMC)
L2_FlashMode(0x01, 0x02, 0x00);
#endif
#if (CFAIDE)
L2_FlashMode(0x01, 0x03, 0x00);
#endif
#if (CFAMEM)
L2_FlashMode(0x01, 0x04, 0x00);
#endif
#if (SD)
L2_FlashMode(0x01, 0x05, 0x00);
#endif
#if (MMC)
L2_FlashMode(0x01, 0x06, 0x00);
#endif
}
else {
#if (SMC)
L2_FlashMode(0x02, 0x01,0x01);
#endif
#if (CFAIDE)
L2_FlashMode(0x03, 0x01,0x01);
#endif
#if (CFAMEM)
L2_FlashMode(0x04, 0x01,0x01);
#endif
#if (SD)
L2_FlashMode(0x05, 0x01,0x01);
#endif
#if (MMC)
L2_FlashMode(0x06, 0x01,0x01);
#endif
//PRINT_L1(" L1_DRAMtoNAND: Error device\n",pagesize);
return 0x01;
}
//PRINT_L1(" L1_DRAMtoNAND: Page size = %d\n",pagesize);
if((nByte%blocksize)==0)
bndry = (nByte >> blockbit) << blockbit;
else bndry = ((nByte >> blockbit)+1) << blockbit;
for(i=0; i<bndry; i=i+blocksize) {
L1_EraseNandBlock(2, (NANDAddr+i)>>pagebit, &error);
if((error & 0x01)!=0) {
//PRINT_L1(" L1_DRAMtoNAND: Erase Fail\n");
break;
}
// WRITE 16 Pages
L2_SetDRAMDMA(DRAMAddr+i/2);
error = L1_DMAWrNAND(0, 8, NANDAddr+i, 16, pagesize);
if(error!=0) {
//PRINT_L1(" L1_DRAMtoNAND: Program Fail\n");
break;
}
}
#if (SMC)
L2_FlashMode(0x02, 0x01,0x01);
#endif
#if (CFAIDE)
L2_FlashMode(0x03, 0x01,0x01);
#endif
#if (CFAMEM)
L2_FlashMode(0x04, 0x01,0x01);
#endif
#if (SD)
L2_FlashMode(0x05, 0x01,0x01);
#endif
#if (MMC)
L2_FlashMode(0x06, 0x01,0x01);
#endif
//PRINT_L1(" L1_DRAMtoNAND: Exit\n");
return 0x00;
}
//-----------------------------------------------------------------------------
//L1_ReadNandID
//-----------------------------------------------------------------------------
/*
routine description:
NAND gate flash read ID command
arguments:
marker ID:
device ID:
return value:
None
*/
//patch4.5@ada@Add timeout count begin
UCHAR L1_ReadNandID(UCHAR* MarkerID, UCHAR* DeviceID) USING_0
//void L1_ReadNandID(UCHAR* MarkerID, UCHAR* DeviceID) USING_0
{
UCHAR Ready;
L2_NANDSendCmd(0x90);
L2_NANDSendAddr(1,0);
L2_NANDCheckRdy(&Ready);
if (Ready != 0)
{
return 0x01;
}
L2_NANDReadPort(MarkerID);
L2_NANDReadPort(DeviceID);
L2_NANDCompleteOperation();
return 0x00;
}
//patch4.5@ada@Add timeout count end
//-----------------------------------------------------------------------------
//L1_EraseNandBlock
//-----------------------------------------------------------------------------
/*
routine description:
NAND gate flash erase block command
arguments:
AddrCycCnt: the number of address cycle to be transfer
1: Addr[7:0] is sent
2: Addr[7:0], Addr[15:8] is sent
3: Addr[7:0], Addr[15:8], Addr[23:16] is sent
4: Addr[7:0], Addr[15:8], Addr[23:16], Addr[31:24] is sent
Addr: block address
Status: the status after erase command completed
return value:
None
*/
//patch4.5@ada@Add timeout count begin
UCHAR L1_EraseNandBlock(UCHAR AddrCycCnt, ULONG Addr, UCHAR* Status) USING_0
//void L1_EraseNandBlock(UCHAR AddrCycCnt, ULONG Addr, UCHAR* Status) USING_0
//patch4.5@ada@Add timeout count end
{
UCHAR Ready;
L2_NANDSendCmd(0x60);
if(AddrCycCnt == 1) L2_NANDSendAddr(1,Addr);
else if(AddrCycCnt == 2) L2_NANDSendAddr(2,Addr);
else if(AddrCycCnt == 3) L2_NANDSendAddr(3,Addr);
else L2_NANDSendAddr(4,Addr);
L2_NANDSendCmd(0xd0);
L2_NANDCheckRdy(&Ready);
if (Ready != 0)
{
return 0x01;
}
L2_NANDSendCmd(0x70);
L2_NANDReadPort(Status);
L2_NANDCompleteOperation();
return 0x00;
}
//patch4.5@ada@Add timeout count end
//-----------------------------------------------------------------------------
//L1_DMAWrNAND
//-----------------------------------------------------------------------------
/*
routine description:
DMA write data to nand gate flash
arguments:
Src:the source of DMA
0: DRAM
1: CPU 4K SRAM (0x1000 ~ 0x1FFF)
2: forbidden (flash itself)
3: Audio
4: USB
5: DMA data port (0x2300)
NandSize: the size of nand gate flash (in the unit of Mbytes)
example: NandSize = 8 , that is 8 M bytes nand gate flash
Addr: the start address of nand gate flash to be written to
PageCnt: the number of page to be transfer (0 is 256 pages)maximum page is 256
PageSize: the number of bytes in a page
return value:
0x00 - success
others - error
*/
UCHAR L1_DMAWrNAND(UCHAR Src, UCHAR NandSize, ULONG Addr, ULONG PageCnt, USHORT PageSize) USING_0
{
ULONG dramaddr;
ULONG tmp;
UCHAR tmp0;
UCHAR ECCCnt;
UCHAR LowAddr;
UCHAR ECCData[12];
//patch4.5@ada@Add timeout count begin
UCHAR error;
//patch4.5@ada@Add timeout count end
UCHAR Status;
//PRINT_L1(" L1_DMAWrNAND: Enter L1_DMAWrNAND(Src,Addr,PageCnt,PageSize)=(%x,%lx,%lx,%x)\n",(USHORT)Src,Addr,PageCnt,PageSize);
if(Src==0) L2_ReadDRAMDMAAdr(&dramaddr);
LowAddr = (UCHAR)(Addr&0x000000ff);
for(tmp0 = 0; tmp0<12 ; tmp0++) ECCData[tmp0] = 0xff;
if(PageSize == 256) {Addr = Addr >> 8; ECCCnt = 3;}
else if(PageSize == 512) {Addr = Addr >> 9; ECCCnt = 6;}
else if(PageSize == 1024) {Addr = Addr >> 10; ECCCnt = 12;}
else return 0x01;
error = 0;
for(tmp = 0; tmp< PageCnt ; tmp++)
{
if(Src == 0) L2_SetDRAMDMA(dramaddr);
L2_NANDSendCmd(0x80);
L2_NANDSendAddr(1,LowAddr);
if(NandSize < 16)
L2_NANDSendAddr(2,Addr);
else
L2_NANDSendAddr(3,Addr);
L2_ECCMode(0);
L2_ClearECC();
//patch4.5@ada@Add timeout count begin
error = L2_DoDMA(Src,2,PageSize,0,0);
if (error != 0)
{
return error;
}
//patch4.5@ada@Add timeout count end
L2_ReadECC(ECCCnt,ECCData);
for(tmp0=0; tmp0<ECCCnt; tmp0++)
L2_NANDWritePort(ECCData[tmp0]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -