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

📄 at49bv040aflashwritesector.c

📁 这是一段AT49BV040Aflsh的驱动程序
💻 C
字号:
#include "stdio.h"
#include "stdlib.h"
/*  
外部提供的函数:
    参数:无
    返回值:
           0:空闲
           1:忙
          -1:设备没有成功初始化
*/
int getflashAT49BV040AStatus();


/*
外部提供的函数:
     参数:
           offset:FLASH偏移
           data:要写的数据
     返回值:
            0:成功
           -1:设备没有初始化成功
*/
int writeflashAT49BV040A(unsigned long offset,unsigned char data);


/*
外部提供的函数:
     参数:
          offset:偏移地址
     返回值:
           读回的值
*/
unsigned char readflashAT49BV040A(unsigned long offset);


/*延时函数*/
static void flashDelay( unsigned long Tns )
{
    unsigned long i;
    for (i=0; i<Tns; i++)
		 ;
}

/*延时1000 纳秒(即1us)*/
#define FS_FLASH_DELAY_TIME  200

/*延时1ms*/
#define FS_FLASH_TASKDELAY_TIME  200000

/*BOOTBLOCK段*/
#define FS_FLASH_BOOT_BLOCK_START_ADDRESS (0x00000000)
#define FS_FLASH_BOOT_BLOCK_ADDRESS(sn) (FS_FLASH_BOOT_BLOCK_START_ADDRESS + (sn) * FS_FLASH_BOOT_BLOCK_SIZE)
#define FS_FLASH_BOOT_BLOCK_SIZE   (16 * 1024)
#define FS_FLASH_BOOT_BLOCK_COUNT   1
#define FS_BOOT_BLOCK_SIZE (FS_FLASH_BOOT_BLOCK_SIZE * FS_FLASH_BOOT_BLOCK_COUNT)

/*PARAMETERBLOCK段*/
#define FS_FLASH_PARAMETER_BLOCK_START_ADDRESS (0x00004000)
#define FS_FLASH_PARAMETER_BLOCK_ADDRESS(sn) (FS_FLASH_PARAMETER_BLOCK_START_ADDRESS + (sn) * FS_FLASH_PARAMETER_BLOCK_SIZE)
#define FS_FLASH_PARAMETER_BLOCK_SIZE   (8 * 1024)
#define FS_FLASH_PARAMETER_BLOCK_COUNT   2
#define FS_PARAMETER_BLOCK_SIZE (FS_FLASH_SECTOR_SIZE * FS_FLASH_SECTOR_COUNT)

/*32KMAINMEMORYBLOCK段*/
#define FS_FLASH_MAINMEMORY_32K_BLOCK_START_ADDRESS (0x00008000)
#define FS_FLASH_MAINMEMORY_32K_BLOCK_ADDRESS(sn) (FS_FLASH_MAINMEMORY_32K_BLOCK_START_ADDRESS + (sn) * FS_FLASH_MAINMEMORY_32K_BLOCK_SIZE)
#define FS_FLASH_MAINMEMORY_32K_BLOCK_SIZE   (32 * 1024)
#define FS_FLASH_MAINMEMORY_32K_BLOCK_COUNT   1
#define FS_MAINMEMORY_32K_BLOCK_SIZE (FS_FLASH_MAINMEMORY_32K_BLOCK_SIZE * FS_FLASH_MAINMEMORY_32K_BLOCK_COUNT)

/*64KMAINMEMORYBLOCK段*/
#define FS_FLASH_MAINMEMORY_64K_BLOCK_START_ADDRESS (0x00010000)
#define FS_FLASH_MAINMEMORY_64K_BLOCK_ADDRESS(sn) (FS_FLASH_MAINMEMORY_64K_BLOCK_START_ADDRESS + (sn) * FS_FLASH_MAINMEMORY_64K_BLOCK_SIZE)
#define FS_FLASH_MAINMEMORY_64K_BLOCK_SIZE   (64 * 1024)
#define FS_FLASH_MAINMEMORY_64K_BLOCK_COUNT   7
#define FS_MAINMEMORY_64K_BLOCK_SIZE (FS_FLASH_MAINMEMORY_64K_BLOCK_SIZE * FS_FLASH_MAINMEMORY_64K_BLOCK_COUNT)

/*
  Boot Block Programing Lockout, 返回0成功
*/
static int flashAT49BV040ABootBlockLockout()
{
	    volatile unsigned long addr;
      unsigned char  lockout;
      
      addr=0x555;
      lockout=0xAA;
      writeflashAT49BV040A(addr,lockout);
      
      addr=0xAAA;
      lockout=0x55;
      writeflashAT49BV040A(addr,lockout);
      
      addr=0x555;
      lockout=0x80;
      writeflashAT49BV040A(addr,lockout);
      
      addr=0x555;
      lockout=0xAA;
      writeflashAT49BV040A(addr,lockout);
      
      addr=0xAAA;
      lockout=0x55;
      writeflashAT49BV040A(addr,lockout);
      
      addr=0x555;
      lockout=0x40;
      writeflashAT49BV040A(addr,lockout);
      
      /*延时1ns*/
      flashDelay(1000*FS_FLASH_TASKDELAY_TIME);
      return 0;      
}

/*
 进入SoftwareProductIdentification模式,检查Boot Block 是否加锁
 返回1:已经加锁
 返回0:没有加锁
*/
static int flashAT49BV040ABootBlockLockoutDetection()
{
	  volatile unsigned long addr;
      unsigned char cmd;
      unsigned char lockoutdetection;
      
      addr=0x555;
      cmd=0xAA;
      writeflashAT49BV040A(addr,cmd);
      
      addr=0xAAA;
      cmd=0x55;
      writeflashAT49BV040A(addr,cmd);
      
      addr=0x555;
      cmd=0x90;
      writeflashAT49BV040A(addr,cmd);
      
      addr=0x00002;
      lockoutdetection=readflashAT49BV040A(addr);
      if(!(lockoutdetection&(0x01)))
      	return 0;
      else
      	return 1;
}
/*
 退出SoftwareProductIdentification模式,进入标准操作模式,返回0成功
*/
static int flashAT49BV040AExitSoftwareProductIdentificationMode()
{
      volatile unsigned long addr;
      unsigned char cmd;

      addr=0x555;
      cmd=0xAA;
      writeflashAT49BV040A(addr,cmd);
      
      addr=0xAAA;
      cmd=0x55;
      writeflashAT49BV040A(addr,cmd);
      
      addr=0x555;
      cmd=0xF0;
      writeflashAT49BV040A(addr,cmd);
      
      return 0;
}

/*擦除指定段,成功返回0*/
static int flashAT49BV040A_block_erase(int block)
{ 
	volatile unsigned long addr;
    unsigned char cmd;
    unsigned long SA;
    unsigned char readdata;
	int start;
  
if(block==1)
	{
	  SA=FS_FLASH_BOOT_BLOCK_START_ADDRESS;
	}
else if((block>=2)&&(block<=3))
	{
	  SA=(FS_FLASH_PARAMETER_BLOCK_START_ADDRESS+((block-2)*FS_FLASH_PARAMETER_BLOCK_SIZE));
	}
else if(block==4)
	{
	  SA=FS_FLASH_MAINMEMORY_32K_BLOCK_START_ADDRESS;
	}
else
	{
	  SA=(FS_FLASH_MAINMEMORY_64K_BLOCK_START_ADDRESS+((block-5)*FS_FLASH_MAINMEMORY_64K_BLOCK_SIZE));
	}
				 
			  
			addr=0x555;
			cmd=0xAA;
			writeflashAT49BV040A(addr,cmd);
			
			addr=0xAAA;
			cmd=0x55;
			writeflashAT49BV040A(addr,cmd);
			
			addr=0x555;
			cmd=0x80;
			writeflashAT49BV040A(addr,cmd);
			
			addr=0x555;
			cmd=0xAA;
			writeflashAT49BV040A(addr,cmd);
			
			addr=0xAAA;
			cmd=0x55;
			writeflashAT49BV040A(addr,cmd);
			
			
			addr=SA;
			cmd=0x30;
			writeflashAT49BV040A(addr,cmd);

			flashDelay(1200*FS_FLASH_TASKDELAY_TIME);

			/*最大延时12s,检查擦数据是否完成*/
			readdata=readflashAT49BV040A(addr);
			start=120;
			while(!(readdata&(0x40)))
			{
				flashDelay(100*FS_FLASH_TASKDELAY_TIME);
                readdata=readflashAT49BV040A(addr);
				if(start--==0)
				{
					printf("Flash erase failly at block %d\n", block);
			        return -1;
				}
			}
			return 0;
}


/*
   向FLASH中写一个8位的数据,返回0成功,-1超时,-2该sector没有擦除
*/
static int flashAT49BV040A_program_chardata(unsigned long dest,unsigned char data)
{
  volatile unsigned long addr;
  unsigned char cmd;
  unsigned char readdata;
  int start;
  
  addr=dest;
  readdata=readflashAT49BV040A(addr);
  if((readdata&data)!=data)
  	return (-2);
  	
    addr=0x555;
    cmd=0xAA;
	writeflashAT49BV040A(addr,cmd);
	
	addr=0xAAA;
    cmd=0x55;
	writeflashAT49BV040A(addr,cmd);
	
	addr=0x555;
    cmd=0xA0;
	writeflashAT49BV040A(addr,cmd);
	
	addr=dest;
	cmd=data;
	writeflashAT49BV040A(addr,cmd);

	flashDelay(50*FS_FLASH_DELAY_TIME);

	/*最大延时1ms,来检查写数据是否正确*/
	start=20;
    readdata=readflashAT49BV040A(addr);
	while(readdata^data)
	{
		flashDelay(50*FS_FLASH_DELAY_TIME);
		readdata=readflashAT49BV040A(addr);
		if(start--==0)
		 return -1;
	}
    return (0);
}
/*
  向block写入一段数据,返回0成功
*/
static int flashAT49BV040A_sector_programmedata(int block,const unsigned char*pBuf)
{
	unsigned long addr;
	unsigned char data;
	unsigned long i, rc;
	unsigned long SA;
	unsigned long blocksize;
	
	 
	    if(block==1)
	    	{
	        SA=FS_FLASH_BOOT_BLOCK_START_ADDRESS;
	       	blocksize=16 * 1024;
	      }
			else if((block>=2)&&(block<=3))
				{
			    SA=(FS_FLASH_PARAMETER_BLOCK_START_ADDRESS+((block-2)*FS_FLASH_PARAMETER_BLOCK_SIZE));
			   	blocksize=8 * 1024;
			  }
			else if(block==4)
				{
			   SA=FS_FLASH_MAINMEMORY_32K_BLOCK_START_ADDRESS;
			   blocksize=32 * 1024;
			  }
			else
				{
				 SA=(FS_FLASH_MAINMEMORY_64K_BLOCK_START_ADDRESS+((block-5)*FS_FLASH_MAINMEMORY_64K_BLOCK_SIZE));
				 blocksize=64 * 1024;
				}
	
	
	addr=SA;	
			
	for (i = 0;i<blocksize;i+=1)
	{
		data = pBuf[i];
		rc = flashAT49BV040A_program_chardata(addr,data);
		if (rc != 0) 
		{
			return (rc);
		}
		addr += 1;
	}
	
 return 0;
}
/*
提供给外部使用的函数
     参数:
          block:段号
          const unsigned char*PData:要写的数据
     返回值:
          2:Boot Block lockout
          1:flash设备忙
          0:成功返回
         -1:flash擦除失败
         -2:向flash写数据失败
         -3:段号超过范围
*/
int flashAT49BV040AwriteSector(int block, const unsigned char*PData)
{
if(getflashAT49BV040AStatus()!=0)
	{
		   printf("flash is busy now!\n");
		   return  1;
	}
else if((block==1)&&(flashAT49BV040ABootBlockLockoutDetection()==1))
	{
		  flashAT49BV040AExitSoftwareProductIdentificationMode();
		  printf("Boot Block Lockout!\n");
		  return 2;
	}
else if((block>11)||(block<1))
	{
		   printf("the number of block can not larger than 11,smaller than 1!\n");
		   return -3;
	}
 
else if(flashAT49BV040A_block_erase(block)!=0)
	{
		   return -1;
	}
else if(flashAT49BV040A_sector_programmedata(block,PData)!=0)
	{
			printf("program flash failly at block %d/n",block);
			return -2;
	}
else
		return 0;
}
					

⌨️ 快捷键说明

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