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

📄 tcl_gdi_flash_cfi.c

📁 完全支持CFI协议的Flash驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
			FLASH_DEBUG(("Sector%d, start:%x,size:%d\n",puSectorNum,pFlashInfo->eSectorInfo[puSectorNum].uStartAdress,
				pFlashInfo->eSectorInfo[puSectorNum].uSecLength));
			*/
			
			puSectorNum = puSectorNum +1;
			size += gEraseRegionInfo.sectorSize;			
		}
					
		if(size>=gFlashTotalSize)
		{
			gNumEraseRegions = i+1;
			break;
		}
        
	}

	/*if this is defined, the small sectors in the flash will not be used for TopMode Flash */
#ifdef DONT_USE_SMALL_SECTOR
{
	TCL_UINT8 uSmallSecNum = 0;

	/* Check from the end of the table, find how many small sectors after the normal sector */

	i = *puSectorNum;
	while(1) 
	{
		if(pFlashInfo->eSectionInfo[i-1].uSecLength < 65536)
		{
			uSmallSecNum++;
			i--;
		}
		else
		{
			/* once there is normal one, terminate the detection. */
			break;
		}
	}

	*puSectorNum = *puSectorNum - uSmallSecNum;
}
#endif

	/* Issue Reset command */
	WRITE_FLASH(CMD_RESET_ADDR[gIsSst16Bit], CMD_RESET_DATA[gIsSst16Bit]);

	/* Disable writes to the flash */
	DisableFlash();	
	
	pFlashInfo->uSectorNum = puSectorNum;
	
	return TCL_TRUE;
}


/******************************************************************************
* Function:            DTV_BoardIs8BitsFlash
* Description:        判断是否是8 位的Flash
* Calls:            	omit
* Called By: 		omit
* Table Accessed:	none
* Table Updated:	none
* Input:   		none
* Output:              	none
* Return:              TCL_TRUE - 是8 位的Flash
				TCL_FALSE - 不是8 位的Flash
* Others: 			
* Note:			
*		Author			Date								Purpose	
*----------------------------------------------------------------------------
*		JokQu			20080229						create
******************************************************************************/
static TCL_BOOL DTV_BoardIs8BitsFlash(TCL_VOID)
{
	return TCL_FALSE;
}


/******************************************************************************
* Function:            FlashAutoSelect
* Description:        获取Flash 信息
* Calls:            	omit
* Called By: 		omit
* Table Accessed:	none
* Table Updated:	none
* Input:   		TCL_GDI_FLASH_INFO *pFlashInfo - Flash 信息指针
* Output:              	TCL_GDI_FLASH_INFO *pFlashInfo - Flash 信息
* Return:              TCL_NO_ERROR
* Others: 			
* Note:			
*		Author			Date								Purpose	
*----------------------------------------------------------------------------
*		JokQu			20080229						create
******************************************************************************/
static TCL_BOOL FlashAutoSelect(TCL_GDI_FLASH_INFO *pFlashInfo)
{
	TCL_UINT16                  id;
	TCL_UINT8                   i;
	TCL_UINT8                   j;
	TCL_UINT32                  size;    
	FL_ERASE_REGION_INFO    gEraseRegionInfo[4];

	pFlashInfo->eBootMode = 0xFF;
		
	if (DTV_BoardIs8BitsFlash())
	{
		WorkMode = 1;
		gIsSst16Bit = TCL_FALSE;

		#if 0
		cbus_write( 0x1a00,     0x454500 );   // Guest 0
		cbus_write( 0x1a01, 0x321045 );
		cbus_write( 0x1a31,   0x300 );      // time out addr
		#endif
	}
	else
	{
		WorkMode = 2;
	}

	FLASH_DEBUG(("Flash works mode: %s\n", (WorkMode == WORK_MODE_8BIT)?"8 Bits":"16 Bits"));

	/* Enable writes to the flash */
	EnableFlash( );

	/* Issue Reset command */
	if (!gIsSst16Bit)
	{
		WRITE_FLASH(CMD_RESET_ADDR[gIsSst16Bit], CMD_RESET_DATA[gIsSst16Bit]);
	}
	else
	{
		WRITE_FLASH(CMD_RESET_ADDR[gIsSst16Bit]/WorkMode, CMD_RESET_DATA[gIsSst16Bit]);
	}
	
	/* Issue unlock command */
	FLASH_UnlockCmd();

	/* Issue AutoSelect command */
	WRITE_FLASH(CMD_AUTOSELECT_ADDR[gIsSst16Bit]/ WorkMode, CMD_AUTOSELECT_DATA[gIsSst16Bit]);

	/* Read Manufacturer ID and Device ID */
	id = READ_FLASH( MANUFACTURER_ID_ADDR / WorkMode )<<8;
	id |= READ_FLASH( DEVICE_ID_ADDR / WorkMode ) & 0xFF;
	
	/* SST39VF088 read Device ID from 0x01 instead of 0x02 */
	if( 0xBF00 == (id & 0xFF00) )
	{
		id = 0xBF00 | READ_FLASH( 0x01 );
	}

	if( 0xBF00 == id)
	{
		id |= READ_FLASH( DEVICE_ID_ADDR );
	}

	pFlashInfo->uManufactId = id&0xFF00;
	pFlashInfo->uDeviceId = id&0xFF;
		
	/* Issue Reset command */
	if (!gIsSst16Bit)
	{
		WRITE_FLASH(CMD_RESET_ADDR[gIsSst16Bit], CMD_RESET_DATA[gIsSst16Bit]);
	}
	else
	{
		WRITE_FLASH(CMD_RESET_ADDR[gIsSst16Bit]/WorkMode, CMD_RESET_DATA[gIsSst16Bit]);
	}
    
	/* Disable writes to the flash */
	DisableFlash( );
    
	FLASH_DEBUG(("Flash ID: %x\n", id));

	if ((gIsSst16Bit) && (id != 0xBF5B) && (id != 0xBF5A) && (id != 0xBF4A) && (id != 0xBF4B))
	{
		return TCL_FALSE;
	}

	gUseDQ5ForTimeout = TCL_TRUE;

	switch(id>>8)
	{
		case 0xBF: /* SST  */
		{
			/* SST Flash Do not use DQ5 for timeout detection */
			gUseDQ5ForTimeout = TCL_FALSE;
		}
		break;
	}

	pFlashInfo->uSectorNum = 0;
	memset(gEraseRegionInfo,0,sizeof(gEraseRegionInfo));
	switch( id )
	{
		case 0xC2C4:        /* Uti/MXIC 29LV160AT 2M Top (for Mico) */
		{
			pFlashInfo->eBootMode		= TCL_GDI_FLBOOT_TOP;
			pFlashInfo->uCFI			= 1;
			pFlashInfo->uSectorNum		= 35;
			pFlashInfo->uFlashSize		= 4 * 1024 * 1024;									
        
			gEraseRegionInfo[0].numSectors = 31;
			gEraseRegionInfo[0].sectorSize = 0x10000;
			gEraseRegionInfo[1].numSectors = 1;
			gEraseRegionInfo[1].sectorSize = 0x8000;
			gEraseRegionInfo[2].numSectors = 2;
			gEraseRegionInfo[2].sectorSize = 0x2000;
			gEraseRegionInfo[3].numSectors = 1;
			gEraseRegionInfo[3].sectorSize = 0x4000;
		}
		break;
            
		case 0xC249:     /* MXIC 29LV160AB   2M Bottom (for ShenZhou) */
		{		
			pFlashInfo->eBootMode		= TCL_GDI_FLBOOT_BOTTOM;
			pFlashInfo->uCFI			= 1;
			pFlashInfo->uSectorNum		= 35;
			pFlashInfo->uFlashSize		= 4 * 1024 * 1024;		
			
			gEraseRegionInfo[3].numSectors = 31;
			gEraseRegionInfo[3].sectorSize = 0x10000;
			gEraseRegionInfo[2].numSectors = 1;
			gEraseRegionInfo[2].sectorSize = 0x8000;
			gEraseRegionInfo[1].numSectors = 2;
			gEraseRegionInfo[1].sectorSize = 0x2000;
			gEraseRegionInfo[0].numSectors = 1;
			gEraseRegionInfo[0].sectorSize = 0x4000;
		}
		break;           
        
		case 0x01DA:        /* AMD Am29LV800BT 1M Top */
		case 0x04DA:        /* FUJITSU MBM29LV800TE/TA  1M Top */
		{
			pFlashInfo->eBootMode		= TCL_GDI_FLBOOT_TOP;
			pFlashInfo->uCFI			= 1;
			pFlashInfo->uSectorNum		= 19;
			pFlashInfo->uFlashSize		= 4 * 1024 * 1024;					
			gEraseRegionInfo[0].numSectors = 15;
			gEraseRegionInfo[0].sectorSize = 0x10000;
			gEraseRegionInfo[1].numSectors = 1;
			gEraseRegionInfo[1].sectorSize = 0x8000;
			gEraseRegionInfo[2].numSectors = 2;
			gEraseRegionInfo[2].sectorSize = 0x2000;
			gEraseRegionInfo[3].numSectors = 1;
			gEraseRegionInfo[3].sectorSize = 0x4000;
		}
		break;
            
		case 0x015B:        /* AMD Am29LV800BB 1M Bottom */
		case 0x045B:        /* FUJITSU MBM29LV800BE/BA  1M Bottom */
		case 0x8C5B:		/* ESMT	F49L800 1M BOTTOM */
		{
			pFlashInfo->eBootMode		= TCL_GDI_FLBOOT_BOTTOM;
			pFlashInfo->uCFI			= 1;
			pFlashInfo->uSectorNum		= 19;
			pFlashInfo->uFlashSize		= 4 * 1024 * 1024;	
			gEraseRegionInfo[3].numSectors = 15;
			gEraseRegionInfo[3].sectorSize = 0x10000;
			gEraseRegionInfo[2].numSectors = 1;
			gEraseRegionInfo[2].sectorSize = 0x8000;
			gEraseRegionInfo[1].numSectors = 2;
			gEraseRegionInfo[1].sectorSize = 0x2000;
			gEraseRegionInfo[0].numSectors = 1;
			gEraseRegionInfo[0].sectorSize = 0x4000;
		}
		break;

		case 0xBF4B:		/* SST39VF1601C */
		{
			pFlashInfo->eBootMode		= TCL_GDI_FLBOOT_BOTTOM;
			pFlashInfo->uCFI			= 1;
			pFlashInfo->uSectorNum		= 32;
			pFlashInfo->uFlashSize		= 4 * 1024 * 1024;				
			gEraseRegionInfo[0].numSectors = 32;
			gEraseRegionInfo[0].sectorSize = 0x10000;  
			gEraseRegionInfo[1].numSectors = 0; 
			gUseDQ5ForTimeout = TCL_FALSE;
			mEraseCmd=CMD_BLOCK_ERASE;
		}
		break;           

		case 0xBF5B:          /* SST39VF3201 */
		{
			pFlashInfo->eBootMode		= TCL_GDI_FLBOOT_BOTTOM;
			pFlashInfo->uCFI			= 1;
			pFlashInfo->uSectorNum		= 64;
			pFlashInfo->uFlashSize		= 4 * 1024 * 1024;					
			gEraseRegionInfo[0].numSectors = 64;
			gEraseRegionInfo[0].sectorSize = 0x10000;  
			gEraseRegionInfo[1].numSectors = 0; 
			gUseDQ5ForTimeout = TCL_FALSE;
			mEraseCmd=CMD_BLOCK_ERASE;
		}
		break;           

		case 0xBFD8:                /* SST39VF088 */
		{
			pFlashInfo->eBootMode		= TCL_GDI_FLBOOT_BOTTOM;
			pFlashInfo->uCFI			= 1;
			pFlashInfo->uSectorNum		= 16;
			pFlashInfo->uFlashSize		= 4 * 1024 * 1024;					
			gEraseRegionInfo[0].numSectors = 16;
			gEraseRegionInfo[0].sectorSize = 0x10000;
			gEraseRegionInfo[1].numSectors = 0;            
		}
		break;

		case 0xBFC8:                /* SST39VF1681 */
		case 0xBFC9:                /* SST39VF1682 */
		{
			pFlashInfo->eBootMode		= TCL_GDI_FLBOOT_BOTTOM;
			pFlashInfo->uCFI			= 1;
			pFlashInfo->uSectorNum		= 32;
			pFlashInfo->uFlashSize		= 4 * 1024 * 1024;		
			gEraseRegionInfo[0].numSectors = 32;
			gEraseRegionInfo[0].sectorSize = 0x10000;
			gEraseRegionInfo[1].numSectors = 0; 
			gUseDQ5ForTimeout = TCL_FALSE;
		}
		break; 
						
		case 0x04C4:    /* Fujitsu(/Malaysia) 29LV160TE */
		case 0x37A8:    /* Amic A29L160 Top */
		case 0x01C4:    /* AMD S29AL160M top */
		case 0x1FC2:    /* ATMEL AT49BV162/3AT top */
		{
			pFlashInfo->eBootMode = TCL_GDI_FLBOOT_TOP;
		}
		break;
            
		default:
			break;  
	}

	if( 0 == pFlashInfo->uSectorNum)
	{           
		/* If not special Flash, return FALSE to use CFI */
		return FlashProbeCFI(pFlashInfo);
	}

	id = 0;
	size = 0;
	
	for(i = 0; i < 4; i++)
	{
		if(0 == gEraseRegionInfo[i].numSectors)
		{
			break;
		}

		for(j = 0; j < gEraseRegionInfo[i].numSectors; j++)
		{            
			pFlashInfo->eSectorInfo[id ].uSectorNo 	= id ;
			pFlashInfo->eSectorInfo[id ].uStartAdress = size;
			pFlashInfo->eSectorInfo[id ].uSecLength 	= gEraseRegionInfo[j].sectorSize;

			id += 1;
			size += gEraseRegionInfo[i].sectorSize;
		}
	}

	return TCL_TRUE;    
}


/******************************************************************************
* Function:            CFI_FlashGetInfo
* Description:        获取Flash 信息
* Calls:            	omit
* Called By: 		omit
* Table Accessed:	none
* Table Updated:	none
* Input:   		TCL_GDI_FLASH_INFO *pFlashInfo - Flash 信息指针
* Output:              	TCL_GDI_FLASH_INFO *pFlashInfo - Flash 信息
* Return:              TCL_NO_ERROR
* Others: 			
* Note:			
*		Author			Date								Purpose	
*----------------------------------------------------------------------------
*		JokQu			20080229						create
******************************************************************************/
TCL_UINT32 CFI_FlashGetInfo(TCL_GDI_FLASH_INFO *pFlashInfo)
{
	if( (TCL_FALSE == FlashAutoSelect(pFlashInfo) )
		&& (WORK_MODE_16BIT == WorkMode))
	{
		if (gIsSst16Bit)
		{
			gIsSst16Bit = TCL_FALSE;
			FlashAutoSelect(pFlashInfo);		
		}
	}

	return TCL_NO_ERROR;
}


/******************************************************************************
* Function:            CFI_FlashSecStartAddr
* Description:        得到一个地址所在的扇区号
* Calls:            	omit
* Called By: 		omit
* Table Accessed:	none
* Table Updated:	none
* Input:   		TCL_UINT32 uAddr - 地址
* Output:              	none
* Return:              扇区号
* Others: 			
* Note:			
*		Author			Date								Purpose	
*----------------------------------------------------------------------------
*		JokQu			20080229						create
******************************************************************************/
static TCL_UINT32 CFI_FlashSecNum(TCL_UINT32 uAddr)
{
	extern TCL_INT32 TCL_GDI_Flash_GetSecNum(TCL_UINT32 );

	return TCL_GDI_Flash_GetSecNum(uAddr);
}


/******************************************************************************
* Function:            CFI_FlashSecStartAddr
* Description:        得到一个扇区的起始地址
* Calls:            	omit
* Called By: 		omit
* Table Accessed:	none
* Table Updated:	none
* Input:   		TCL_UINT32 uSector - 扇区号
* Output:              	none
* Return:              起始地址
* Others: 			
* Note:			
*		Author			Date								Purpose	
*----------------------------------------------------------------------------
*		JokQu			20080229						create
******************************************************************************/
static TCL_UINT32 CFI_FlashSecStartAddr(TCL_UINT32 uSector)
{
	extern TCL_UINT32 TCL_GDI_Flash_GetSecStartAddr(TCL_UINT32);
	return TCL_GDI_Flash_GetSecStartAddr(uSector);
}

⌨️ 快捷键说明

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