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

📄 flash.c

📁 c8051f310xmodembootloader.rar
💻 C
字号:
/*****************************************
*
*
*****************************************/
#include <reg52.h>
#include <string.h>
#include <intrins.h>
#include <stdio.h>
#include <absacc.h>
#include "FlashRam.h"

unsigned char xdata eeprom[0x2000]  _at_ 0x0000;
unsigned char xdata pageSel         _at_ 0x6000;

unsigned char data FlashType;	// Flash型号
unsigned long fAddr = 0;

extern void dog();
//=========================================
//
//=========================================
void Check_Toggle_Ready(unsigned int addr)
{
	unsigned char data preTmp;
	unsigned char data currTmp;
	preTmp = eeprom[addr] & 0x40;
	while(1)
	{
		currTmp = eeprom[addr] & 0x40;
		if (preTmp == currTmp)
		{
			break;
		}
		preTmp = currTmp;
	}
}

//=========================================
// 解锁SST28SF040A
//=========================================
void eepUnlock(void)
{
	unsigned char data tmp;
	tmp = eeprom[0x1823];
	tmp = eeprom[0x1820];
	tmp = eeprom[0x1822];
	tmp = eeprom[0x0418];
	tmp = eeprom[0x041B];
	tmp = eeprom[0x0419];
	tmp = eeprom[0x041A];
}

//=========================================
// 读取器件ID
// 成功: 返回1,否则返回0
//=========================================
char eepGetChipId(void)
{
	unsigned char data cId[2];
	pageSel = 0x00;		// 页址

	eeprom[0] = 0xff;	// reset command
	_nop_();
	eeprom[0] = 0x90;	// read id
	_nop_();
	cId[0] = eeprom[0];
	cId[1] = eeprom[1];
	eeprom[0] = 0xff;
	if ((cId[0] == 0xbf) && (cId[1] == 0x04))
	{
		eepUnlock();
		FlashType = cId[1];
		return 1;
	}

	eeprom[0] = 0xf0;	// 取消所有操作
	_nop_();
	_nop_();
	eeprom[0x0555] = 0xAA;
	eeprom[0x02AA] = 0x55;
	eeprom[0x0555] = 0x90;		// Software ID Entry Command
	_nop_();			// Wait TIDA
	_nop_();
	cId[0] = eeprom[0x0000];		// Manufacturer’s ID = BFH
	cId[1] = eeprom[0x0001];	// SST29SF040 Device ID = 13H

	eeprom[0x0555] = 0xAA;
	eeprom[0x02AA] = 0x55;
	eeprom[0x0555] = 0xF0;		// Software ID Entry Command
	_nop_();			// Wait TIDA
	if (cId[0] == 0xbf)
	{
		FlashType = cId[1];
		return 1;
	}
	FlashType = NONE_FLASH;
	return 0;
}
//=========================================
//
//=========================================
void eepEraseChip(void)
{
	pageSel = 0;
	switch(FlashType)
	{
		case SST28SF040A:
			eeprom[0] = 0x30;
			eeprom[0] = 0x30;
			Check_Toggle_Ready(0);
			break;
		case SST29SF040:
			eeprom[0x0555] = 0xAA;
			eeprom[0x02AA] = 0x55;
			eeprom[0x0555] = 0x80;
			eeprom[0x0555] = 0xAA;
			eeprom[0x02AA] = 0x55;
			eeprom[0x0555] = 0x10;
			Check_Toggle_Ready(0);
			break;
		default:
			break;
	}
	
}

//==================================================
// 擦除扇区
// input:   扇区起始地址
// output: 1=成功
//==================================================
char eepEraseSector(unsigned int addr)
{
	unsigned char data try;
	int data cnt, block_size;
	unsigned data addr_mask;
	try = 0;
	while (try<3)
	{
		switch(FlashType)
		{
			case SST28SF040A:
				addr_mask=0x1f00;
				addr=addr&0x1f00;
				block_size = 256;

				eeprom[addr] = 0x20;
				eeprom[addr] = 0xD0;
				Check_Toggle_Ready(addr);
				break;

			case SST29SF040:
				addr_mask=0x1f80;
				addr=addr&0x1f80;
				block_size=128;

				eeprom[0x0555] = 0xAA;
				eeprom[0x02AA] = 0x55;
				eeprom[0x0555] = 0x80;
				eeprom[0x0555] = 0xAA;
				eeprom[0x02AA] = 0x55;
				eeprom[addr] = 0x20;
				Check_Toggle_Ready(addr);
				break;
			default:
				return 0;  // 失败
		}

		for (cnt=0; cnt<block_size; cnt++)
		{
			if (eeprom[addr&addr_mask + cnt] != 0xff)		// 检查扇区是否全部擦空
			{
				break;
			}
		}
		if ( cnt > block_size-1)
		{
			return 1;
		}
		++try;			// 未擦空,重擦
	}
	return 0;
}
//=========================================
// 字节编程
// input:   addr=地址
//          dat=数据
// output:   ---
//=========================================
void eepProgramByte(unsigned int addr,unsigned char dat)
{
	switch(FlashType)
	{
		case SST28SF040A:
			eeprom[addr] = 0x10;		// AUTO_PGRM
			eeprom[addr] = dat;
			Check_Toggle_Ready(addr);
			break;
		case SST29SF040:
			eeprom[0x0555] = 0xAA;
			eeprom[0x02AA] = 0x55;
			eeprom[0x0555] = 0xA0;
			eeprom[addr] = dat;
			Check_Toggle_Ready(addr);
			break;
		default:
			break;
	}
}
//=========================================
//
//=========================================
unsigned char eepReadByte(unsigned long addr)
{
	pageSel = (unsigned char)(addr>>13);
	return (eeprom[addr&0x1fff]);
}

//=========================================
//
//=========================================
void eepWriteRam(unsigned long addr,unsigned char dat)
{
	bit _ea_save;
	int block_size;
	_ea_save = EA;

	EA = 0;
	switch (FlashType)
	{
		case SST28SF040A:
			block_size=256;
			break;
		case SST29SF040:
			block_size=128;
			break;
		default:
			EA = _ea_save;
			return;
	}
	pageSel = (unsigned char)(addr>>13);		// 页选

	if (eeprom[addr&0x1fff] != 0xff)		// 数据不为空
	{
		int data cnt;
		unsigned char xdata tmpBuffer[256];
		unsigned int mask;

		if (FlashType == SST28SF040A)mask=0x1f00;
		else mask=0x1f80;

		for (cnt=0; cnt<block_size; cnt++)
		{
			tmpBuffer[cnt] = eeprom[ addr&mask + cnt];	// 读
		}

		eepEraseSector(addr);		// 擦除扇区
		
//		DOG = !DOG;
		dog();
		if (FlashType == SST28SF040A)tmpBuffer[addr&0x00ff] = dat;		// 改
		else tmpBuffer[addr&0x007f] = dat;

		for (cnt=0; cnt<block_size; cnt++)
		{
			eepProgramByte(addr&mask + cnt, tmpBuffer[cnt]);	// 写
		}
	}
	else	// 直接写入
	{
		eepProgramByte(addr & 0x1fff, dat);
	}

	EA = _ea_save;
}

//=========================================
//
//=========================================
void eepWrite(unsigned long addr,unsigned char dat)
{
	bit _ea_save;
	unsigned char mask;
	_ea_save = EA;
	EA = 0;
	pageSel = (unsigned char)(addr>>13);		// 页选

	if (FlashType==SST28SF040A)mask=0xff;
	else mask=0x7f;
	if ((addr&mask)==0)
	{
		eepEraseSector(addr);		// 擦除扇区
	}
	dog();
	eepProgramByte(addr & 0x1fff, dat);
	EA = _ea_save;
}

int fopen(void)
{
	fAddr = 0;
	if (FlashType != NONE_FLASH)
		return 1;
	return -1;
}

int fread(unsigned char *buff, int len)
{
	int rlen;
	int cnt;

	if (fAddr>0x7ffff)return -1;

	rlen = 0;
	for (cnt=0; cnt<len; cnt++)
	{
		++rlen;
		buff[cnt] = eepReadByte(fAddr++);
		if (fAddr>0x7ffff)break;
	}
	return rlen;
}

int fwrite(unsigned char *buff, int len)
{
	int wlen;
	int cnt;
	if (fAddr>0x7ffff)return -1;
	wlen = 0;
	for (cnt=0; cnt<len; cnt++)
	{
		eepWrite(fAddr, buff[cnt]);
		
		++wlen;
		++fAddr;
		if (fAddr>0x7ffff)break;
	}
	return wlen;
}
void fclose(void)
{
	fAddr=0;
}

⌨️ 快捷键说明

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