⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 davincievm_nandflash.c

📁 erase 讀寫nand flash
💻 C
字号:
/*
 *  Copyright 2005 by Spectrum Digital Incorporated.
 *  All rights reserved. Property of Spectrum Digital Incorporated.
 *
 *  Not for distrubition.
 */

/*
 *  NAND Flash implementation
 *
 */

#include "davincievm_nandflash.h"


inline void NANDFLASH_ECCStart (void) {
	AEMIF_NANDFCR |= (1<<8);
}

inline Uint32 NANDFLASH_ECCRead (void) {
	 return AEMIF_NANDECC2;
}

#if 0
inline void NANDFLASH_ECCStop (void) {
		AEMIF_NANDFCR &= ~(1<<8);
}
#endif

Int16 NANDFLASH_protect(Uint32 startBlkAddr, Uint32 endBlkAddr){
	NANDFLASH_ASSERT_CE;

    NANDFLASH_CLE = NANDFLASH_LOCK_BLOCK;
	/* Issue Unlock Start Block */

	NANDFLASH_DEASSERT_CE;

	return 0;
}

Int16 NANDFLASH_unProtect(Uint32 startBlkAddr, Uint32 endBlkAddr){

	NANDFLASH_ASSERT_CE;

	/* Issue Unlock Start Block */
    NANDFLASH_CLE = NANDFLASH_START_UNLOCK;
	NANDFLASH_ALE = startBlkAddr & 0xFF;
	NANDFLASH_ALE = (startBlkAddr >> 8);
	NANDFLASH_ALE = (startBlkAddr >> 16);

	/* Issue Unlock Start Block */
    NANDFLASH_CLE = NANDFLASH_END_UNLOCK;
	NANDFLASH_ALE = endBlkAddr & 0xFF;
	NANDFLASH_ALE = (endBlkAddr >> 8) & 0xFF;
	NANDFLASH_ALE = (endBlkAddr >> 16) & 0xFF;

	NANDFLASH_DEASSERT_CE;

	return 0;
}

/* ------------------------------------------------------------------------ *
 *  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 NANDFLASH_init( )
{
    /* ---------------------------------------------------------------- *
     *  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;

    /* Issue Reset command */
    NANDFLASH_CLE = NANDFLASH_RESET;

    /* Wait while the device is busy */
    if ( NANDFLASH_pollBusyBit( ( Uint32 )-1 ) )
        return NANDFLASH_TIMEOUT;

    NANDFLASH_DEASSERT_CE;

    return 0;
}

/* ------------------------------------------------------------------------ *
 *  NANDFLASH_pollBusyBit( timeout )                                        *
 *      Poll the external RDY/BSY pin                                       *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Int16 NANDFLASH_pollBusyBit( Uint32 timeout )
{
    Uint32 timecount = 0;

    /* Short delay to let Ready/Busy signal go low */
    sw_wait( 200 );

    /* Wait while the device is busy */
    while( ( ( ! NANDFLASH_READ_RB ) && ( ++timecount < timeout ) ) );

    if ( timecount == timeout )
        return NANDFLASH_TIMEOUT;
    else
        return 0;
}

/* ------------------------------------------------------------------------ *
 *  NANDFLASH_getTotalPages( )                                              *
 *                                                                          *
 *      Determine the total number of pages of NAND Flash                   *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Uint32 NANDFLASH_getTotalPages( )
{
    Uint8 mfg_id;
    Uint8 dev_id;
    Uint32 total_pages = 0;

    NANDFLASH_ASSERT_CE;

    /* Issue ReadID command */
    NANDFLASH_CLE = NANDFLASH_READID;
    NANDFLASH_ALE_1( 0 );

    /* Read Mfg ID followed by Device ID */
    mfg_id = NANDFLASH_BASE_PTR;
    dev_id = NANDFLASH_BASE_PTR;

    /* Validate MFG ID & Device ID from 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 == 0x20 )
	{
		if ( dev_id == 0x36 )
            total_pages = DEV_K9K1208Q0C_PAGE_COUNT;
	}
    NANDFLASH_DEASSERT_CE;

    return total_pages;
}


/* ------------------------------------------------------------------------ *
 *  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 NANDFLASH_erase( Uint32 start, Uint32 block_count )
{
    Uint32 i;

    for ( i = 0 ; i < block_count ; i++ )
    {
        NANDFLASH_ASSERT_CE;

        /* Issue the Erase command  */
        NANDFLASH_CLE = NANDFLASH_ERASE;
        NANDFLASH_ALE_3( start );
        NANDFLASH_CLE = NANDFLASH_ERASE_CONFIRM;

        /* Wait while the device is busy */
        if ( NANDFLASH_pollBusyBit( ( Uint32 )-1 ) )
        {
            NANDFLASH_DEASSERT_CE;
            return NANDFLASH_TIMEOUT;
        }

        /* Verify a successful erase operation */
        NANDFLASH_CLE = NANDFLASH_STATUS;
        if ( NANDFLASH_BASE_PTR & NANDFLASH_STATUS_ERROR )
        {
            NANDFLASH_DEASSERT_CE;
            return NANDFLASH_ERROR;
        }

        NANDFLASH_DEASSERT_CE;

        /* Increment start address */
        start += NANDFLASH_BLOCKSIZE;
    }
    return 0;
}


/* ------------------------------------------------------------------------ *
 *  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 NANDFLASH_readPage( Uint32 src, Uint32 dst, Uint32 page_count )
{
    Uint32 i, j;
	Uint32 ecc, spareEcc;
    volatile Uint8* dst8 = ( volatile Uint8* )dst;
    Uint8 spare;

    for ( i = 0 ; i < page_count ; i++ )
    {
        NANDFLASH_ASSERT_CE;

        /* Issue the Read command */
        NANDFLASH_CLE = NANDFLASH_READ;
        NANDFLASH_ALE_4( src );

        /* Wait while the device is busy */
        if ( NANDFLASH_pollBusyBit( ( Uint32 )-1 ) )
        {
            NANDFLASH_DEASSERT_CE;
            return NANDFLASH_TIMEOUT;
        }

		NANDFLASH_ECCRead();
		NANDFLASH_ECCStart();

        /* Read main array */
        for ( j = 0 ; j < NANDFLASH_PAGESIZE ; j++ )
            *dst8++ = NANDFLASH_BASE_PTR;

		/* Read ECC & compare with what's in the spare area */
		ecc = NANDFLASH_ECCRead() & 0x0FFF0FFF;

		spareEcc = (NANDFLASH_BASE_PTR & 0xFF) << 24;
		spareEcc |= (NANDFLASH_BASE_PTR & 0xFF) << 16;
		spareEcc |= (NANDFLASH_BASE_PTR & 0xFF) << 8;
		spareEcc |= (NANDFLASH_BASE_PTR & 0xFF);

		spareEcc &= 0x0FFF0FFF;

        /* Read the remaining spare array & ignore data */
        for ( j = 4 ; j < NANDFLASH_SPARESIZE ; j++ )
		{
            spare = NANDFLASH_BASE_PTR;
			spare = spare;
		}

		if(spareEcc != ecc)
		{
			printf("    Error in ECC Compare - ECC=0x%x SpareECC=0x%x @ page %d\n", ecc, spareEcc, i);
		}

        NANDFLASH_DEASSERT_CE;

        /* Increment src address */
        src += NANDFLASH_PAGESIZE;
    }

    return 0;
}

/* ------------------------------------------------------------------------ *
 *  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 NANDFLASH_writePage( Uint32 src, Uint32 dst, Uint32 page_count )
{
    Uint32 i, j = 0;
	Uint32 ecc = 0;
    volatile Uint8* src8 = ( volatile Uint8* )src;

    for ( i = 0 ; i < page_count ; i++ )
    {
        NANDFLASH_ASSERT_CE;

        /* Set pointer to the main array & issue program command */
        NANDFLASH_CLE = NANDFLASH_PROGRAM;
        NANDFLASH_ALE_4( dst );

		NANDFLASH_ECCRead();
		NANDFLASH_ECCStart();

        /* Write from the src address to the page register */
        for ( j = 0 ; j < NANDFLASH_PAGESIZE; j++ )
            NANDFLASH_BASE_PTR = *src8++;

		/* Read ECC & write to the spare area */
		ecc = NANDFLASH_ECCRead() & 0x0FFF0FFF;

		NANDFLASH_BASE_PTR = (ecc >> 24) & 0xFF;
		NANDFLASH_BASE_PTR = (ecc >> 16) & 0xFF;
		NANDFLASH_BASE_PTR = (ecc >> 8) & 0xFF;
		NANDFLASH_BASE_PTR = (ecc) & 0xFF;

		for ( j = 4 ; j < NANDFLASH_SPARESIZE; j++ )
            NANDFLASH_BASE_PTR = 0xFF;

        /* Execute program operation */
        NANDFLASH_CLE = NANDFLASH_PROGRAM_CONFIRM;

        /* Wait while the device is busy */
        if ( NANDFLASH_pollBusyBit( ( Uint32 )-1 ) )
        {
            NANDFLASH_DEASSERT_CE;
            return NANDFLASH_TIMEOUT;
        }

        /* Verify a successful programming operation */
        NANDFLASH_CLE = NANDFLASH_STATUS;
        if ( NANDFLASH_BASE_PTR & NANDFLASH_STATUS_ERROR )
        {
            NANDFLASH_DEASSERT_CE;
            return NANDFLASH_ERROR;
        }

        NANDFLASH_DEASSERT_CE;

        /* Increment dst address */
        dst += NANDFLASH_PAGESIZE;
    }
    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -