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

📄 nand.c

📁 支持大页面的nand flash的类库, 可由用户自由定制。
💻 C
📖 第 1 页 / 共 2 页
字号:
	 *    block			block no
	 * Return
	 *    error code
	 */
	BOOL Nand_EraseBlock(BLOCK_ID block)
	{
		BYTE status;
		DWORD page;
		
		page = BLOCK_TO_PAGE(block);
		
		NF_nFCE_L();
		
		NF_CMD(CMD_BlockErase_1st);
		NF_ADDR_ROW(page);
		NF_CMD(CMD_BlockErase_2nd);
		
		NF_WAIT_RnB();
		
		NF_READ_STATUS(status);
		
		NF_nFCE_H();
		
		return NF_STATUS_FAILED(status) ? FALSE : TRUE;
	}
	
	//
	//  Nand_GetBlockStatus
	//
	//  Returns the status of a block.  The status information is stored in the spare area of the first sector for
	//  the respective block.
	//
	//  A block is BAD if the bBadBlock byte on the first page is not equal to 0xff.
	//
	DWORD Nand_GetBlockStatus(BLOCK_ID blockID)
	{
	    SECTOR_ADDR sectorAddr = BLOCK_TO_PAGE(blockID);
	    SectorInfo SI;
	    DWORD dwResult = 0;
	
		if(!Nand_ReadPageSpare(sectorAddr, &SI, sizeof(SI)))
		{
	        return BLOCK_STATUS_UNKNOWN;
		}
	
	    if(!(SI.bOEMReserved & OEM_BLOCK_READONLY))
		{
	        dwResult |= BLOCK_STATUS_READONLY;
		}
	    
	    if(!(SI.bOEMReserved & OEM_BLOCK_RESERVED))
	    {
	    	dwResult |= BLOCK_STATUS_RESERVED;
	    }
	
	    if(SI.bBadBlock != 0xFF)
		{
	        dwResult |= BLOCK_STATUS_BAD;
		}
	
	    return dwResult;
	}
	
	//
	//  Nand_SetBlockStatus
	//
	//  Sets the status of a block.  Only implement for bad blocks for now.
	//  Returns TRUE if no errors in setting.
	//
	BOOL Nand_SetBlockStatus(BLOCK_ID blockID, DWORD dwStatus)
	{
		if (dwStatus & (BLOCK_STATUS_READONLY | BLOCK_STATUS_RESERVED | BLOCK_STATUS_BAD))
		{
			SECTOR_ADDR Sector = BLOCK_TO_PAGE(blockID);
			SectorInfo SI;
			
			if (!Nand_ReadPageSpare(Sector, &SI, sizeof(SectorInfo)))
			{
			    return FALSE;
			}
			
			if (dwStatus & BLOCK_STATUS_READONLY)
			{
			    SI.bOEMReserved &= ~OEM_BLOCK_READONLY;
			}
			
			if (dwStatus & BLOCK_STATUS_RESERVED)
			{
			    SI.bOEMReserved &= ~OEM_BLOCK_RESERVED;
			}
			
			if(dwStatus & BLOCK_STATUS_BAD)
			{
				SI.bBadBlock = 0x00;		//0xFF good block, 0x00 bad block
			}
			
			if (!Nand_WritePageSpare (Sector, &SI, sizeof(SectorInfo)))
			{
			    return FALSE;
			}
			
			return TRUE;
		}
		
		return FALSE;
	}
	
	/*
	 * Write a page
	 *
	 * Parameter
	 *    block			block no
	 *    page			page  no
	 *    pdata			data buffer pointer
	 *    len			data buffer length
	 * Return
	 *    status byte
	 */
	BOOL Nand_WritePageEx(BLOCK_ID block, SECTOR_ADDR offset_pages, const void *pdata, DWORD len)
	{
		DWORD pages;
		
		if(len > Nand_PageSize())
		{
			len = Nand_PageSize();
		}
		
		pages = BLOCK_TO_PAGE(block) + offset_pages;
		
		return (AdvFlash == NAND_Advance) ? NF_WriteAdv(pages, 0, pdata, len) : NF_Write(pages, 0, pdata, len);
	}
	
	BOOL Nand_WritePage(SECTOR_ADDR absolute_pages, const void *pdata, DWORD len)
	{
		return (AdvFlash == NAND_Advance) ? NF_WriteAdv(absolute_pages, 0, pdata, len) : NF_Write(absolute_pages, 0, pdata, len);
	}
	
	BOOL Nand_WritePageSpare(SECTOR_ADDR absolute_pages, const void *pdata, DWORD len)
	{
		return (AdvFlash == NAND_Advance) ? NF_WriteSpareAdv(absolute_pages, pdata, len) : NF_WriteSpare(absolute_pages, pdata, len);
	}
	
	/*
	 * Read a page
	 *    block			block no
	 *    page			page no
	 *    pdata			data buffer pointer
	 *    len			data buffer length
	 * Return
	 *    status byte
	 */
	BOOL Nand_ReadPageEx(BLOCK_ID block, SECTOR_ADDR offset_pages, void *pdata, DWORD len)
	{
		DWORD pages;
		
		if(len > Nand_PageSize())
		{
			len = Nand_PageSize();
		}
		
		pages = BLOCK_TO_PAGE(block) + offset_pages;
		
		return (AdvFlash == NAND_Advance) ? NF_ReadAdv(pages, 0, pdata, len) : NF_Read(pages, 0, pdata, len);
	}
	
	BOOL Nand_ReadPage(SECTOR_ADDR absolute_pages, void *pdata, DWORD len)
	{
		return (AdvFlash == NAND_Advance) ? NF_ReadAdv(absolute_pages, 0, pdata, len) : NF_Read(absolute_pages, 0, pdata, len);
	}
	
	BOOL Nand_ReadPageSpare(SECTOR_ADDR absolute_pages, void *pdata, DWORD len)
	{
		return (AdvFlash == NAND_Advance) ? NF_ReadSpareAdv(absolute_pages, pdata, len) : NF_ReadSpare(absolute_pages, pdata, len);
	}
	
	//----------------------------------------------------------------------------------------
	// Nand private methods
	//----------------------------------------------------------------------------------------
	// Normal mode (512)
	static BOOL NF_Write(SECTOR_ADDR pages, DWORD offset_bytes, const void* pdata, DWORD len)
	{
		return TRUE;
	}
	
	static BOOL NF_Read(SECTOR_ADDR pages, DWORD offset_bytes, void* pdata, DWORD len)
	{
		return TRUE;
	}
	
	static BOOL NF_WriteSpare(SECTOR_ADDR pages, const void* pdata, DWORD len)
	{
		return TRUE;
	}
	
	static BOOL NF_ReadSpare(SECTOR_ADDR pages, void* pdata, DWORD len)
	{
		return TRUE;
	}
	
	// Advanced mode (2048)
	static BOOL NF_WriteAdv(SECTOR_ADDR pages, DWORD offset_bytes, const void* pdata, DWORD len)
	{
		BOOL error = FALSE;
		BYTE status;
		
		DebugPrintf(("::NF_WriteAdv(pages=%d, offset_bytes=%d, pdata=%p, len=%d)\n", pages, offset_bytes, pdata, len));
		
		if(offset_bytes >= Nand_PageSize())
		{
			return FALSE;
		}
		
		//data len can be write
		if(len + offset_bytes > Nand_PageSize())
		{
			len = Nand_PageSize() - offset_bytes;
		}
		
		NF_nFCE_L();
		
		//output command : Program 1st & address & Program 2nd
		NF_CMD(CMD_PageProgram_1st);
		NF_ADDR_COL(offset_bytes);
		NF_ADDR_ROW(pages);
		
		__WrPageBytes(pdata, len);
	//	for(i=0;  i<len; i++)
	//	{
	//		NF_WDATA8(*pdata++);
	//	}
		
		NF_CMD(CMD_PageProgram_2nd);
				
		NF_WAIT_RnB();
		
		NF_READ_STATUS(status);
	
		error = (NF_STATUS_FAILED(status)) ? FALSE : TRUE;
		
	
		NF_nFCE_H();
		
		return error;
	}
	
	static BOOL NF_ReadAdv(SECTOR_ADDR pages, DWORD offset_bytes, void* pdata, DWORD len)
	{
		BOOL error = FALSE;
		
		DebugPrintf(("::NF_ReadAdv(pages=%d, offset_bytes=%d, pdata=%p, len=%d)\n", pages, offset_bytes, pdata, len));
		
		if(offset_bytes >= Nand_PageSize())
		{
			return FALSE;
		}
		
		//data len can be write
		if(len + offset_bytes > Nand_PageSize())
		{
			len = Nand_PageSize() - offset_bytes;
		}
		
		NF_nFCE_L();
		
		//output command : Read 1st & address & Read 2nd
		NF_CMD(CMD_Read_1st);
		NF_ADDR_COL(offset_bytes);
		NF_ADDR_ROW(pages);
		NF_CMD(CMD_Read_2nd);
		
		NF_WAIT_RnB();
		
		__RdPageBytes(pdata, len);
	//	for(i=0; i<len; i++)
	//	{
	//		*pdata++ = NF_RDATA8();
	//	}
		
		//MainECC check
		
		
		NF_nFCE_H();
		
		error = TRUE;
		
		return error;
	}
	
	static BOOL NF_WriteSpareAdv(SECTOR_ADDR pages, const void* pdata, DWORD len)
	{
		BOOL error = FALSE;
		BYTE status;
		
		DebugPrintf(("::NF_WriteSpareAdv(pages=%d, pdata=%p, len=%d)\n", pages, pdata, len));
		
		//data len can be write
		if(len > SpareSize)
		{
			len = SpareSize;
		}
		
		NF_nFCE_L();
		
		//output command : Program 1st & address & Program 2nd
		NF_CMD(CMD_PageProgram_1st);
		NF_ADDR_COL(Nand_PageSize());
		NF_ADDR_ROW(pages);
		
		__WrPageBytes(pdata, len);
	//	for(i=0;  i<len; i++)
	//	{
	//		NF_WDATA8(*pdata++);
	//	}
		
		NF_CMD(CMD_PageProgram_2nd);
		
		NF_WAIT_RnB();
			
		NF_READ_STATUS(status);
	
		error = (NF_STATUS_FAILED(status)) ? FALSE : TRUE;
		
	
		NF_nFCE_H();
		
		return error;
	}
	
	static BOOL NF_ReadSpareAdv(SECTOR_ADDR pages, void* pdata, DWORD len)
	{
		BOOL error = FALSE;
		
		DebugPrintf(("::NF_ReadSpareAdv(pages=%d, pdata=%p, len=%d)\n", pages, pdata, len));
		
		//data len can be write
		if(len > SpareSize)
		{
			len = SpareSize;
		}
		
		NF_nFCE_L();
		
		//output command : Read 1st & address & Read 2nd
		NF_CMD(CMD_Read_1st);
		NF_ADDR_COL(Nand_PageSize());
		NF_ADDR_ROW(pages);
		NF_CMD(CMD_Read_2nd);
		
		NF_WAIT_RnB();
		
		__RdPageBytes(pdata, len);
	//	for(i=0; i<len; i++)
	//	{
	//		*pdata++ = NF_RDATA8();
	//	}
		
		//SpareECC check
		
		
		NF_nFCE_H();
		
		error = TRUE;
		
		return error;
	}
	
	BOOL NF_ReadChipInfo(FlashInfo *pFlashInfo)
	{
		WORD wChipID = Nand_ReadID();
		
		int i;
		for(i=0; i< sizeof(ChipID2NumBlocks)/sizeof(ChipID2NumBlocks[0]); i++)
		{
			if(wChipID == ChipID2NumBlocks[i][0])
			{
				pFlashInfo->dwNumBlocks = ChipID2NumBlocks[i][1];
				return TRUE;
			}
		}
		
		return FALSE;
	}

#ifdef __cplusplus
}
#endif



⌨️ 快捷键说明

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