📄 davincievm_nandflash.c
字号:
/*
* Copyright 2005 by Spectrum Digital Incorporated.
* All rights reserved. Property of Spectrum Digital Incorporated.
*
* Not for distribution.
*/
/*
* NAND Flash implementation
*
*/
#include "davincievm_nandflash.h"
/* ------------------------------------------------------------------------ *
* *
* NANDFLASH_waitWhileBusy( timeout ) *
* *
* Poll the external RDY/BSY pin *
* *
* ------------------------------------------------------------------------ */
Int16 NANDFLASH_waitWhileBusy( Uint32 timeout )
{
Uint32 timecount = 0;
/*
* Short delay to let Ready/Busy signal go low
*/
DAVINCIEVM_wait( 1000 );
/*
* Wait while the device is busy
*/
while( ( ( ! NANDFLASH_READ_RB ) && ( ++timecount < timeout ) ) );
if ( timecount == timeout )
return NANDFLASH_TIMEOUT;
else
return 0;
}
/* ------------------------------------------------------------------------ *
* *
* DAVINCIEVM_NANDFLASH_init( ) *
* Initialize the NAND Flash *
* *
* Note: *
* The Write Protect on the NAND Flash is disabled. This allows the *
* erase & write NAND flash to work. *
* *
* ------------------------------------------------------------------------ */
Int16 DAVINCIEVM_NANDFLASH_init( )
{
/*------------------------------------------------------------------*
* NAND FLASH CHIP TIMEOUT @ 594 MHz *
* *
* AEMIF.CLK freq = PLL1/6 = 594/6 = 99 MHz *
* AEMIF.CLK period = 1/99 MHz = 10.1 ns *
* *
*------------------------------------------------------------------*/
Uint32 acfg2 = 0
| ( 0 << 31 ) // selectStrobe
| ( 0 << 30 ) // extWait
| ( 1 << 26 ) // writeSetup // 10 ns
| ( 4 << 20 ) // writeStrobe // 40 ns
| ( 1 << 17 ) // writeHold // 10 ns
| ( 1 << 13 ) // readSetup // 10 ns
| ( 6 << 7 ) // readStrobe // 60 ns
| ( 1 << 4 ) // readHold // 10 ns
| ( 3 << 2 ) // turnAround // ?? ns
| ( 0 << 0 ) // asyncSize // 8-bit bus
;
DAVINCIEVM_EMIF_config( acfg2,
AEMIF_MAX_TIMEOUT_16BIT,
AEMIF_MAX_TIMEOUT_16BIT,
AEMIF_MAX_TIMEOUT_16BIT );
AEMIF_NANDFCR = 0x00000001;
/* ---------------------------------------------------------------- *
* *
* Note: If NANDFLASH_CE_DO_CARE is defined, then CE will be low *
* during read/write/erase operations. *
* *
* Else if NANDFLASH_CE_DO_NOT_CARE is defined, then CE will *
* only be low during accesses to the NAND Flash device. *
* *
* ---------------------------------------------------------------- */
NANDFLASH_ASSERT_CE( ); // Assert CE if needed
NANDFLASH_CLE( NANDFLASH_RESET ); // Reset NAND Flash
if ( NANDFLASH_waitWhileBusy( ( Uint32 )-1 ) ) // Wait while busy
return NANDFLASH_TIMEOUT;
NANDFLASH_DEASSERT_CE( ); // Deassert CE
return 0;
}
/* ------------------------------------------------------------------------ *
* *
* DAVINCIEVM_NANDFLASH_getTotalPages( ) *
* *
* Determine the total number of pages of NAND Flash *
* *
* ------------------------------------------------------------------------ */
Uint32 DAVINCIEVM_NANDFLASH_getTotalPages( )
{
Uint8 mfg_id;
Uint8 dev_id;
Uint32 total_pages = 0;
NANDFLASH_ASSERT_CE( ); // Assert CE if needed
NANDFLASH_CLE( NANDFLASH_READID ); // Issue Read ID command
NANDFLASH_ALE_1( 0 );
mfg_id = NANDFLASH_BASE_PTR; // Read MFG Id
dev_id = NANDFLASH_BASE_PTR; // Read Device Id
/*
* Compared MFG ID & Device ID to the supported devices
*/
if ( mfg_id == MFG_SAMSUNG )
{
if ( dev_id == DEV_K9F5608U0B )
total_pages = DEV_K9F5608U0B_PAGE_COUNT;
else if ( dev_id == DEV_K9F5608Q0B )
total_pages = DEV_K9F5608Q0B_PAGE_COUNT;
else if ( dev_id == DEV_K9F2808U0C )
total_pages = DEV_K9F2808U0C_PAGE_COUNT;
else if ( dev_id == DEV_K9K1208Q0C )
total_pages = DEV_K9K1208Q0C_PAGE_COUNT;
else if ( dev_id == DEV_SMCARD_128 )
total_pages = DEV_SMCARD_128_PAGE_COUNT;
}
else if( mfg_id==MFG_STMicroelectronics)
{
if ( dev_id == DEV_NAND512W3A )
total_pages = DEV_NAND512W3A_PAGE_COUNT;
}
NANDFLASH_DEASSERT_CE( ); // Deassert CE
return total_pages;
}
/* ------------------------------------------------------------------------ *
* *
* DAVINCIEVM_NANDFLASH_erase( start, block_count ) *
* *
* Erase the blocks of Flash memory *
* start = destination address [ block address ] *
* block_count = # of blocks [ 1 block = 16384 bytes ] *
* *
* Return: 0 pass *
* 1000 error *
* 2000 timeout *
* *
* ------------------------------------------------------------------------ */
Int16 DAVINCIEVM_NANDFLASH_erase( Uint32 start, Uint32 block_count )
{
Uint32 i;
Int16 bad_blocks = 0;
for ( i = 0 ; i < block_count ; i++ )
{
NANDFLASH_ASSERT_CE( ); // Assert CE if needed
NANDFLASH_CLE( NANDFLASH_ERASE ); // Erase block
NANDFLASH_ALE_3( start );
NANDFLASH_CLE( NANDFLASH_ERASE_CONFIRM ); // Confirm Erase
if ( NANDFLASH_waitWhileBusy( ( Uint32 )-1 ) ) // Wait while busy
{
NANDFLASH_DEASSERT_CE( );
return NANDFLASH_TIMEOUT; // Timeout Error
}
NANDFLASH_CLE( NANDFLASH_STATUS ); // Check erase status
if ( NANDFLASH_BASE_PTR & NANDFLASH_STATUS_ERROR )
bad_blocks++; // Increment # bad blocks
NANDFLASH_DEASSERT_CE( ); // Deassert CE
start += NANDFLASH_BLOCKSIZE; // Increment address
}
return bad_blocks;
}
/* ------------------------------------------------------------------------ *
* *
* DAVINCIEVM_NANDFLASH_readPage( src, dst, page_count ) *
* *
* Read data from NAND Flash by pages ( 512 bytes ) *
* *
* src = source address [ must be aligned to start of page ] *
* dst = destination address [ any address ] *
* page_count = # of pages [ a page is 512 bytes ] *
* *
* Note does not return spare array data *
* *
* Return: 0 pass *
* 2000 timeout *
* *
* ------------------------------------------------------------------------ */
Int16 DAVINCIEVM_NANDFLASH_readPage( Uint32 src, Uint32 dst, Uint32 page_count )
{
Uint32 i, j;
volatile Uint8* dst8 = ( volatile Uint8* )dst;
Uint8 spare[NANDFLASH_SPARESIZE];
for ( i = 0 ; i < page_count ; i++ )
{
NANDFLASH_ASSERT_CE( ); // Assert CE if needed
NANDFLASH_CLE( NANDFLASH_READ ); // Read page
NANDFLASH_ALE_4( src );
if ( NANDFLASH_waitWhileBusy( ( Uint32 )-1 ) ) // Wait while busy
{
NANDFLASH_DEASSERT_CE( );
return NANDFLASH_TIMEOUT; // Timeout Error
}
for ( j = 0 ; j < NANDFLASH_PAGESIZE ; j++ ) // Read main array
*dst8++ = NANDFLASH_BASE_PTR;
for ( j = 0 ; j < NANDFLASH_SPARESIZE ; j++ ) // Read spare array
spare[j] = NANDFLASH_BASE_PTR;
NANDFLASH_DEASSERT_CE( ); // Deassert CE
src += NANDFLASH_PAGESIZE; // Increment address
}
return 0;
}
/* ------------------------------------------------------------------------ *
* *
* DAVINCIEVM_NANDFLASH_writePage( src, dst, page_count ) *
* *
* Program NAND Flash. *
* src = source address [ any address ] *
* dst = destination address [ must be aligned to start of page ] *
* page_count = # of pages [ a page is 512 bytes ] *
* *
* Note does not program SPARE arrays *
* *
* Return: 0 pass *
* 1000 error *
* 2000 timeout *
* *
* ------------------------------------------------------------------------ */
Int16 DAVINCIEVM_NANDFLASH_writePage( Uint32 src, Uint32 dst, Uint32 page_count )
{
Uint32 i, j = 0;
volatile Uint8* src8 = ( volatile Uint8* )src;
Int16 bad_pages = 0;
for ( i = 0 ; i < page_count ; i++ )
{
NANDFLASH_ASSERT_CE( ); // Assert CE if needed
NANDFLASH_CLE( NANDFLASH_PROGRAM ); // Program page
NANDFLASH_ALE_4( dst );
for ( j = 0 ; j < NANDFLASH_PAGESIZE ; j++ ) // Write main array
NANDFLASH_BASE_PTR = *src8++;
NANDFLASH_CLE( NANDFLASH_PROGRAM_CONFIRM ); // Confirm Program
if ( NANDFLASH_waitWhileBusy( ( Uint32 )-1 ) ) // Wait while busy
{
NANDFLASH_DEASSERT_CE( );
return NANDFLASH_TIMEOUT; // Timeout Error
}
NANDFLASH_CLE( NANDFLASH_STATUS ); // Check erase status
if ( NANDFLASH_BASE_PTR & NANDFLASH_STATUS_ERROR )
bad_pages++; // Increment # bad blocks
NANDFLASH_DEASSERT_CE( ); // Deassert CE
dst += NANDFLASH_PAGESIZE; // Increment address
}
return bad_pages;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -