?? nand_drv.c
字號:
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
}while((++mi)<temp);
GenerateEcc(&EccBuf[0]);
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
*pd++ = (UINT8) (mNand_Read_Data() & 0xff) ;
error_code = CompareEcc(&EccBuf[0],pReadBuf + SECTOR_SIZE);
}
#endif /*_NFLASH_DMA_*/
return error_code ;
}
NAND_Ret NAND_PageProgramWithEcc(UINT32 udAddress, dataWidth *pWritebuf,UINT32 len )
{
#ifdef _NAND_DEBUG_
DEBUG_OUT("NandWriteWithEcc\n\r") ;
if ((pWritebuf == NULL) || (len > PAGE_SIZE))
{
DEBUG_OUT("Write NAND_SW_ERR\n\r") ;
return NAND_SW_ERR ;
}
if (udAddress >= FLASH_SIZE_64MB)
{
DEBUG_OUT("Write NAND_ADDR_OVERFLOW\n\r") ;
return NAND_ADDR_OVERFLOW;
}
/*if Write protection is valid*/
if (!IsWriteProtect())
{
DEBUG_OUT("Write NAND_WRPRT_ERR\n\r") ;
return NAND_WRPRT_ERR;
}
#endif /*_NAND_DEBUG_*/
WRITE_REG32(NFLASH_NFINTP_ADDR,1) ;
mNandWrite_SET_CLE(READ1_CMD_00H); /*reset pointer to 'a' area*/
mNandWrite_SET_CLE(PAGE_PRO_TRUE_CMD1);
mNandWrite_SET_ALE(udAddress&0x03ffffff) ;
EccClear() ;
/*********Write the main data area***********/
#ifdef _NFLASH_DMA_
{
UINT32 temp = 0;
UINT32 TimeOut = 0;
OS_DRIVER_ObtainSemaphore(DMA_SEMAPHORE_ID);
#if (DMA_TYPE==TYPE_IS_MOSE_DMA)
EnablePDClk(PD_CCKEN_DMAC_BIT);
/*start ,byte width ,length is len, source inc ,dst fix*/
/*temp = 1 << 0 | 0 << 4 | (SECTOR_SIZE - 1) << 8 | 0 << 20 | 1 << 21 ; */
temp = 0x21FF01 ;
ProgramDMAChannel((UINT32) pWritebuf,NFLASH_NFDOUT_ADDR,temp) ;
#ifndef _STAND_ALONE_
{
UINT32 EventResult; /* The 32-bit variable to where the set bits is copied*/
UINT16 EventStatus; /* Event status*/
EventStatus = OS_DRIVER_WaitEventOR(PERIPH_EVENT_ID,PERIPH_DMA_EVTBIT,
&EventResult,NAND_DMA_TIMEOUT_VALUE);
if (EventStatus == OS_DRIVER_WAIT_EVENT_TIMEOUT)
{
DEBUG_OUT("Write NAND_DMA_TIMEOUT\n\r") ;
OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID);
return NAND_DMA_TIMEOUT;
}
}
#else
temp = READ_REG32(DMA_DCR_ADDR);
while (temp & 0x10000000)
{
temp = READ_REG32(DMA_DCR_ADDR);
TimeOut++ ;
if (TimeOut == NAND_TIMEOUT_VALUE)
{
OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID);
return NAND_DMA_TIMEOUT ;
}
}
#endif/*_STAND_ALONE_*/
DisablePDClk(PD_CCKEN_DMAC_BIT);
#elif(DMA_TYPE==TYPE_IS_GPRS_DMA)
{
UINT32 CtlrParam = 0, CfgrParam = 0;
UINT32 ErrorCode ;
/*src busrt size 0 |dst burst size 0|src width 8bits|dst width 8bits|src inc,dst fix*/
CtlrParam = 1 << 22 ;
/*src dst peripheral is ignored | src master 0 | dst master 1| memory to memory | len bytes*/
CfgrParam = (1 << 7) | (512 << 12);
ProgramDMAChannel((UINT32) pWritebuf,NFLASH_NFDOUT_ADDR,CtlrParam,CfgrParam);
#ifndef _STAND_ALONE_
{
UINT32 EventResult; /* The 32-bit variable to where the set bits is copied*/
UINT16 EventStatus; /* Event status*/
EventStatus = OS_DRIVER_WaitEventOR(PERIPH_EVENT_ID,PERIPH_DMA_EVTBIT,
&EventResult,NAND_DMA_TIMEOUT_VALUE);
if (EventStatus == OS_DRIVER_WAIT_EVENT_TIMEOUT)
{
DEBUG_OUT("Write NAND_DMA_TIMEOUT\n\r") ;
OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID);
return NAND_DMA_TIMEOUT;
}
}
#else
temp = READ_REG32(DMA_ISR_ADDR);
while ((temp & 0x4) == 0)//default to channel 2
{
temp = READ_REG32(DMA_ISR_ADDR);
TimeOut++ ;
if (TimeOut == NAND_TIMEOUT_VALUE)
{
WRITE_REG32(DMA_ISR_ADDR, 0x4);
OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID);
return NAND_DMA_TIMEOUT ;
}
}
WRITE_REG32(DMA_ISR_ADDR, 0x4);
#endif/* _STAND_ALONE_*/
}
#endif/*(DMA_TYPE==TYPE_IS_MOSE_DMA)*/
OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID);
GenerateEcc(&pWritebuf[SECTOR_SIZE]);
/*start ,byte width ,length is len, source inc ,dst fix*/
OS_DRIVER_ObtainSemaphore(DMA_SEMAPHORE_ID);
/*temp = 1 << 0 | 0 << 4 | (16 - 1) << 8 | 0 << 20 | 1 << 21 ; */
#if (DMA_TYPE==TYPE_IS_MOSE_DMA)
EnablePDClk(PD_CCKEN_DMAC_BIT);
temp = 0x200F01 ;
ProgramDMAChannel((UINT32) (pWritebuf + SECTOR_SIZE),NFLASH_NFDOUT_ADDR,temp) ;
#ifndef _STAND_ALONE_
{
UINT32 EventResult; /* The 32-bit variable to where the set bits is copied*/
UINT16 EventStatus; /* Event status*/
EventStatus = OS_DRIVER_WaitEventOR(PERIPH_EVENT_ID,PERIPH_DMA_EVTBIT,
&EventResult,NAND_DMA_TIMEOUT_VALUE);
if (EventStatus == OS_DRIVER_WAIT_EVENT_TIMEOUT)
{
DEBUG_OUT("Write NAND_DMA_TIMEOUT\n\r") ;
OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID);
return NAND_DMA_TIMEOUT;
}
}
#else
TimeOut = 0;
temp = READ_REG32(DMA_DCR_ADDR);
while (temp & 0x10000000)
{
temp = READ_REG32(DMA_DCR_ADDR);
TimeOut++ ;
if (TimeOut == NAND_TIMEOUT_VALUE)
{
OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID);
return NAND_DMA_TIMEOUT ;
}
}
#endif/*_STAND_ALONE_*/
DisablePDClk(PD_CCKEN_DMAC_BIT);
#elif(DMA_TYPE==TYPE_IS_GPRS_DMA)
{
UINT32 CtlrParam = 0, CfgrParam = 0;
UINT32 ErrorCode ;
/*src busrt size 0 |dst burst size 0|src width 8bits|dst width 8bits|src inc,dst fix*/
CtlrParam = 1 << 22 ;
/*src dst peripheral is ignored | src master 0 | dst master 1| memory to memory | len bytes*/
CfgrParam = (1 << 7) | (16 << 12);
ProgramDMAChannel((UINT32) (pWritebuf + SECTOR_SIZE),NFLASH_NFDOUT_ADDR,
CtlrParam,CfgrParam);
#ifndef _STAND_ALONE_
{
UINT32 EventResult; /* The 32-bit variable to where the set bits is copied*/
UINT16 EventStatus; /* Event status*/
EventStatus = OS_DRIVER_WaitEventOR(PERIPH_EVENT_ID,PERIPH_DMA_EVTBIT,
&EventResult,NAND_DMA_TIMEOUT_VALUE);
if (EventStatus == OS_DRIVER_WAIT_EVENT_TIMEOUT)
{
DEBUG_OUT("Write NAND_DMA_TIMEOUT\n\r") ;
OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID);
return NAND_DMA_TIMEOUT;
}
}
#else
temp = READ_REG32(DMA_ISR_ADDR);
while ((temp & 0x4) == 0)//default to channel 2
{
temp = READ_REG32(DMA_ISR_ADDR);
TimeOut++ ;
if (TimeOut == NAND_TIMEOUT_VALUE)
{
WRITE_REG32(DMA_ISR_ADDR, 0x4);
OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID);
return NAND_DMA_TIMEOUT ;
}
}
WRITE_REG32(DMA_ISR_ADDR, 0x4);
#endif /*_STAND_ALONE_*/
}
#endif/* (DMA_TYPE==TYPE_IS_MOSE_DMA) */
OS_DRIVER_ReleaseSemaphore(DMA_SEMAPHORE_ID);
}
#else /*_NFLASH_DMA_*/
{
UINT8 mi,*pd;
UINT16 temp = SECTOR_SIZE>>4 ;
pd=(unsigned char *)pWritebuf;
mi=0;
do
{
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
}while((++mi)<temp);
GenerateEcc(&pWritebuf[SECTOR_SIZE]);
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
mNand_Write_Data(*pd++) ;
}
#endif /*_NFLASH_DMA_*/
mNandWrite_SET_CLE(PAGE_PRO_TRUE_CMD2);
if (!IsReadyToRW())
{
DEBUG_OUT("Write NAND_HW_ERR\n\r") ;
return NAND_HW_ERR ;
}
/*if failure it need to block placement*/
if (!IsSucessProgram())
{
DEBUG_OUT("Write NAND_PRG_FAIL\n\r") ;
return NAND_FAIL ;
}
#ifdef _NAND_VERIFY_WRITE_
{
UINT16 k;
NAND_PageReadWithEcc(udAddress,len,ReadBackBuf) ;
for (k = 0; k < len; k++)
{
if (ReadBackBuf[k] != pWritebuf[k])
{
DEBUG_OUT("Write NAND_VERIFY_ERR\n\r") ;
return NAND_VERIFY_ERR;
}
}
}
#endif/*_NAND_VERIFY_WRITE_*/
return NAND_PASS ;
}
/*********************************************************************************/
/******************************Interface to NFTL*************************************/
/*********************************************************************************/
void EnableNAND(void)
{
#ifdef NAND_POWER_SAVING
//NAND_ObtainSleepSema();
#endif /*NAND_POWER_SAVING*/
OS_DRIVER_ObtainSemaphore(NAND_SEMAPHORE_ID);
NFlashSelect() ;
#ifdef NAND_POWER_SAVING
EnableNANDClock();
EnableNANDControler();
#endif/*NAND_POWER_SAVING*/
}
void DisableNAND(void)
{
#ifdef NAND_POWER_SAVING
DisableNANDClock();
DisableNANDControler();
#endif /*NAND_POWER_SAVING*/
NFlashDeselect() ;
OS_DRIVER_ReleaseSemaphore(NAND_SEMAPHORE_ID);
#ifdef NAND_POWER_SAVING
//NAND_ReleaseSleepSema();
#endif /*NAND_POWER_SAVING*/
}
NAND_Ret NAND_Init(void)
{
UINT8 ErrorCode ;
//EnableNAND();
ErrorCode = HD_NFlashInit();
//DisableNAND();
return ErrorCode ;
}
NAND_Ret NAND_CopyBack(UINT32 udSourceAddr, UINT32 udDestinationAddr)
{
udSourceAddr &= 0x01ffff00 ;
udDestinationAddr &= 0x01ffff00 ;
mNandWrite_SET_CLE(COPY_BACK_PRO_TRUE_CMD1);
mNandWrite_SET_ALE(udSourceAddr) ;
if (!IsReadyToRW())
{
return NAND_HW_ERR ;
}
mNandWrite_SET_CLE(COPY_BACK_PRO_TRUE_CMD2);
mNandWrite_SET_ALE(udDestinationAddr) ;
mNandWrite_SET_CLE(COPY_BACK_PRO_TRUE_CMD3);
if (!IsReadyToRW())
{
return NAND_HW_ERR ;
}
/*if failure it need to block placement*/
return(IsSucessProgram()) ;
}
/******************************************************************************
NAND_BlockErase
Function: NAND_Ret NAND_BlockErase(udword udAddress)
Arguments: udAddress
The address inside the block to erase.
Return Value:
NAND_FLASH_SIZE_OVERFLOW:
The address is not within the flash
NAND_PASS
The operation are successfully executed
NAND_FAIL
The operation are not successfully executed,
Description: This function issue a Block Erase Command as explained in the
datasheet of the 528 byte/264 word page family.
******************************************************************************/
#if 0
NAND_Ret NAND_BlockErase(UINT32 udAddress)
{
UINT8 ErrorCode ;
//EnableNAND();
ErrorCode = NFlashBlockErase(udAddress);
//DisableNAND();
return ErrorCode ;
}
#endif
#if 0
NAND_Ret NAND_PageReadWithEcc(UINT32 udAddress, dataWidth *pReadBuf, UINT32 len)
{
UINT8 ErrorCode ;
// EnableNAND();
ErrorCode = NandReadWithEcc(udAddress,len,pReadBuf);
// DisableNAND();
return ErrorCode ;
}
#endif
#if 0
NAND_Ret NAND_PageProgramWithEcc(UINT32 udAddress, dataWidth *Buffer, UINT32 udLenght)
{
UINT8 ErrorCode ;
//EnableNAND();
ErrorCode = NandWriteWithEcc(udAddress,udLenght,Buffer);
//DisableNAND();
return ErrorCode ;
}
#endif
#if 0
NAND_Ret NAND_PageRead(UINT32 udAddress, dataWidth *pReadBuf, UINT32 len)
{
UINT8 ErrorCode ;
//EnableNAND();
ErrorCode = NandReadNoEcc(udAddress,len,pReadBuf);
//DisableNAND();
return ErrorCode ;
}
#endif
#if 0
NAND_Ret NAND_PageProgram(UINT32 udAddress, dataWidth *Buffer, UINT32 udLenght)
{
UINT8 ErrorCode ;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -