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

📄 nandflash.c

📁 uCOS-II 2.8和uC-TCP/IP在ATMEL AT91SAM9261上移植
💻 C
📖 第 1 页 / 共 2 页
字号:
	} else {
		for(i=0; i<uBytesToRead; i++)
		{
			*pOutBuffer = READ_NAND();
			pOutBuffer++;
		}
	}

exit:
	/* Disable the chip */
	NAND_DISABLE_CE();

	return bRet;
}

#else /* NANDFLASH_LARGE_BLOCKS */

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

	/* 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.*/

	/* Enable the chip */
	NAND_ENABLE_CE();

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

	/* Push offset address */
	switch(fZone)
	{
		case ZONE_DATA:
			uBytesToRead = pNandInfo->uDataNbBytes;
			WRITE_NAND_ADDRESS(0x00);
			WRITE_NAND_ADDRESS(0x00);
			break;
		case ZONE_INFO:
			uBytesToRead = pNandInfo->uSpareNbBytes;
			pOutBuffer += pNandInfo->uDataNbBytes;
			if (pNandInfo->uDataBusWidth)
			{	/* 16 bits */
				WRITE_NAND_ADDRESS(((pNandInfo->uDataNbBytes/2) >>  0) & 0xFF); /* Div 2 is because we address in word and not
				in byte */
				WRITE_NAND_ADDRESS(((pNandInfo->uDataNbBytes/2) >>  8) & 0xFF);
			} else { /* 8 bits */
				WRITE_NAND_ADDRESS((pNandInfo->uDataNbBytes >>  0) & 0xFF);
				WRITE_NAND_ADDRESS((pNandInfo->uDataNbBytes >>  8) & 0xFF);			
			}
			break;
		case ZONE_DATA | ZONE_INFO:
			uBytesToRead = pNandInfo->uSectorNbBytes;
			WRITE_NAND_ADDRESS(0x00);
			WRITE_NAND_ADDRESS(0x00);
			break;
		default:
			bRet = FALSE;
			goto exit;
	}

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

	WRITE_NAND_COMMAND(CMD_READ_2);

	/* 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;
		}
	} else {
		for(i=0; i<uBytesToRead; i++)
		{
			*pOutBuffer++ = READ_NAND();
		}
	}

exit:
	/* Disable the chip */
	NAND_DISABLE_CE();

	return bRet;
}
#endif

/*------------------------------------------------------------------------------*/
/* \fn    AT91F_NandRead							*/
/* \brief Read Sector Algorithm							*/
/*------------------------------------------------------------------------------*/
static BOOL AT91F_NandRead(PSNandInfo pNandInfo, unsigned int uBlockNb, unsigned int uSectorNb, unsigned int uSpareValue, char *pOutBuffer)
{
	PSSectorInfo pSectorInfo;
	unsigned int uSectorAddr = uBlockNb * pNandInfo->uBlockNbData + uSectorNb * pNandInfo->uDataNbBytes;

	/* If uSectorNb = 0 -> First sector of the Block so read Spare bytes */
	if (!uSectorNb)
	{
		/* Read First Page Spare zone */
		AT91F_NandReadSector(pNandInfo, uSectorAddr, pOutBuffer, ZONE_INFO);
		pSectorInfo = (PSSectorInfo)&pOutBuffer[pNandInfo->uDataNbBytes];
		if (pSectorInfo->bBadBlock != 0xFF)
		{
			return FALSE;
		}
		
		/* Read Second Page Spare zone */
		AT91F_NandReadSector(pNandInfo, uSectorAddr + pNandInfo->uDataNbBytes, pOutBuffer, ZONE_INFO);
		pSectorInfo = (PSSectorInfo)&pOutBuffer[pNandInfo->uDataNbBytes];
		if (pSectorInfo->bBadBlock != 0xFF)
		{
			return FALSE;
		}	
	}

	return AT91F_NandReadSector(pNandInfo, uSectorAddr, pOutBuffer, ZONE_DATA);
}

/*------------------------------------------------------------------------------*/
/* \fn    load_nandflash							*/
/* \brief load from nandflash 							*/
/*------------------------------------------------------------------------------*/
int load_nandflash(unsigned int img_addr, unsigned int img_size, unsigned int img_dest)
{
	SNandInfo sNandInfo;
	PSNandInitInfo pNandInitInfo;
	unsigned char *pOutBuffer = (unsigned char*)img_dest;
	unsigned int blockIdx, badBlock, blockRead, length, sizeToRead, nbSector, newBlock, sectorIdx, blockError, sectorSize;

	nandflash_hw_init();
	
	/* Read Nand Chip ID */
    	pNandInitInfo = AT91F_NandReadID();

	if (!pNandInitInfo)
 	{
#ifdef CFG_DEBUG	
	   	dbg_print("\n\r-E- No NandFlash detected !!!\n\r");
#endif
		return -1;
    	}

	/* Initialize NandInfo Structure */
	AT91F_NandInit(&sNandInfo, pNandInitInfo);

	if (sNandInfo.uDataBusWidth)
		nandflash_cfg_16bits_dbw_init();

    	/* Initialize the block offset */
    	blockIdx = img_addr / sNandInfo.uBlockNbData;
	/* Initialize the number of bad blocks */
    	badBlock = 0;
	blockRead = 0;
    
	length = img_size;
    
	while (length > 0)
	{
        	/* Read a buffer corresponding to a block in the origin file */
		if (length < sNandInfo.uBlockNbData)
		{
			sizeToRead = length;
		}
		else
		{
			sizeToRead = sNandInfo.uBlockNbData;
		}

		/* Adjust the number of sectors to read */
        	nbSector = sizeToRead / sNandInfo.uDataNbBytes;
        	if (sizeToRead % sNandInfo.uDataNbBytes)
		{
            		nbSector++;
        	}

        	newBlock = 1;
		/* Loop until a valid block has been read */
		while (newBlock == 1)
		{
			/* Reset the error flag */
			blockError = 0;
            
			/* Read the sectors */
			for (sectorIdx=0; (sectorIdx < nbSector) && (blockError == 0); sectorIdx++)
			{
				sectorSize = sizeToRead - (sectorIdx * sNandInfo.uDataNbBytes);
				if (sectorSize < sNandInfo.uDataNbBytes)
				{
					sectorSize = sizeToRead - (sectorIdx * sNandInfo.uDataNbBytes);
				}
				else
				{
					sectorSize = sNandInfo.uDataNbBytes;
				}

	                	/* Read the sector */
        	        	if (AT91F_NandRead(&sNandInfo, blockIdx, sectorIdx, ZONE_DATA, pOutBuffer) == FALSE)
				{
					blockError = 1;
				}
				else
				{
					pOutBuffer+=sNandInfo.uDataNbBytes;
				}
			}
            
			if (blockError == 0)
			{
                		/* If the block is valid exit */
	                	newBlock = 0;
        	    	}
			blockIdx++;
		}

        	/* Decrement length */
	        length -= sizeToRead;
		blockRead++;
	}

	return 0;
}
#endif

⌨️ 快捷键说明

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