📄 tmbtnanddrv_write.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 + -