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

📄 flash.c

📁 三星44B0的BOOTLOADER
💻 C
字号:
#include "../inc/44blib.h"


typedef struct {
	unsigned short * start;
	const unsigned int size;
} sector_t;

typedef struct {
	const char * name;
	const int manufactor;
	const int device_id;
	volatile unsigned short * CMD_ADDR0;
	volatile unsigned short * CMD_ADDR1;
	sector_t sector[6];
} flash_t;

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

flash_t * current_flash;



flash_t * flash_probe()
{
	int tmp, i;
	for (i=0; i<sizeof(flash_list)/sizeof(flash_list[0]); i++) {
		current_flash = flash_list + i;
		*current_flash->CMD_ADDR0 = 0xaaaa;
		*current_flash->CMD_ADDR1 = 0x5555;
		*current_flash->CMD_ADDR0 = 0x9090;
		tmp = *(unsigned short *)0;
		if (tmp == current_flash->manufactor) {
			tmp = *(unsigned short *)2;
			*current_flash->CMD_ADDR0 = 0xf0f0;
			if (tmp == current_flash->device_id)
				break;
		}
	}
	if (i == sizeof(flash_list)/sizeof(flash_list[0]))
		current_flash = 0;
	return current_flash;
}

int flash_erase(volatile unsigned short * addr)
{
	int count = 5000000;

	if (!current_flash)
		return 0;

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

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

int flash_write(volatile unsigned short * addr, const unsigned short * data, unsigned int len)
{
	int count;
	register unsigned short tmp, tmp2;
	if (!current_flash)
		return 0;

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



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

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

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

}

/******************************************************************************
【功能说明】从指定扇区begin开始,将size个来自指针data的数据编程到Flash
******************************************************************************/
int SectorProg(unsigned int begin, unsigned short *data, unsigned int size)
{
	unsigned int i, actual_size;
	while (size) {
		for (i=0; ; i++) {
			if (current_flash->sector[i].size == 0)
				return 1;
			if ((unsigned int)current_flash->sector[i+1].start > begin)
				break;
		}
		
		if (begin % current_flash->sector[i].size) {
			Uart_Printf("Unaligned sector, ignored!\n");
			return 1;
		}
		
		if (size < current_flash->sector[i].size)
			actual_size = size;
		else
			actual_size = current_flash->sector[i].size;
		
		Uart_Printf("Flash Erase 0x%06x ", begin);
		if (flash_erase((unsigned short *)begin))
			Uart_Printf("OK!\n");
		else {
			Uart_Printf("Failed!\n");
			return 1;
		}
		Uart_Printf("Flash Burn 0x%06x ", begin);
		if (flash_write((unsigned short *)begin, data, actual_size))
			Uart_Printf("OK!\n");
		else {
			//Uart_Printf("Failed!\n");
			return 1;
		}
		begin += current_flash->sector[i].size;
		data += current_flash->sector[i].size/2;
		size -= actual_size;
	}
	return 0;
}

⌨️ 快捷键说明

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