📄 hardwareadaptationlayer.c
字号:
currentDevice->pagesInBlock = 32;
currentDevice->manCode = 0xec;
currentDevice->devCode = 0x76;
currentDevice->numOfBlocks = 4096;
currentDevice->mainSize = 512;
currentDevice->spareSize = 16;
currentDevice->pageSize = 528;
currentDevice->planNumber = 2;
currentDevice->deviceFamily = 512;
currentDevice->devicesNumber = 1;
currentDevice->busWidth = 8;
return SUCCESS;
}
//******************************************************************************
// GetDeviceArchitecture
//******************************************************************************
//Retrieve the nand device detail an fill a DeviceArchitecture struct with them
//-----------------------------------------------------------------------------
// PARAMETERS:
// deviceArchitecture : the struct that will contains the device details
//*****************************************************************************
DeviceArchitecture GetDeviceArchitecture()
{
DeviceArchitecture devArch;
devArch.blockSize = currentDevice->blockSize;
devArch.pagesInBlock = currentDevice->pagesInBlock;
devArch.manCode = currentDevice->manCode;
devArch.devCode = currentDevice->devCode;
devArch.numOfBlocks = currentDevice->numOfBlocks;
devArch.mainSize = currentDevice->mainSize;
devArch.spareSize = currentDevice->spareSize;
devArch.pageSize = currentDevice->mainSize + currentDevice->spareSize;
devArch.planNumber = currentDevice->planNumber;
devArch.deviceFamily = currentDevice->deviceFamily;
devArch.devicesNumber = currentDevice->devicesNumber;
devArch.busWidth = currentDevice->busWidth;
return devArch;
}
//******************************************************************************
// CalculateChunkPosition
//******************************************************************************
// Retrieve the position of a chunk in the write buffer
//******************************************************************************
// PARAMETERS:
// blockNumber: the block physical number
// pageNumber : the number of page containing the chunk
// pageOffset : it will contains the offset of the page in the buffer array
// chunkPosition : it will contains the position of the chunk in the chunk array
//
// RETURN VALUES:
// SUCCESS : no problem have occurs
// WRONG_ADDRESS : the address is not in the device
// FAILURE : the chunk is not present in buffer
//*********************************************************************************
NFTL_Return CalculateChunkPosition(UINT16 blockNumber, UINT8 pageNumber,
UINT8 *pageOffset, UINT8 *chunkPosition)
{
if (pageNumber >=
currentDevice->pagesInBlock * (currentDevice->mainSize / CHUNK_DATA_SIZE))
{
return WRONG_ADDRESS;
}
//calculate the physical page number containing the chunk pageNumber
if (pageNumber <= ((currentDevice->pageSize / CHUNK_SIZE) - 1))
{
*pageOffset = 0;
*chunkPosition = pageNumber;
return SUCCESS;
}
else
{
*pageOffset = pageNumber / (currentDevice->pageSize / CHUNK_SIZE);
*chunkPosition = pageNumber -
(currentDevice->pageSize / CHUNK_SIZE) * (*pageOffset);
return SUCCESS;
}
return FAILURE;
}
NFTL_Return Unmount_HAL()
{
#if 0
int i;
if (UD_BUFFER_ENABLED)
{
if (WDBuffer != NULL)
{
for (i = 0; i < UD_BUFFER_SIZE / CHUNK_SIZE; i++)
{
if (WDBuffer->Buffer[i] != NULL)
{
OS_DRIVER_Free(WDBuffer->Buffer[i]);
WDBuffer->Buffer[i] = NULL;
}
}
if (WDBuffer->Buffer != NULL)
{
OS_DRIVER_Free(WDBuffer->Buffer);
WDBuffer->Buffer = NULL;
}
if (WDBuffer->ChunkStatus != NULL)
{
OS_DRIVER_Free(WDBuffer->ChunkStatus);
WDBuffer->ChunkStatus = NULL;
}
if (WDBuffer->PageNumber != NULL)
{
OS_DRIVER_Free(WDBuffer->PageNumber);
WDBuffer->PageNumber = NULL;
}
OS_DRIVER_Free(WDBuffer);
WDBuffer = NULL;
}
}
#endif
return SUCCESS;
}
//***********************************************************************************
// FlushBuffer *
//***********************************************************************************
// Flush the write buffer *
//----------------------------------------------------------------------------------*
// On error (FLUSH_ERROR) do not empty the buffer for future recovery *
// RETURN VALUES: *
// SUCCESS : flush executed without errors *
// FLUSH_ERROR : error during cache program, ChunkWithError in WDBuffer contain *
// the page number where programming is failed *
// FAILURE : error in program of page,ChunkWithError in WDBuffer contain *
// the page number where programming is failed *
//***********************************************************************************
NFTL_Return FlushBuffer(void)
{
//buffer not allocated
//return
if (WDBuffer == NULL)
return SUCCESS;
{
INT32 i;
for (i = 0; i < WDBuffer->NoOfSequentialWrite; i++)
{
UINT32 address;
NFTL_Return returnValue;
CalculateAddress(WDBuffer->LastBlock, WDBuffer->PageNumber[i], &address);
//execute the page program
returnValue = NAND_PageProgramWithEcc(address, WDBuffer->Buffer[i],
currentDevice->pageSize);
if (returnValue != NAND_PASS)
{
WDBuffer->ChunkWithError = i;
return FLUSH_ERROR;
}
}
}
WDBuffer->LastBlock = -1;
ResetWriteBuffer();
return SUCCESS;
}
INT8 FirstFreePageInBuffer()
{
INT8 i;
for (i = 0; i < WDBuffer->NoOfPages; i++)
{
if (WDBuffer->PageNumber[i] == -1)
return i;
}
//no OS_Free page
return -1;
}
//********************************************************************************
// Write528Cached *
//********************************************************************************
// Execute page program in device with 528 bytes page size when write buffering *
// is enabled *
//********************************************************************************
// PARAMETERS: *
// BlockNumber : number of block where write *
// PageNumber : number of page where write *
// buffer : number of page where write *
//********************************************************************************
NFTL_Return Write528Cached(UINT16 BlockNumber, UINT8 PageNumber, UINT8 *buffer)
{
NFTL_Return ret;
if (WDBuffer->LastBlock == -1)
{
WriteChunkInBuffer(0, PageNumber, BlockNumber, buffer, CHUNK_SIZE, 0, 0);
return SUCCESS;
}
//buffer must be flushed
if (WDBuffer->LastBlock != BlockNumber)
{
ret = FlushBuffer();
if (ret != SUCCESS)
return ret;
WriteChunkInBuffer(0, PageNumber, BlockNumber, buffer, CHUNK_SIZE, 0, 0);
return SUCCESS;
}
else
{
//check if page is yet present in buffer
INT8 pageNum;
pageNum = IsPageInBuffer(PageNumber);
//page is in buffer
if (pageNum != -1)
{
OS_MemCopy((WDBuffer->Buffer[pageNum]) , buffer, CHUNK_SIZE);
return SUCCESS;
}
else
{
pageNum = FirstFreePageInBuffer();
//there is no space in buffer
if (pageNum == -1)
{
ret = FlushBuffer();
if (ret != SUCCESS)
return ret;
pageNum = 0;
}
}
WriteChunkInBuffer(pageNum, PageNumber, BlockNumber, buffer, CHUNK_SIZE, 0, pageNum);
}
return SUCCESS;
}
//******************************************************************************
// WriteSpare528
//******************************************************************************
// Exexute the write of spare area in page of 528 bytes size
//--------------------------------------------------------------------------------
// PARAMETERS: *
// BlockNumber: block number where the spare to write is *
// PageNumber: the number of page to write *
// buffer: contains data to write *
// *
// RETURN VALUES: *
// SUCCESS : read executed correctly *
// FAILURE : error during read *
// FLUSH_ERROR : error during buffer flush *
//******************************************************************************
NFTL_Return WriteSpare528(UINT16 BlockNumber, UINT8 PageNumber, UINT8 *buffer)
{
UINT32 returnAddress;
#if 0
if (UD_BUFFER_ENABLED)
{
//buffer is empty
if (WDBuffer->LastBlock == -1)
{
WriteChunkInBuffer(0, PageNumber, BlockNumber, buffer, CHUNK_SIZE,
currentDevice->mainSize, 0);
return SUCCESS;
}
//buffer must be flushed
if (WDBuffer->LastBlock != BlockNumber)
{
NFTL_Return ret;
ret = FlushBuffer();
if (ret != SUCCESS)
return ret;
WriteChunkInBuffer(0, PageNumber, BlockNumber, buffer, CHUNK_SIZE,
currentDevice->mainSize, 0);
return SUCCESS;
}
else
{
//check if page is yet present in buffer
INT8 pageNum;
pageNum = IsPageInBuffer(PageNumber);
if (pageNum != -1)
{
NFTL_Return ret;
ret = FlushBuffer();
if (ret != SUCCESS)
return ret;
}
WriteChunkInBuffer(WDBuffer->NoOfSequentialWrite, PageNumber, BlockNumber, buffer,
CHUNK_SIZE, currentDevice->mainSize, 0);
//buffer is full,flush the buffer
if (WDBuffer->NoOfSequentialWrite == WDBuffer->NoOfChunks)
{
return FlushBuffer();
}
return SUCCESS;
}
}
#endif
//CalculateAddress(BlockNumber,PageNumber,&returnAddress) ;
returnAddress = mCalculateAddress(BlockNumber,PageNumber) ;
if (NAND_SpareProgram(returnAddress,buffer,CHUNK_SPARE_SIZE) != NAND_PASS)
{
return FAILURE;
}
return SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -