欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

flash.c

32位嵌入式中常用NOR Flash的驱动函数包。内含多种Flash的驱动
C
字号:
/*
**************************************************************************************************
*
*
*
*
*
*
*
*
*************************************************************************************************
*/



#include "../inc/s4510b.h"
#include "..inc/serial.h"
#include "../inc/flash.h"
#include "../inc/brd.h"
typedef struct {
	INT16U * start;
	const INT32U size;
} sector_t;

typedef struct {
	const char * name;
	const INT32S manufactor;
	const INT32S device_id;
	volatile INT16U * CMD_ADDR0;
	volatile INT16U * CMD_ADDR1;
	sector_t sector[6];
} flashTpye;

flashTpye flash_list[] = {
	{
		"SST39VF160",
		0xbf,
		0x2782,
		(volatile INT16U *)(ROM_BASE + 0x5555*2),
		(volatile INT16U *)(ROM_BASE + 0x2aaa*2),
		{
			{(INT16U *)(ROM_BASE + 0x000000), 0x1000},
			{(INT16U *)(ROM_BASE + 0x200000), 0}
		}
	},
	{
		"SST39VF1601",
		0xbf,
		0x234B,
		(volatile INT16U *)(ROM_BASE + 0x5555*2),
		(volatile INT16U *)(ROM_BASE + 0x2aaa*2),
		{
			{(INT16U *)ROM_BASE + 0x000000, 0x1000},
			{(INT16U *)ROM_BASE + 0x200000, 0}
		}
	},
	{
		"MX29LV160T",
		0xc2,
		0x22c4,
		(volatile INT16U *)(ROM_BASE + 0x555*2),
		(volatile INT16U *)(ROM_BASE + 0x2aa*2),
		{
			{ (INT16U *)ROM_BASE + 0x000000, 0x10000 },
			{ (INT16U *)ROM_BASE + 0x1f0000, 0x8000 },
			{ (INT16U *)ROM_BASE + 0x1f8000, 0x2000 },
			{ (INT16U *)ROM_BASE + 0x1fa000, 0x2000 },
			{ (INT16U *)ROM_BASE + 0x1fc000, 0x4000 },
			{ (INT16U *)ROM_BASE + 0x200000, 0 }
		}
	},
	{
		"MX29LV160B",
		0xc2,
		0x2249,
		(volatile INT16U *)(ROM_BASE + 0x555*2),
		(volatile INT16U *)(ROM_BASE + 0x2aa*2),
		{
			{ (INT16U *)ROM_BASE + 0x000000, 0x4000 },
			{ (INT16U *)ROM_BASE + 0x004000, 0x2000 },
			{ (INT16U *)ROM_BASE + 0x006000, 0x2000 },
			{ (INT16U *)ROM_BASE + 0x008000, 0x8000 },
			{ (INT16U *)ROM_BASE + 0x010000, 0x10000 },
			{ (INT16U *)ROM_BASE + 0x200000, 0 }
		}
	}
};

flashTpye * currentFlash;



flashTpye * flash_probe()
{
	INT32S tmp, i;
	for (i=0; i<sizeof(flash_list)/sizeof(flash_list[0]); i++) {
		currentFlash = flash_list + i;
		*currentFlash->CMD_ADDR0 = 0xaaaa;
		*currentFlash->CMD_ADDR1 = 0x5555;
		*currentFlash->CMD_ADDR0 = 0x9090;
		tmp = *(INT16U *)ROM_BASE;  						/*modified by hojin*/
		if (tmp == currentFlash->manufactor) {
			tmp = *(INT16U *)(ROM_BASE + 2); 				/*modified by hojin*/
			*currentFlash->CMD_ADDR0 = 0xf0f0;
			if (tmp == currentFlash->device_id)
				break;
		}
	}
	if (i == sizeof(flash_list)/sizeof(flash_list[0]))
		currentFlash = 0;
	return currentFlash;
}

INT32S flash_erase(volatile INT16U * addr)
{
	INT32S count = 5000000;

	if (!currentFlash)
		return 0;

	*currentFlash->CMD_ADDR0 = 0xaaaa;
	*currentFlash->CMD_ADDR1 = 0x5555;
	*currentFlash->CMD_ADDR0 = 0x8080;
	*currentFlash->CMD_ADDR0 = 0xaaaa;
	*currentFlash->CMD_ADDR1 = 0x5555;
	*addr = 0x3030;

	while (--count && ((*addr & 0xff) != 0xff));
	
	return count;
}

INT32S flash_write(volatile INT16U * addr, const INT16U * data, INT32U len)
{
	INT32S count;
	register INT16U tmp, tmp2;
	if (!currentFlash)
		return 0;

	len = (len+1)/2;
	while (len--) {
		tmp = *data;
		*currentFlash->CMD_ADDR0 = 0xaaaa;
		*currentFlash->CMD_ADDR1 = 0x5555;
		*currentFlash->CMD_ADDR0 = 0xa0a0;
		*addr = tmp;
		count = 10000;
		while (--count && ((tmp2=*addr) != tmp));
		if (count == 0)
			break;
		addr++;
		data++;
	}
	
	
	if (count == 0)
		urtPrintf("Failed @ 0x%06x, req: 0x%04x, act: 0x%04x, now: 0x%04x\n", addr, (unsigned)*data, (unsigned)tmp2, (unsigned)*addr);
	return count;
}



/******************************************************************************
【功能说明】获取Falsh的ID号
******************************************************************************/
INT32U GetFlashID(void)
{
	flashTpye * flash;
	flash = flash_probe();
	if (flash) {
		urtPrintf("FLASH Type: %s\n", flash->name);
		return (flash->manufactor<<16 | flash->device_id);
	}
	urtPrintf("Unsupported Flash, ID=0x%08x!\n", flash->manufactor<<16 | flash->device_id);
	return 0;
}

/******************************************************************************
【功能说明】从Flash指定地址Readstart开始读取Size个数据到DataPtr
******************************************************************************/
void FlashRead(INT32U ReadStart, INT16U *DataPtr, INT32U Size)
{
	INT32S i;

	for(i=0; i<Size/2; i++)
		DataPtr[i] = ((INT16U *)ReadStart)[i];

}

/******************************************************************************
[Function:] write size data from (*data) to (beging) sector.
note: beginning sectors.
******************************************************************************/
INT32S SectorProg(INT32U begin, INT16U *data, INT32U size)
{
	INT32U i, actual_size,tempSize;
	urtPrintf("\n     Complete");
	tempSize = size;
	while (size) {
		for (i=0; ; i++) {
			if (currentFlash->sector[i].size == 0)
				return FAIL;
			if ((INT32U)currentFlash->sector[i+1].start > begin)
				break;
		}
		
		if (begin % currentFlash->sector[i].size) {
			urtPrintf("Unaligned sector, ignored!\n");
			return FAIL;
		}
		
		if (size < currentFlash->sector[i].size)
			actual_size = size;
		else
			actual_size = currentFlash->sector[i].size;
		
	/*	urtPrintf("Flash Erase 0x%06x ", begin);  */
		if (flash_erase((INT16U *)begin)){
	/*		urtPrintf("OK!\n");  */}
		else {
			urtPrintf("Erase Failed!\n");
			return FAIL;
		}
	/*	urtPrintf("Flash Burn 0x%06x ", begin);  */
		if (flash_write((INT16U *)begin, data, actual_size)){
	/*		urtPrintf("OK!\n");  */}
		else {
			urtPrintf("Write Failed!\n");
			return FAIL;
		}
		begin += currentFlash->sector[i].size;
		data += currentFlash->sector[i].size/2;
		size -= actual_size;
		urtPrintf("\r%3d%%",(100-((size *100)/tempSize)) );
	}
	urtPrintf("\n");
	return PASS;
}

⌨️ 快捷键说明

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