📄 c2188.c
字号:
#ifdef DMA_ENABLE
/* to be implemented */
#else
for(i=0;i<length;i++)
{
Buffer[i] = NAND_DataOutput();
}
#endif
SetLastAddressInCacheRead(GetLastAddressInCacheRead()+length);
return NAND_PASS;
}
/******************************************************************************
NAND_PageProgram function
Function: NAND_PageProgram(udword *udAddresses, dataWidth **Buffer,
ubyte numOfChunks, udword *udlength)
Arguments: udAddresses:
The addresses into the page to program.
Buffer:
Contains the source buffers with the data to program.
udlength:
length of the data pieces to program
Return Value: NAND_FLASH_SIZE_OVERFLOW:
The address is not within the flash
NAND_PAGE_OVERFLOW
Some data pieces exceed the page limit
NAND_PASS
The operation are successfully executed
NAND_DIFFERENT_PAGES
The addresses refer to different pages
NAND_FAIL
The operation are not successfully execute
Description: The PageProgram operation issue a PageProgram Command as
explained in the datasheet of the 2112 byte/1056 word page
family. It can performa page program with random data input
******************************************************************************/
NAND_Ret NAND_PageProgram(udword *udAddresses, dataWidth **Buffer,ubyte numOfChunks, uword *udlength) {
register udword udIndex;
ubyte i;
ubyte ubStatus;
uword index_next;
/* Control if the address is within the flash */
for(i=0;i<numOfChunks;i++)
{
if ( udAddresses[i] >= FLASH_SIZE )
return NAND_FLASH_SIZE_OVERFLOW;
/* check if there is an overflow in main or spare */
if ((udlength[i] & 0x8000) != 0) { /* IN SPARE */
if (( (udAddresses[i] & (0x000003FF<<SHIFT_A8)) + (udlength[i]&0x7FFF) ) > PAGE_SPARE_SIZE) return NAND_FAIL;
} else /* IN MAIN */
if ( ( (udAddresses[i] & (0x000003FF<<SHIFT_A8)) + udlength[i]) > PAGE_SIZE) return NAND_FAIL;
/* check if there is an overlapping */
for (index_next=i+1; index_next<numOfChunks; index_next++)
if ( ((udlength[i] & 0x8000) != 0) && ((udlength[index_next] & 0x8000) != 0) ) {
if ( ((udAddresses[i] & (0x000003FF<<SHIFT_A8))+(udlength[i]&0x7FFF) ) > (udAddresses[index_next] & (0x000003FF<<SHIFT_A8)) ) return NAND_FAIL;
} else {
if ( ((udlength[i] & 0x8000) == 0) && ((udlength[index_next] & 0x8000) == 0) ) {
if ( ((udAddresses[i] & (0x000003FF<<SHIFT_A8))+udlength[i]) > (udAddresses[index_next] & (0x000003FF<<SHIFT_A8)) ) return NAND_FAIL;
} else {
if ( ((udlength[i] & 0x8000) == 0) && ((udlength[index_next] & 0x8000) != 0) ){
if ( ((udAddresses[i] & (0x000003FF<<SHIFT_A8))+udlength[i]) > (udAddresses[index_next] & (0x000003FF<<SHIFT_A8))+PAGE_DATA_SIZE ) return NAND_FAIL;
} else
if ( ((udAddresses[index_next] & (0x000003FF<<SHIFT_A8))+udlength[index_next]) > (udAddresses[i] & (0x000003FF<<SHIFT_A8))+PAGE_DATA_SIZE ) return NAND_FAIL;
}
}
/* check if the addresses refer to the same page */
if( (udAddresses[i]&(0x0000FC00 << SHIFT_A8))!=(udAddresses[0]&(0x0000FC00 << SHIFT_A8)))
return NAND_DIFFERENT_PAGES;
}
NAND_Open();
for(i=0;i<numOfChunks;i++)
{
#ifdef DMA_ENABLE
/* to be implemented */
/* wait for availability of DMA channel */
#endif
if(i==0)
{
/* Issue Sequential data input command */
NAND_CommandInput((ubyte)0x80);
if((udlength[i]&0x8000)==0x8000){
InsertSpareAddress(udAddresses[i]);
}else{
InsertAddress(udAddresses[i]);
}
}
else
{
/*random data input command*/
NAND_CommandInput((ubyte)0x85);
/* Column Address Insertion */
if((udlength[i]&0x8000)==0x8000){
InsertColumnAddressSpare(udAddresses[i]);
}else
{
InsertColumnAddress(udAddresses[i]);
}
}
#ifdef DMA_ENABLE
/* to be implemented */
#else
/* Write the data to the internal buffer */
for (udIndex=0;udIndex<((0x7FFF)&udlength[i]);udIndex++)
NAND_DataInput( *( Buffer[i] + udIndex) );
#endif
}
#ifdef DMA_ENABLE
/* to be implemented */
/* wait for availability of DMA channel */
#endif
/* Issue the Program Command*/
NAND_CommandInput((ubyte)0x10);
/* Wait for ready */
ubStatus=waitForReady();
NAND_Close();
if( (ubStatus&(0x80))==0)
return ubStatus&(0x80);
return ubStatus&(0x01);
}
/************** NAND_PageProgram ***************/
/******************************************************************************
NAND_SpareProgram function
Function: NAND_SpareProgram(udword udAddress, dataWidth *Buffer,
udword udlength)
Arguments: udAddress:
The address into the page to program.
Buffer:
Contains the source buffer with the data to program.
udlength:
length of the data piece to program
Return Value: NAND_FLASH_SIZE_OVERFLOW:
The address is not within the flash
NAND_PAGE_OVERFLOW
Some data pieces exceed the page limit
NAND_PASS
The operation are successfully executed
NAND_FAIL
The operation are not successfully execute
Description: The SpareProgram operation issue a PageProgram Command as
explained in the datasheet of the 2112 byte/1056 word page
family in sapre area.
******************************************************************************/
NAND_Ret NAND_SpareProgram(udword udAddress, dataWidth *Buffer, udword udlength) {
register udword udIndex;
ubyte ubStatus;
udword colAddr=0;
/* Control if the address is within the flash*/
if ( udAddress >= FLASH_SIZE )
return NAND_FLASH_SIZE_OVERFLOW;
if (FLASH_WIDTH == 8) {
/*get the column address*/
colAddr=udAddress&(0x000007FF);
/*check that data fit in page*/
if((colAddr+udlength)>PAGE_SPARE_SIZE)
return NAND_PAGE_OVERFLOW;
} else {
/*get the column address*/
colAddr=udAddress&(0x000003FF);
/*check that data fit in page*/
if((colAddr+udlength)>PAGE_SPARE_SIZE)
return NAND_PAGE_OVERFLOW;
}
NAND_Open();
/* Issue Sequential data input command */
NAND_CommandInput((ubyte)0x80);
/*Insert Spare address*/
InsertSpareAddress(udAddress);
#ifdef DMA_ENABLE
/* to be implemented */
#else
/* Write the data to the internal buffer */
for (udIndex=0;udIndex<udlength;udIndex++)
NAND_DataInput(Buffer[udIndex]);
#endif
#ifdef DMA_ENABLE
/* to be implemented */
/* wait for availability of DMA channel */
#endif
/* Issue the Program Command*/
NAND_CommandInput((ubyte)0x10);
/* Wait for ready */
ubStatus=waitForReady();
NAND_Close();
if( (ubStatus&(0x80))==0)
return ubStatus&(0x80);
return ubStatus&(0x01);
}
/************** NAND_SpareProgram ***************/
/******************************************************************************
NAND_SpareRead
Function: NAND_Ret NAND_SpareRead(udword udAddress, dataWidth *Buffer,
udword udlength)
Arguments: udAddresses:
The address in the page where read.
Buffer:
Contains the destination buffer to store the data.
udLength:
length of the data pieces to read
Return Value: NAND_FLASH_SIZE_OVERFLOW:
The address is not within the flash
NAND_PAGE_OVERFLOW
Addres exceeds page size
NAND_WRONG_ADDRESS
The address is invalid
NAND_PASS
The operation are successfully executed
NAND_FAIL
The operation are not successfully execute
Description: The SapreRead operation issue a SpareRead Command as explained
in the datasheet of the 2112bytes/1056 word page family.
It can execute page read with random data output.
******************************************************************************/
NAND_Ret NAND_SpareRead(udword udAddress, dataWidth *Buffer, udword udlength)
{
volatile udword udIndex=0;
ubyte ubStatus;
uword i;
udword colAddr=0;
/* Control if the address is within the flash*/
if ( udAddress >= FLASH_SIZE )
return NAND_FLASH_SIZE_OVERFLOW;
if (FLASH_WIDTH == 8) {
/*get the column address*/
colAddr=udAddress&(0x000007FF);
/*check that data fit in page*/
if((colAddr+udlength)>PAGE_SPARE_SIZE)
return NAND_PAGE_OVERFLOW;
} else {
/*get the column address*/
colAddr=udAddress&(0x000003FF);
/*check that data fit in page*/
if((colAddr+udlength)>PAGE_SPARE_SIZE)
return NAND_PAGE_OVERFLOW;
}
NAND_Open();
/* page read command */
NAND_CommandInput((ubyte)0x00);
/* Insert Spare Address */
InsertSpareAddress(udAddress);
/* Leave Read Status Register mode */
NAND_CommandInput((ubyte)0x30);
/* Wait for ready */
ubStatus=waitForReady();
/* return read mode */
NAND_CommandInput((ubyte)0x00);
#ifdef DMA_ENABLE
/* to be implemented */
#else
/*read data*/
for(i=0;i<udlength;i++)
{
Buffer[udIndex++] = NAND_DataOutput();
}
#endif
#ifdef DMA_ENABLE
/* to be implemented */
/* wait for availability of DMA channel */
#endif
ubStatus=waitForReady();
NAND_Close();
/* Return Pass or Fail */
return (ubStatus&(0x01));
}
/******************************************************************************
NAND_CopyBack
Function: NAND_Ret NAND_CopyBack(udword udSourceAddr, udword udDestinationAddr,
uword *offsetInPage,uword *chunkSizes,
uword numOfChunks.dataWidth** Buffers)
Arguments: udSourceAddr:
The address of the source page to copy.
udDestinationAddr:
The address of the destination page.
offsetInPage:
the starting offsets of the pieces of data to copy
chunkSizes:
the size of each piece of data to copy
numOfChunks:
the number of the data pieces to copy
Buffers:
buffers of data to write
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.
NAND_WRONG_ADDRESS
The pages are not in the same half of the flash.
Description: This function issue a CopyBack Command as explained in the
datasheet of the 2112 byte/1056 word page family.
The function permits the copy back with random data input. in
this case the data inserted are all 1
******************************************************************************/
NAND_Ret NAND_CopyBack(udword udSourceAddr, udword udDestinationAddr,uword *offsetInPage,uword *chunkSizes,uword numOfChunks, dataWidth **Buffers)
{
ubyte ubStatus;
uword index,index_next;
NAND_Open();
/* Control if the address is within the flash*/
if ( (udSourceAddr >= FLASH_SIZE) ||
(udDestinationAddr >= FLASH_SIZE))
return NAND_FLASH_SIZE_OVERFLOW;
/*test if the addresses are at the start of the pages*/
if(((udSourceAddr&(0x000003FF<<SHIFT_A8))!=0)||((udDestinationAddr&(0x000003FF<<SHIFT_A8)!=0)))
return NAND_WRONG_ADDRESS;
/*test if the offset and corrispondent chnckSize are correct*/
for(index=0;index<numOfChunks;index++){
if ((chunkSizes[index] & 0x8000) != 0) {
if ( (offsetInPage[index]+(chunkSizes[index]&0x7FFF))>PAGE_SPARE_SIZE) return NAND_FAIL;
} else if ( (offsetInPage[index]+chunkSizes[index]) > PAGE_SIZE) return NAND_FAIL;
for (index_next=index+1; index_next<numOfChunks; index_next++)
if ( ((chunkSizes[index] & 0x8000) != 0) && ((chunkSizes[index_next] & 0x8000) != 0) ) {
if ( (offsetInPage[index]+(chunkSizes[index]&0x7FFF) ) > offsetInPage[index_next] ) return NAND_FAIL;
} else {
if ( ((chunkSizes[index] & 0x8000) == 0) && ((chunkSizes[index_next] & 0x8000) == 0) ) {
if ( (offsetInPage[index]+chunkSizes[index]) > offsetInPage[index_next] ) return NAND_FAIL;
} else {
if ( ((chunkSizes[index] & 0x8000) == 0) && ((chunkSizes[index_next] & 0x8000) != 0) )
if ( (offsetInPage[index]+chunkSizes[index]) > offsetInPage[index_next]+PAGE_DATA_SIZE ) return NAND_FAIL;
}
}
}
NAND_CommandInput((ubyte)0x00);
/*issue the source address */
InsertAddress(udSourceAddr);
/*read command for copy-back*/
NAND_CommandInput((ubyte)0x35);
/* Wait for ready */
ubStatus=waitForReady();
/* Issue Copy-Back Data Input Command*/
NAND_CommandInput((ubyte)0x85);
/*issue the destination address */
InsertAddress(udDestinationAddr);
/* Copy chncks into nand buffer with random data input*/
for (index=0; index<numOfChunks; index++){
/* insert random data input command */
NAND_CommandInput((ubyte)0x85);
/* Insert Column Address*/
if ((chunkSizes[index] & 0x8000) != 0) InsertColumnAddressSpare(offsetInPage[index]);
else InsertColumnAddress(offsetInPage[index]);
/* Write the data to the internal buffer */
for (index_next=0; index_next<(chunkSizes[index]&0x7FFF); index_next++)
NAND_DataInput( Buffers[index][index_next] );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -