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

📄 nandflash.c

📁 uCOS-II 2.8和uC-TCP/IP在ATMEL AT91SAM9261上移植
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ----------------------------------------------------------------------------
 *         ATMEL Microcontroller Software Support  -  ROUSSET  -
 * ----------------------------------------------------------------------------
 * Copyright (c) 2006, Atmel Corporation

 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the disclaimer below.
 *
 * - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the disclaimer below in the documentation and/or
 * other materials provided with the distribution.
 *
 * Atmel's name may not be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ----------------------------------------------------------------------------
 * File Name           : nandflash.c
 * Object              :
 * Creation            : NLe Sep 28th 2006
 *-----------------------------------------------------------------------------
 */

#include <includes.h>

#ifdef CFG_NANDFLASH

/*----------------------------------------------------------------------------*/
/* NAND Commands							      */
/*----------------------------------------------------------------------------*/
/* 8 bits devices */
#define WRITE_NAND_COMMAND(d) do{ *(volatile unsigned char *)((unsigned long)AT91C_SMARTMEDIA_BASE | AT91_SMART_MEDIA_CLE) = (unsigned char)(d); } while(0)
#define WRITE_NAND_ADDRESS(d) do{ *(volatile unsigned char *)((unsigned long)AT91C_SMARTMEDIA_BASE | AT91_SMART_MEDIA_ALE) = (unsigned char)(d); } while(0)
#define WRITE_NAND(d) do{ *(volatile unsigned char *)((unsigned long)AT91C_SMARTMEDIA_BASE) = (unsigned char)d; } while(0)
#define READ_NAND() ((unsigned char)(*(volatile unsigned char *)(unsigned long)AT91C_SMARTMEDIA_BASE))

/* 16 bits devices */
#define WRITE_NAND16(d) do{ *(volatile unsigned short *)((unsigned long)AT91C_SMARTMEDIA_BASE) = (unsigned short)d; } while(0)
#define READ_NAND16() ((volatile unsigned short)(*(volatile unsigned short *)(unsigned long)AT91C_SMARTMEDIA_BASE))

/*------------------------------------------------------------------------------*/
/* \fn    AT91F_NandInit							*/
/* \brief Initialize NandFlash informations					*/
/* 										*/
/* TCL_PAGE_BUF[1] = NF_NbBlocks						*/
/* TCL_PAGE_BUF[2] = NF_BlockSize						*/
/* TCL_PAGE_BUF[3] = NF_SectorSize						*/
/* TCL_PAGE_BUF[4] = NF_SpareSize						*/
/* TCL_PAGE_BUF[5] = NF_DataBusWidth						*/
/*------------------------------------------------------------------------------*/
static void AT91F_NandInit(PSNandInfo pNandInfo, PSNandInitInfo pNandInitInfo)
{
	unsigned int uSectorSize, i=0;

	pNandInfo->uNbBlocks 	  = pNandInitInfo->uNandNbBlocks;	/* Nb of blocks in device */
	pNandInfo->uBlockNbData	  = pNandInitInfo->uNandBlockSize;	/* Nb of DataBytes in a block */
	pNandInfo->uDataNbBytes	  = pNandInitInfo->uNandSectorSize;	/* Nb of bytes in data section */
	pNandInfo->uSpareNbBytes  = pNandInitInfo->uNandSpareSize;	/* Nb of bytes in spare section */
	pNandInfo->uSectorNbBytes = pNandInfo->uDataNbBytes +
								pNandInfo->uSpareNbBytes;	/* Total nb of bytes in a sector */

	pNandInfo->uBlockNbSectors = pNandInfo->uBlockNbData / pNandInfo->uDataNbBytes;		/* Nb of sector in a block */
	pNandInfo->uBlockNbSpares = pNandInfo->uSpareNbBytes * pNandInfo->uBlockNbSectors;	/* Nb of SpareBytes in a block */
	pNandInfo->uBlockNbBytes = pNandInfo->uSectorNbBytes * pNandInfo->uBlockNbSectors;	/* Total nb of bytes in a block */

	pNandInfo->uNbSectors = pNandInfo->uBlockNbSectors * pNandInfo->uNbBlocks;	/* Total nb of sectors in device */
	pNandInfo->uNbData = pNandInfo->uBlockNbBytes * pNandInfo->uNbBlocks;		/* Nb of DataBytes in device */
	pNandInfo->uNbSpares = pNandInfo->uBlockNbSpares * pNandInfo->uNbBlocks;	/* Nb of SpareBytes in device */
	pNandInfo->uNbBytes	= pNandInfo->uNbData + pNandInfo->uNbSpares;		/* Total nb of bytes in device */

	pNandInfo->uDataBusWidth = pNandInitInfo->uNandBusWidth;			/* Data Bus Width (8/16 bits) */
	
	
	uSectorSize = pNandInfo->uDataNbBytes - 1;
	pNandInfo->uOffset = 0;

	while (uSectorSize >> i)
	{
		pNandInfo->uOffset++;
		i++;
	}
}

/*------------------------------------------------------------------------------*/
/* \fn    AT91F_NandReadID							*/
/* \brief Read Nand ID								*/
/*------------------------------------------------------------------------------*/
static PSNandInitInfo AT91F_NandReadID(void)
{
	unsigned int uChipID, i=0;
	unsigned char bManufacturerID, bDeviceID;
	
	/* Enable chipset */
	NAND_ENABLE_CE();

	/* Ask the Nand its IDs */
	WRITE_NAND_COMMAND(CMD_READID);
	WRITE_NAND_ADDRESS(0x00);

	/* Read answer */
	bManufacturerID	= READ_NAND();
    	bDeviceID	= READ_NAND();

	/* Disable chipset before returning */
	NAND_DISABLE_CE();

	uChipID = (bManufacturerID << 8) | bDeviceID;
	
	/* Search in NandFlash_InitInfo[] */
	while (NandFlash_InitInfo[i].uNandID != 0)
	{
		if (NandFlash_InitInfo[i].uNandID == uChipID)
			return &NandFlash_InitInfo[i];	
	
		i++;
	}
	
	return 0;
}

/*------------------------------------------------------------------------------*/
/* \fn    AT91F_NandEraseBlock0							*/
/* \brief Erase Block 0								*/
/*------------------------------------------------------------------------------*/
BOOL AT91F_NandEraseBlock0(void)
{
	unsigned int uPhySecNb = 0;
	BOOL bRet = TRUE;

	/* Chip enable */
	NAND_ENABLE_CE();

	/* Push Erase_1 command */
	WRITE_NAND_COMMAND(CMD_ERASE_1);

	/* Push sector address in three cycles */
	WRITE_NAND_ADDRESS((uPhySecNb >>  0) & 0xFF);
	WRITE_NAND_ADDRESS((uPhySecNb >>  8) & 0xFF);
	WRITE_NAND_ADDRESS((uPhySecNb >> 16) & 0xFF);

	/* Push Erase_2 command */
	WRITE_NAND_COMMAND(CMD_ERASE_2);

	/* Wait for nand to be ready */
	NAND_WAIT_READY();
	NAND_WAIT_READY();
	
	/* Check status bit for error notification */
	WRITE_NAND_COMMAND(CMD_STATUS);
	NAND_WAIT_READY();
	if (READ_NAND() & STATUS_ERROR)
	{
		/* Error during block erasing */
		bRet = FALSE;
		goto exit;	
	}

exit:
	/* Chip disable */
	NAND_DISABLE_CE();

	return bRet;
}


#ifdef NANDFLASH_SMALL_BLOCKS
/*------------------------------------------------------------------------------*/
/* \fn    AT91F_NandReadSector							*/
/* \brief Read a Sector								*/
/*------------------------------------------------------------------------------*/
BOOL AT91F_NandReadSector(PSNandInfo pNandInfo, unsigned int uSectorAddr, char *pOutBuffer, unsigned int fZone)
{
	BOOL		bRet = TRUE;
	unsigned int	uBytesToRead, i;
	unsigned char   Cmd;

	/* WARNING : During a read procedure you can't call the ReadStatus flash cmd */
	/* The ReadStatus fill the read register with 0xC0 and then corrupt the read.*/

	/* Push offset address */
	switch(fZone)
	{
		case ZONE_DATA:
			uBytesToRead = pNandInfo->uDataNbBytes;
			Cmd = CMD_READ_A;
			break;
		case ZONE_INFO:
			uBytesToRead = pNandInfo->uSpareNbBytes;
			pOutBuffer += pNandInfo->uDataNbBytes;
			Cmd = CMD_READ_C;
			break;
		case ZONE_DATA | ZONE_INFO:
			uBytesToRead = pNandInfo->uSectorNbBytes;
			Cmd = CMD_READ_A;
			break;
		default:
			bRet = FALSE;
			goto exit;
	}

	/* Enable the chip */
	NAND_ENABLE_CE();

	/* Write specific command, Read from start */
	WRITE_NAND_COMMAND(Cmd);

	/* Push sector address */
	uSectorAddr >>= pNandInfo->uOffset;
		
	WRITE_NAND_ADDRESS(0x00);
	WRITE_NAND_ADDRESS((uSectorAddr >>  0) & 0xFF);
	WRITE_NAND_ADDRESS((uSectorAddr >>  8) & 0xFF);
	WRITE_NAND_ADDRESS((uSectorAddr >> 16) & 0xFF);

	/* Wait for flash to be ready (can't pool on status, read upper WARNING) */
	NAND_WAIT_READY();
	NAND_WAIT_READY();	/* Need to be done twice, READY detected too early the first time? */
	
	/* Read loop */
	if (pNandInfo->uDataBusWidth)
	{	/* 16 bits */
		for(i=0; i<uBytesToRead/2; i++) // Div2 because of 16bits
		{
			*((short*)pOutBuffer) = READ_NAND16();
			pOutBuffer+=2;
		}

⌨️ 快捷键说明

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