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

📄 memory_test.c

📁 s3c2410开发板的内存检测程序
💻 C
字号:
#define	NULL	0
#define FLASH_BASE 0x00000000
#define DM_PG(x)
int DM_CNT = 0;

unsigned short ReadDeviceID(void)
{
	unsigned short nDevID = 0;
	volatile unsigned short * p;
	unsigned char			 oldDmCnt;
	oldDmCnt = DM_CNT;		//保存DM_CNT当前值,即保存当前页号
	DM_PG(0);				//映射到FLASH第0页,因为对FLASH操作的命令地址都是相对于第0页的
	p 	= (volatile unsigned short *)FLASH_BASE + 0x555;
	*p 	= 0xAA;
	p	= (volatile unsigned short *)FLASH_BASE + 0x2AA;
	*p	= 0x55;
	p	= (volatile unsigned short *)FLASH_BASE + 0x555;
	*p	= 0x90;
	p	= (volatile unsigned short *)FLASH_BASE + 0x01;
	nDevID = *p;		/*获得设备号*/
	
	DM_CNT = oldDmCnt;		//恢复到初始页
	UnlockByreset();
	return nDevID;		
}

int EraseChip(void)
{
	volatile unsigned short * p;
	unsigned short			 data = 0;
	unsigned char			 oldDmCnt;
	oldDmCnt = DM_CNT;		//保存DM_CNT当前值,即保存当前页号
	DM_PG(0);				//映射到FLASH第0页,因为对FLASH操作的命令地址都是相对于第0页的
	p	= (volatile unsigned short *)FLASH_BASE + 0x555;
	*p	= 0xAA;
	p	= (volatile unsigned short *)FLASH_BASE + 0x2AA;
	*p	= 0x55;
	p	= (volatile unsigned short *)FLASH_BASE + 0x555;
	*p	= 0x80;
	p	= (volatile unsigned short *)FLASH_BASE + 0x555;
	*p	= 0xAA;
	
	p	= (volatile unsigned short *)FLASH_BASE + 0x2AA;
	*p	= 0x55;
	p	= (volatile unsigned short *)FLASH_BASE + 0x555;
	*p	= 0x10;	
	DM_CNT = oldDmCnt;		//恢复到初始页	
	//对FLASH的擦除操作开始进行,我们需要等待并检查相关的数据来判断操作是否完成,
	//或者操作失败
	do
	{
		data = *p;			//获取相关数据
		if (data & 0x0080)	//若擦除操作完成或成功,则data的最高位Bit7将被置为1
		{
			return 1;
		}
		else{}
		
	}while ( (data & 0x0020) == 0);	//若擦除操作正在进行,则data的Bit5置为0,继续等待
	data = *p;				//获取相关数据
	if (data & 0x0080)		//若擦除操作成功,则data的最高位Bit7将被置为1
		return 1;
	else
		return 0;	
}
//
int EraseSector(unsigned long addr)
{
	volatile unsigned short * p;
	unsigned short			 data = 0;
	unsigned char			 oldDmCnt;
	if (addr > 0x8000)
	{
		printf("Invalid address, out of range.\n");
		return 0;
	}
	else{}
	oldDmCnt = DM_CNT;		//保存DM_CNT当前值,即保存当前页号
	DM_PG(0);				//映射到FLASH第0页,因为对FLASH操作的命令地址都是相对于第0页的
	 p	= (volatile unsigned short *)FLASH_BASE + 0x555;
	*p	= 0xAA;
	p 	= (volatile unsigned short *)FLASH_BASE + 0x2AA;
	*p	= 0x55;
	p	= (volatile unsigned short *)FLASH_BASE + 0x555;
	*p	= 0x80;
	p	= (volatile unsigned short *)FLASH_BASE + 0x555;
	*p 	= 0xAA;
	p 	= (volatile unsigned short *)FLASH_BASE + 0x2AA;
	*p	= 0x55;
	
	DM_CNT = oldDmCnt;		//恢复到初始页

	p 	= (volatile unsigned short *)FLASH_BASE + addr;
	*p	= 0x30;
		
	do
	{
		data = *p;		//获取相关数据
		if (data & 0x0080)//若擦除操作完成或成功,则data的最高位Bit7将被置为1
		{
			return 1;
		}
		else{}
		
	}while ( (data & 0x0020) == 0);
	
	data = *p;			//获取相关数据
	if (data & 0x0080)	//若擦除操作成功,则data的最高位Bit7将被置为1
	{
		return 1;
	}
	else
	{
		return 0;
	}
}


int ReadFlash(unsigned long addr, unsigned long length, unsigned short * p)
{
	unsigned long i;
	
	if (NULL == p)
	{
		printf("Invalid polonger to buffer!\n");
		return 0;	
	}
	else{}
	
	if (addr > 0x8000)
	{
		printf("Invalid address, out of range.\n");
		return 0;
	}
	else{}
	
	if (addr + length > 0x8000)
	{
		printf("Invalid length, the biggest address is out of range.\n");
		return 0;
	}
	else{}
	
	for (i = 0; i < length; i++)
	{
		*(p + i) = *(unsigned short *)(FLASH_BASE + addr + i*2);
	}
	
	return length;
}
int ReadSector(unsigned long addr, unsigned short * p)
{
	unsigned long i;
	unsigned long length = 0;
	unsigned long sectorStartAddr = 0;		//块起始地址
	
	if (NULL == p)
	{
		printf("Invalid pointer to buffer!\n");
		return 0;	
	}
	else{}
	
	if (addr > 0x8000)
	{
		printf("Invalid address, out of range.\n");
		return 0;
	}
	else{}
	
	if ( (DM_CNT & 0x1F) != 7)				//若当前页不是第7页,则0页就是0块
	{
		length = 0x8000;					//一个块32KWord
		sectorStartAddr = 0;
	}
	else
	{
		if (addr < 0x4000)
		{
			length = 0x4000;				//一个块16KWord
			sectorStartAddr = 0;
		}
		else if (addr >= 0x4000 && addr < 0x6000)
		{
			length = 0x1000;				//一个块4KWord
			if (addr < 0x5000)
			{
				sectorStartAddr = 0x4000;
			}
			else
			{
				sectorStartAddr = 0x5000;
			}
		}
		else if (addr >= 0x6000 && addr < 0x8000)
		{
			length = 0x2000;				//一个块8KWord
			sectorStartAddr = 0x6000;
		}
		else
		{
			printf("Invalid address, out of range.\n");
			return 0;
		}
	}
	for (i = 0; i < length; i++)
	{
		*(p + i) = *(unsigned short *)(FLASH_BASE + sectorStartAddr + i);
	}
	
	return length;	
}


int ProgramFlash(unsigned long addr, unsigned short data)
{
	volatile unsigned short * p;
	unsigned short			  tmpData;
	unsigned char			 oldDmCnt;
	
	if (addr > 0x8000)
	{
		printf("Invalid address, out of range.\n");
		return 0;
	}
	else{}
	
	
	oldDmCnt = DM_CNT;		//保存DM_CNT当前值,即保存当前页号
	DM_PG(0);				//映射到FLASH第0页,因为对FLASH操作的命令地址都是相对于第0页的

	p	= (volatile unsigned short *)(FLASH_BASE + 0x555);
	*p	= 0xAA;
	
	p 	= (volatile unsigned short *)(FLASH_BASE + 0x2AA);
	*p 	= 0x55;
	
	p 	= (volatile unsigned short *)(FLASH_BASE + 0x555);
	*p	= 0xA0;
	
	DM_CNT = oldDmCnt;		//恢复到初始页
	
	p 	= (volatile unsigned short *)(FLASH_BASE + addr);
	*p 	= data;
	
	//烧写操作需要0定的时间,要不断的检测烧写操作是否完成
	do
	{
		tmpData = *p;						//获取数据
		if ( ((tmpData ^ data) & 0x0080) == 0)//若烧写成功,则tmpData 与 data的最高位与Bit7相同
			return 1;
		else{}
		
	}while ( (tmpData & 0x0020) == 0);		//若烧写还在进行,则tmpData的Bit5为0,否则完成
	
	return 0;	
}


int UnlockByProgram(unsigned long addr, unsigned short data)
{
	volatile unsigned short * p;
	unsigned short			  tmpData;
	unsigned char			  oldDmCnt;
	
	if (addr > 0x8000)
	{
		printf("Invalid address, out of range.\n");
		return 0;
	}
	else{}
	
	
	oldDmCnt = DM_CNT;		//保存DM_CNT当前值,即保存当前页号
	DM_PG(0);				//映射到FLASH第0页,因为对FLASH操作的命令地址都是相对于第0页的

	p	= (volatile unsigned short *)(FLASH_BASE + 0xAAA);
	*p	= 0xA0;
	
	
	DM_CNT = oldDmCnt;		//恢复到初始页

	p 	= (volatile unsigned short *)(FLASH_BASE + addr);
	*p 	= data;
	
	//烧写操作需要0定的时间,要不断的检测烧写操作是否完成
	do
	{
		tmpData = *p;							//获取数据
		if ( ((tmpData ^ data) & 0x0080) == 0)	//若烧写成功,则tmpData 与 data的Bit7相同
			return 1;
		else{}
		
	}while ( (tmpData & 0x0020) == 0);		//若烧写还在进行,则tmpData的Bit5为0,否则完成
	
	return 0;
}

int WriteFlash(unsigned long addr, unsigned long length, unsigned short * p)
{
	unsigned long i = 0;
	
	if (NULL == p)
	{
		printf("Invalid polonger to buffer!\n");
		return 0;	
	}
	else{}
	
	if (addr > 0x8000)
	{
		printf("Invalid address, out of range.\n");
		return 0;
	}
	else{}
	
	if (addr + length > 0x8000)
	{
		printf("Invalid length, the biggest address is out of range.\n");
		return 0;
	}
	else{}
	
	UnlockBypass();			//进入unlock bypass模式
	
	for (i = 0; i < length * 2; i+=2)
	{
		if (UnlockByProgram(addr + i, *(p + i/2)) == 0)
		{
			UnlockByreset();
			printf("Program Failed!\n");
			return 0;
		}
		else{}
	}
	
	UnlockByreset();
	
	return length;
}

int WriteSector(unsigned long addr, unsigned short * p)
{
	unsigned long i;
	unsigned long length = 0;
	unsigned long sectorStartAddr = 0;		//块起始地址
	
	if (NULL == p)
	{
		printf("Invalid polonger to buffer!\n");
		return 0;	
	}
	else{}
	
	if (addr > 0x8000)
	{
		printf("Invalid address, out of range.\n");
		return 0;
	}
	else{}
	
	
	if ( (DM_CNT & 0x1F) != 7)				//若当前页不是第7页,则0页就是0块
	{
		length = 0x8000;					//一个块32KWord
		sectorStartAddr = 0;
	}
	else
	{
		if (addr < 0x4000)
		{
			length = 0x4000;				//一个块16KWord
			sectorStartAddr = 0;
		}
		else if (addr >= 0x4000 && addr < 0x6000)
		{
			length = 0x1000;				//一个块4KWord
			if (addr < 0x5000)
			{
				sectorStartAddr = 0x4000;
			}
			else
			{
				sectorStartAddr = 0x5000;
			}
		}
		else if (addr >= 0x6000 && addr < 0x8000)
		{
			length = 0x2000;				//一个块8KWord
			sectorStartAddr = 0x6000;
		}
		else
		{
			printf("Invalid address, out of range.\n");
			return 0;
		}
	}
	
	UnlockBypass();			//进入unlock bypass模式
	
	for (i = 0; i < length * 2; i+=2)
	{
		if (UnlockByProgram(sectorStartAddr + i, *(p + i/2)) == 0)
		{
			UnlockByreset();
			printf("Program Failed!\n");
			return 0;
		}
		else{}
	}
	
	UnlockByreset();
	
	return length;

}


int UnlockBypass(void)
{
	volatile unsigned short * p;
	unsigned char			 oldDmCnt;
	
	
	oldDmCnt = DM_CNT;		//保存DM_CNT当前值,即保存当前页号
	DM_PG(0);				//映射到FLASH第0页,因为对FLASH操作的命令地址都是相对于第0页的
	
	p 	= (volatile unsigned short *)FLASH_BASE + 0x555;
	*p	= 0xAA;
	
	p 	= (volatile unsigned short *)FLASH_BASE + 0x2AA;
	*p	= 0x55;
	
	p 	= (volatile unsigned short *)FLASH_BASE + 0x555;
	*p	= 0x20;
	
	DM_CNT = oldDmCnt;		//恢复到初始页
	
	return 1;
}

int UnlockByreset(void)
{
	volatile unsigned char * p;
	unsigned char			 oldDmCnt;
	
	
	oldDmCnt = DM_CNT;		//保存DM_CNT当前值,即保存当前页号
	DM_PG(0);			//映射到FLASH第0页,因为对FLASH操作的命令地址都是相对于第0页的

	
	p 	= (volatile unsigned char *)FLASH_BASE;
	*p 	= 0x90;
	
	p 	= (volatile unsigned char *)FLASH_BASE;
	*p	= 0x00;
	
	DM_CNT = oldDmCnt;		//恢复到初始页
	
	return 1;
}

int EraseSuspend(void)
{
	volatile unsigned char * p;
	unsigned char			 oldDmCnt;
	
	
	oldDmCnt = DM_CNT;		//保存DM_CNT当前值,即保存当前页号
	DM_PG(0);			//映射到FLASH第0页,因为对FLASH操作的命令地址都是相对于第0页的

	
	p 	= (volatile unsigned char *)FLASH_BASE + 0xAAA;
	*p	= 0xB0;
	
	DM_CNT = oldDmCnt;		//恢复到初始页
	
	return 1;
}
int EraseResume(void)
{
	volatile unsigned char * p;
	unsigned char			 oldDmCnt;
	
	
	oldDmCnt = DM_CNT;		//保存DM_CNT当前值,即保存当前页号
	DM_PG(0);				//映射到FLASH第0页,因为对FLASH操作的命令地址都是相对于第0页的
	p 	= (volatile unsigned char *)FLASH_BASE + 0xAAA;
	*p	= 0x30;
	
	DM_CNT = oldDmCnt;		//恢复到初始页

	return 1;
}

⌨️ 快捷键说明

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