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

📄 am29lv160drv.c

📁 ucos移植在S3C44BOX上的源码
💻 C
字号:
/**************************************************************************************************
*
* 作者: 胡翌博,浙江大学信电系电路与系统2001研
*
* 文件名:am29lv160Drv.c 
*
* 版本: 1.1
*
* 功能描述:该文件提供了29lv160的驱动程序。
*
* 被本文件引用的文件列表:s3c4510bDef.h, typDef.h
*
* 应用本文件的文件列表:no
*
* 版本更迭:
*         日期         版本号      作者      备注
*      07-15-2003       1.0       胡翌博     --实验成功
*      07-27-2003       1.1       胡翌博     --s3c4510b.h更名为s3c4510bDef.h,修改相应的include语句
*                                            --am29lv160.c更名为am29lv160Drv.c
**************************************************************************************************/



#include "s3c4510bDef.h"
#include "typDef.h"

#define AM_START_ADDR          0x1100000
#define AM_CHIP_HWORD_SIZE     0x100000                 /*1M HWords*/
#define AM_ADDR_UNLOCK1        0x555
#define AM_ADDR_UNLOCK2        0x2aa
#define AM_DATA_UNLOCK1        0xaaaa
#define AM_DATA_UNLOCK2        0x5555
#define AM_SETUP_WRITE         0xa0a0
#define AM_SETUP_ERASE         0x8080
#define AM_CHIP_ERASE          0x1010
#define AM_SECTOR_ERASE	       0x3030



/**************************************************************************************************
函数名称:       amOpOverDetect()
函数功能:       采用poll方式检测flash擦写是否完成.
入口参数:       ptr         数据写入地址/擦除扇区首址.
		trueData    要写入的值.
		timeCounter 超时计数.
返 回 值:       OK		操作成功.
		ERROR	操作失败.
备    注:       在预定时间内如果d7,d6仍不是truedata,则返回ERROR.
**************************************************************************************************/
STATUS  amOpOverDetect(UINT16 *ptr,  UINT16 trueData, int timeCounter)
{
	int timeTmp = timeCounter;
	volatile UINT16 *pFlash = ptr;
	UINT16 buf1, buf2,curTrueData;
	
	curTrueData = trueData & 0x8080;                  //先检测d7位.
	while((*pFlash & 0x8080) != curTrueData)
	{
		if(timeTmp-- <= 0) break;                 //超时以后不是应该用return ERROR吗?
	}
	
	timeTmp = timeCounter;
	buf1 = *pFlash & 0x4040;			  //(为保险)再检测d6位.
	while(1)
	{
		    buf2  = *pFlash & 0x4040;
		    if(buf1 == buf2) break;
		    else buf1 = buf2;
		    if(timeTmp-- <= 0) 
		    {
				return ERROR;
		    }
	}

	return OK;
}



/**************************************************************************************************
函数名称:       sstWrite()
函数功能:       读取缓冲区数据,根据给定的长度写入指定地址.
入口参数:       flashAddr    数据目标地址(flash).
		buffer       数据源地址.
		length 	     要写入的字节数.
				
返 回 值:      	NULL	     写失败.
		flashPtr     flash的下一个地址.
备    注:       由于sst39vf160只能按半字(16bit)操作,所以
                如果要多次调用这个函数来写入一个文件,则应
                每次读取偶数个字节,以保证连续性.
**************************************************************************************************/    

UINT16 *amWrite(UINT16 *flashAddr, UINT8 *buffer, int length)
{
	int i, cLength;
	volatile UINT16 *flashPtr;
	volatile UINT16 *gBuffer;
	
        flashPtr = flashAddr;
	cLength = (length + 1)/2;				//计算半字长度.
	gBuffer = (UINT16 *)buffer;      
	
	while (cLength > 0) 
	{
	  *((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK1) = AM_DATA_UNLOCK1;          //解锁.
	  *((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK2) = AM_DATA_UNLOCK2;
    	  *((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK1) = AM_SETUP_WRITE;
	  *flashPtr = *gBuffer;                                         //写入数据.
		
	  if(amOpOverDetect((UINT16 *)flashPtr, *gBuffer, 0x100000))    //检测写入是否成功.
	  {
		//printf("warning: write flash may failed at:0x%x.\n", (int)flashPtr);
	  }
		cLength--;
		flashPtr++;
		gBuffer++;
	}	
	
        flashPtr = flashAddr;
	gBuffer = (UINT16 *)buffer; 
	cLength = length/2;
	for(i=0; i<cLength; i++)			//写入的数据全部校验一次.
	{
	    if(*flashPtr++ != *gBuffer++)
	    {    
	        //printf("Error: write failed in SST39vf160 at 0x%x on verification.\n", (int)flashPtr);
	        return NULL;
	    }
	}
	if(length%2)
	{
	    if((*flashPtr++ & 0x00ff) != (*gBuffer++ & 0x00ff))  /*奇数长度的最后一个字节.*/
	    {
	        //printf("Error: write failed in SST39vf160 at 0x%x on verification.\n", (int)flashPtr);
	        return NULL;	    
	    }
	}
	return (UINT16 *)flashPtr;
}



/**************************************************************************************************
函数名称:       amChipErase()
函数功能:       擦除整个flash芯片.
入口参数:       无.
				
返 回 值:      	OK	 擦除完全正确.
		ERROR    有单元不能正确擦除.
备    注:       datasheet上说典型时间为26s,实际大约15秒,
		所以尽量用amSectorErase().
**************************************************************************************************/
STATUS amChipErase(void)
{
    int i;
    volatile UINT16 *flashPtr = NULL;
    
    *((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK1) = AM_DATA_UNLOCK1;			//连续解锁.
    *((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK2) = AM_DATA_UNLOCK2;
    *((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK1) = AM_SETUP_ERASE;
    *((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK1) = AM_DATA_UNLOCK1;
    *((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK2) = AM_DATA_UNLOCK2;
    *((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK1) = AM_CHIP_ERASE;			//写入擦除命令.

	flashPtr = (volatile UINT16 *)AM_START_ADDR;			  

	if(amOpOverDetect((UINT16 *)flashPtr, 0xffff, 0x800000) != OK)
	{
		//printf("warning: Chip Erase time out!\n");	
	}	
	
	flashPtr = (volatile UINT16 *)AM_START_ADDR;			  
	for(i=0; i<AM_CHIP_HWORD_SIZE; i++,flashPtr++)  					//校验是否全为0xffff.
	{
	   if(*flashPtr != 0xffff)
	   {
	      //printf("Debug: Erase failed at 0x%x in SST39VF160 on verification.\n", (int)flashPtr);
	      return ERROR;
           }
	}
	return OK;
}    



/**************************************************************************************************
函数名称:       amSectorErase()
函数功能:       擦除指定的flash扇区.
入口参数:       pSector  扇区地址.
				
返 回 值:      	OK	 擦除完全正确.
		ERROR    有单元不能正确擦除.
备    注:       
**************************************************************************************************/
STATUS amSectorErase(UINT16 *pSector)
{
    //int i;
    volatile UINT16 *flashPtr = pSector;
    
	*((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK1) = AM_DATA_UNLOCK1;			//连续解锁.
	*((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK2) = AM_DATA_UNLOCK2;
	*((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK1) = AM_SETUP_ERASE;
	*((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK1) = AM_DATA_UNLOCK1;
	*((volatile UINT16 *)AM_START_ADDR + AM_ADDR_UNLOCK2) = AM_DATA_UNLOCK2;
	*flashPtr = AM_SECTOR_ERASE;			//写入擦除命令.

	if(amOpOverDetect((UINT16 *)flashPtr, 0xffff, 0x20000) != OK)
	{
	    return ERROR;
	    //printf("warning: Chip Erase time out!\n");	
	}	
	
	return OK;
}



/**************************************************************************************************
函数名称:       amSecNumErase()
函数功能:       根据指定的扇区号(段号),擦除flash扇区.
入口参数:       secNum  扇区号.
				
返 回 值:      	OK	 该扇区擦除完全正确.
		ERROR    该扇区有单元不能正确擦除.
备    注:       
**************************************************************************************************/
STATUS amSecNumErase(int secNum)
{
	int n;
	STATUS rv;
	
	n=secNum;
	rv=OK;
	switch(n)
	{
		case 0:
    		  if(amSectorErase((UINT16 *)0x1100000) !=OK)         //擦除第一个扇区.
    		  {
    		  	rv=ERROR;
    		  	break;
    		  }
    		  rv=OK;
    		  break;
    		case 1:
    		  if(amSectorErase((UINT16 *)0x1102000) !=OK)         //擦除第二个扇区.
    		  {
    		  	rv=ERROR;  		        
    		  	break;
    		  }
    		  rv=OK;
    		  break;
    		case 2:
    		  if(amSectorErase((UINT16 *)0x1103000) !=OK)         //擦除第三个扇区.
    		  {
    		  	rv=ERROR;   		        
    		  	break;
    		  }
    		  rv=OK;
    		  break;
    		case 3:
    		  if(amSectorErase((UINT16 *)0x1104000) !=OK)         //擦除第二个扇区.
    		  {
    		  	rv=ERROR;   		        
    		  	break;
    		  }
    		  rv=OK;
    		  break;
    		case 4:
    		  if(amSectorErase((UINT16 *)0x1108000) !=OK)         //擦除第二个扇区.
    		  {
    		  	rv=ERROR;   		        
    		  	break;
    		  }
    		  rv=OK;
    		  break;
    		case 5:
    		case 6:
    		case 7:
    		case 8:
    		case 9:
    		case 10:
    		case 11:
    		case 12:
    		case 13:
    		case 14:
    		case 15:
    		case 16:
    		case 17:
    		case 18:
    		case 19:
    		case 20:
    		case 21:
    		case 22:
    		case 23:
    		case 24:
    		case 25:
    		case 26:
    		case 27:
    		case 28:
    		case 29:
    		case 30:
    		case 31:
    		case 32:
    		case 33:
    		case 34:
    		  if(amSectorErase((UINT16 *)(17858560+32768*(n-4))) !=OK)
    		  {
    		  	rv=ERROR;
    		  	break;
    		  }
    		  rv=OK;
    		  break;
    		default: break;
    	}//end of switch(n)
    	return rv;
}

⌨️ 快捷键说明

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