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

📄 tmbtnanddrv_write.c

📁 pnx8950 nand flash 驱动
💻 C
字号:
/*
                           SDK (Nand Driver)
                         -----------------------------


   Copyright (c) 2004 Koninklijke Philips Electronics N.V. All rights reserved

   This source code and any compilation or derivative thereof is the
   proprietary information of Koninklijke Philips Electronics N.V.
   and is confidential in nature.
   Under no circumstances is this software to be exposed to or placed
   under an Open Source License of any type without the expressed
   written permission of Koninklijke Philips Electronics N.V.

   COMPANY CONFIDENTIAL

Filename  :     tmbtNandDrv.c


Rev Date       Author      Comments
--------------------------------------------------------------------------------
001 04/10/2004 A Charrett  Original
002 25/05/2005 A Charrett  Update with new cache library names and macros.
003 13/09/2005 A Charrett  Update for 8bit flash
004 24/10/2005 burningh    Adding support for larger devices (4 addr cycles)
*/

/** Description

*/

/* Do not remove the following comments even if not applicable.
   This makes the fact explicit that for eg. there are no local typedefs,
   and allows consistant layout during maintenance phases     */

/*******************
* INCLUDE FILES    *
********************/
#include "tmbtNandDrv.h"
#include "tmbtNandDrv_internal.h"
#include "tmbtViper2.h"
#include "tmbtMips.h"

/*******************
* LOCAL MACROS     *
********************/
/** Dummy write to send the address we want to write to, to the nand flash */
#define SEND_NAND_ADDRESS(__naddrphys) (*((UInt16*)PHYS_TO_UNCACHED(__naddrphys))=0)

//#define SEND_NAND_ADDRESS(__naddrphys) (*((UInt16*)PHYS_TO_UNCACHED(__naddrphys))=0xFFFF) //added by lym
#define NAND_STATUS_PROGRAM_ERASE_M 0x01
#define NAND_STATUS_BUSY_M          0x40
#define NAND_STATUS_PROTECTED_M     0x80

/*******************
* EXPORTED DATA    *
********************/

/*******************
* LOCAL TYPEDEFS   *
********************/

/**********************
* FUNCTION PROTOTYPES *
***********************/

/*******************
* STATIC DATA      *
********************/

/***************************
* FUNCTION IMPLEMENTATIONS *
****************************/


/******************************************************************************/
/** +++ tmbtNandDrvWriteMainArea

    Write the data specified into the main page area of flash at the specified
    flash address.
    The amount of data written is specified by gtmbtNandDrvNumOfBytesMain.

    +++ Parameter         Flow    Description
        nandaddr          IN      Address in flash to write.
        dramaddr          IN      Address of data to write into flash.
                                  MUST be 32bit aligned.

    +++ Return value

    +++ Additional Notes

*/
/******************************************************************************/
tmErrorCode_t tmbtNandDrvWriteMainArea(UInt32 nandaddr, void * dramaddr)
{
   // print("test by lym!\n\r");   //added by lym
    tmErrorCode_t err = TM_OK;
    UInt32 nandPhys;
    UInt32 dramPhys;

    volatile UInt16 *pDummy, status;

    if ((nandaddr & (gtmbtNandDrvNumOfBytesMain - 1)) != 0)
    {
        err = TM_BT_ERR_NAND_DRV_INVALID_PARAMETER_UNALIGNED_NAND_ADDRESS;
        goto functionreturn;
    }
    if (((UInt32)dramaddr & 3) != 0)
    {
        err = TM_BT_ERR_NAND_DRV_INVALID_PARAMETER_UNALIGNED_RAM_ADDRESS;
        goto functionreturn;
    }
    if (nandaddr >= gtmbtNandDrvNumOfBytesDevice)
    {
        err = TM_BT_ERR_NAND_DRV_INVALID_PARAMETER_NAND_ADDRESS_TOO_HIGH;
        goto functionreturn;
    }

    if ((nandaddr + gtmbtNandDrvNumOfBytesMain) > gtmbtNandDrvNumOfBytesDevice)
    {
        err = TM_BT_ERR_NAND_DRV_INVALID_PARAMETER_LENGTH_TO_BIG;
        goto functionreturn;
    }
    nandPhys = VIRT_TO_PHYS(gptmbtNandDrvNandBase) + nandaddr;
    dramPhys = VIRT_TO_PHYS(dramaddr);


    cachePr4450DCFlush(dramaddr, gtmbtNandDrvNumOfBytesMain);

    XIO_REG(MMIO_GPXIO_INT_CLEAR) = GPXIO_XIO_ACK_DONE_M;

    NAND_CMD(1, 0, gtmbtNandDrv64MegDevice, NAND_CMD_READ_MAIN, 0);

   // SEND_NAND_ADDRESS(nandPhys);

    pDummy = (short *)((UInt32)gptmbtNandDrvNandBase + nandaddr); //added by lym
    status = *pDummy;   //added by lym


    NAND_CMD_WITH_DATA(2, gtmbtNandDrvAddressCyclesRW, gtmbtNandDrv64MegDevice, NAND_CMD_WRITE_A, NAND_CMD_WRITE_B);

    /** Transfer the data to the nand device */
    err = tmbtNandDrvDMA(dramPhys, nandPhys, gtmbtNandDrvNumOfBytesMain, 7);
    if (err == TM_BT_ERR_NAND_DRV_DMA_TIMEOUT)
    {
        goto functionreturn;
    }

    while((XIO_REG(MMIO_GPXIO_INT_STATUS) & GPXIO_XIO_ACK_DONE_M) == 0); /* Wait for the ACK signal */

    while((XIO_REG(MMIO_XIO_CTRL) & XIO_ACK_M) == 0); /* Wait for the ACK signal to not be live */

    NAND_CMD_WITH_DATA(1, 0, gtmbtNandDrv64MegDevice, NAND_CMD_READ_STATUS, 0);
    do
    {
#ifdef NAND16BIT
        status = *((unsigned short *)gptmbtNandDrvNandBase);
#else
        status = *((unsigned char *)gptmbtNandDrvNandBase);
#endif
        if ((status & NAND_STATUS_PROTECTED_M) == 0)
        {
            err = TM_BT_ERR_NAND_DRV_NAND_PROTECTED;
            goto functionreturn;
        }
    }while((status & NAND_STATUS_BUSY_M) == 0);

#ifdef NAND16BIT
    status = *((unsigned short *)gptmbtNandDrvNandBase);
#else
    status = *((unsigned char *)gptmbtNandDrvNandBase);
#endif
    if ((status & NAND_STATUS_PROGRAM_ERASE_M) == NAND_STATUS_PROGRAM_ERASE_M)
    {
        err = TM_BT_ERR_NAND_DRV_NAND_PROGRAM_ERASE_FAILED;
    }
functionreturn:
    return err;
}
/******************************************************************************/
/** +++ tmbtNandDrvWriteSpareArea

    Write the data specified into the spare/oob page area of flash at the specified
    flash address.
    The amount of data written is specified by gtmbtNandDrvNumOfBytesSpare.

    +++ Parameter         Flow    Description
        nandaddr          IN      Address in flash to write.
        dramaddr          IN      Address of data to write into flash.
                                  MUST be 32bit aligned.

    +++ Return value

    +++ Additional Notes

*/
/******************************************************************************/
tmErrorCode_t tmbtNandDrvWriteSpareArea(unsigned long nandaddr, void * dramaddr)
{
    tmErrorCode_t err = TM_OK;
    UInt32 nandPhys;
    UInt32 dramPhys;

    volatile UInt16 *pDummy, status;

    if (((UInt32)dramaddr & 3) != 0)
    {
        err = TM_BT_ERR_NAND_DRV_INVALID_PARAMETER_UNALIGNED_RAM_ADDRESS;
        goto functionreturn;
    }

    if (nandaddr >= gtmbtNandDrvNumOfBytesDevice)
    {
        err = TM_BT_ERR_NAND_DRV_INVALID_PARAMETER_NAND_ADDRESS_TOO_HIGH;
        goto functionreturn;
    }

    nandaddr = nandaddr & (~(gtmbtNandDrvNumOfBytesMain - 1)); /* align NAND offset to page start*/

    nandPhys = VIRT_TO_PHYS(gptmbtNandDrvNandBase) + nandaddr;
    dramPhys = VIRT_TO_PHYS(dramaddr);


    cachePr4450DCFlush(dramaddr, gtmbtNandDrvNumOfBytesSpare);

    XIO_REG(MMIO_GPXIO_INT_CLEAR) = GPXIO_XIO_ACK_DONE_M;

    NAND_CMD(1, 0, gtmbtNandDrv64MegDevice, NAND_CMD_READ_SPARE, 0);

    //SEND_NAND_ADDRESS(nandPhys);
    pDummy = (short *)((UInt32)gptmbtNandDrvNandBase + nandaddr); //added by lym
    status = *pDummy;   //added by lym

    

    NAND_CMD_WITH_DATA(2, gtmbtNandDrvAddressCyclesRW, gtmbtNandDrv64MegDevice, NAND_CMD_WRITE_A, NAND_CMD_WRITE_B);
    /** Transfer the data to the nand device */
    err = tmbtNandDrvDMA(dramPhys, nandPhys, gtmbtNandDrvNumOfBytesSpare, 7);
    if (err == TM_BT_ERR_NAND_DRV_DMA_TIMEOUT)
    {
        goto functionreturn;
    }

    while((XIO_REG(MMIO_GPXIO_INT_STATUS) & GPXIO_XIO_ACK_DONE_M) == 0); /* Wait for the ACK signal */

    while((XIO_REG(MMIO_XIO_CTRL) & XIO_ACK_M) == 0); /* Wait for the ACK signal to not be live */

    NAND_CMD_WITH_DATA(1, 0, gtmbtNandDrv64MegDevice, NAND_CMD_READ_STATUS, 0);
    do
    {
#ifdef NAND16BIT
        status = *((unsigned short *)gptmbtNandDrvNandBase);
#else
        status = *((unsigned char *)gptmbtNandDrvNandBase);
#endif
        if ((status & NAND_STATUS_PROTECTED_M) == 0)
        {
            err = TM_BT_ERR_NAND_DRV_NAND_PROTECTED;
            goto functionreturn;
        }
    }while((status & NAND_STATUS_BUSY_M) == 0);

#ifdef NAND16BIT
    status = *((unsigned short *)gptmbtNandDrvNandBase);
#else
    status = *((unsigned char *)gptmbtNandDrvNandBase);
#endif
    if ((status & NAND_STATUS_PROGRAM_ERASE_M) == NAND_STATUS_PROGRAM_ERASE_M)
    {
        err = TM_BT_ERR_NAND_DRV_NAND_PROGRAM_ERASE_FAILED;
    }
functionreturn:
    return err;
}
/******************************************************************************/
/** +++ tmbtNandDrvBlockErase

    Erase the specified block of flash memory

    +++ Parameter         Flow    Description
        nandaddr          IN      Address in flash to erase.

    +++ Return value

    +++ Additional Notes

*/
/******************************************************************************/
tmErrorCode_t tmbtNandDrvBlockErase(unsigned long nandaddr)
{
       // print("erase test by lym!\n\r" );  //added by lym
        tmErrorCode_t err = TM_OK;
        volatile UInt16 *pDummy, status;

       if (nandaddr >= gtmbtNandDrvNumOfBytesDevice)
        {
            err = TM_BT_ERR_NAND_DRV_INVALID_PARAMETER_NAND_ADDRESS_TOO_HIGH;
            goto functionreturn;
        }

        nandaddr = nandaddr & (~(gtmbtNandDrvNumOfBytesMain - 1)); /* align NAND offset to page start*/
        XIO_REG(MMIO_GPXIO_INT_CLEAR) = GPXIO_XIO_ACK_DONE_M;

        NAND_CMD(2, gtmbtNandDrvAddressCyclesBE, gtmbtNandDrv64MegDevice, NAND_CMD_ERASE_A, NAND_CMD_ERASE_B);


        /** Dummy read to send the address we want to write to, to the nand flash */
        pDummy = (short *)((UInt32)gptmbtNandDrvNandBase + nandaddr);
        status = *pDummy;

        while((XIO_REG(MMIO_GPXIO_INT_STATUS) & GPXIO_XIO_ACK_DONE_M) == 0); /* Wait for the ACK signal */

        while((XIO_REG(MMIO_XIO_CTRL) & XIO_ACK_M) == 0); /* Wait for the ACK signal to not be live */

        NAND_CMD_WITH_DATA(1, 0, gtmbtNandDrv64MegDevice, NAND_CMD_READ_STATUS,0);
        do
        {
#ifdef NAND16BIT
            status = *((unsigned short *)gptmbtNandDrvNandBase);
#else
            status = *((unsigned char *)gptmbtNandDrvNandBase);
#endif
            if ((status & NAND_STATUS_PROTECTED_M) == 0)
            {
                err = TM_BT_ERR_NAND_DRV_NAND_PROTECTED;
                goto functionreturn;
            }
        }while((status & NAND_STATUS_BUSY_M) == 0);

#ifdef NAND16BIT
        status = *((unsigned short *)gptmbtNandDrvNandBase);
#else
        status = *((unsigned char *)gptmbtNandDrvNandBase);
#endif
        if ((status & NAND_STATUS_PROGRAM_ERASE_M) == NAND_STATUS_PROGRAM_ERASE_M)
        {
            err = TM_BT_ERR_NAND_DRV_NAND_PROGRAM_ERASE_FAILED;
        }
    functionreturn:
        return err;
}

⌨️ 快捷键说明

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