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

📄 am29lv160db.c

📁 非tffs格式的flash读写程序。其实大体格式都一样
💻 C
📖 第 1 页 / 共 3 页
字号:
  word value=0;

  if(numbytes == 0)
	 value = (word) strlen(buffer);
  else
	 value = numbytes;

  if (value & 0x0001)
	 value--; /* Need to make sure we don't overrun buffer */

  flash_write(sector, offset, buffer, value,TRUE);
  return (1);
}

/*********************************************************************/
/* flash_reset_ub() is required to remove the flash from unlock      */
/* bypass mode.  This is important, as other flash commands will be  */
/* ignored while the flash is in unlock bypass mode.                 */
/*********************************************************************/

byte flash_reset_ub(void)
{
  flash_command(FLASH_UBRESET,1,0,0);
  return(1);
}

/*********************************************************************/
/* Usefull funtion to return the number of sectors in the device.    */
/* Can be used for functions which need to loop among all the        */
/* sectors, or wish to know the number of the last sector.           */
/*********************************************************************/

void flash_get_numsectors(int *num)
{
/*  *num = meminfo->nsect;*/
  *num = meminfo.nsect;
}

/*********************************************************************/
/* flash_get_cfi() is the main CFI workhorse function.  Due to it's  */
/* complexity and size it need only be called once upon              */
/* initializing the flash system.  Once it is called, all operations */
/* are performed by looking at the meminfo structure.                */
/* All possible care was made to make this algorithm as efficient as */
/* possible.  90% of all operations are memory reads, and all        */
/* calculations are done using bit-shifts when possible              */
/*********************************************************************/

byte flash_get_cfi(struct cfi_query *query)
{
/*  word far *fwp;*/ /* flash window */
  word  *fwp;
  int volts=0, milli=0, temp=0, i=0;
  int num_secs=0, offset=0;

  flash_command(FLASH_RESET,0,0,0); /* Use sector 0 for all commands */
/*  flash_command(FLASH_AUTOSEL,0,0,0);*/
  flash_command(FLASH_CFIQUERY,0,0,0);/*bob*/

  fwp = (word *)get_flash_memptr(0);

  /* Initial house-cleaning */

  for(i=0; i < 8; i++) {
    query->erase_block[i].sector_size = 0;
    query->erase_block[i].num_sectors = 0;
  }

  query->query_string[0] = fwp[0x10];
  query->query_string[1] = fwp[0x11];
  query->query_string[2] = fwp[0x12];
  query->query_string[3] = '\0';

  /* If not 'QRY', then we dont have a CFI enabled device in the
	  socket */

  if( query->query_string[0] != 'Q' &&
    query->query_string[1] != 'R' &&
    query->query_string[2] != 'Y') {
    return(-1);
  }

  query->oem_command_set       = fwp[0x13];
  query->primary_table_address = fwp[0x15]; /* Important one! */
  query->alt_command_set       = fwp[0x17];
  query->alt_table_address     = fwp[0x19];

  /* We will do some bit translation to give the following values
	  numerical meaning in terms of C 'float' numbers */

/*  volts = ((fwp[0x1B] & 0xF0) >> 4);
  milli = (fwp[0x1B] & 0x0F);
  query->vcc_min = (float) (volts + ((float)milli/10));

  volts = ((fwp[0x1C] & 0xF0) >> 4);
  milli = (fwp[0x1C] & 0x0F);
  query->vcc_max = (float) (volts + ((float)milli/10));

  volts = ((fwp[0x1D] & 0xF0) >> 4);
  milli = (fwp[0x1D] & 0x0F);
  query->vpp_min = (float) (volts + ((float)milli/10));

  volts = ((fwp[0x1E] & 0xF0) >> 4);
  milli = (fwp[0x1E] & 0x0F);
  query->vpp_max = (float) (volts + ((float)milli/10));
*/
  /* Let's not drag in the libm library to calculate powers
	  for something as simple as 2^(power)
	  Use a bit shift instead - it's faster */

  temp = fwp[0x1F];
  query->timeout_single_write = (1 << temp);

  temp = fwp[0x20];
  if (temp != 0x00)
    query->timeout_buffer_write = (1 << temp);
  else
    query->timeout_buffer_write = 0x00;

  temp = 0;
  temp = fwp[0x21];
  query->timeout_block_erase = (1 << temp);

  temp = fwp[0x22];
  if (temp != 0x00)
    query->timeout_chip_erase = (1 << temp);
  else
    query->timeout_chip_erase = 0x00;

  temp = fwp[0x23];
  query->max_timeout_single_write = (1 << temp) *
  query->timeout_single_write;

  temp = fwp[0x24];
  if (temp != 0x00)
    query->max_timeout_buffer_write = (1 << temp) *
    query->timeout_buffer_write;
  else
    query->max_timeout_buffer_write = 0x00;

  temp = fwp[0x25];
  query->max_timeout_block_erase = (1 << temp) *
  query->timeout_block_erase;

  temp = fwp[0x26];
  if (temp != 0x00)
    query->max_timeout_chip_erase = (1 << temp) *
    query->timeout_chip_erase;
  else
    query->max_timeout_chip_erase = 0x00;

  temp = fwp[0x27];
  query->device_size = (long) (((long)1) << temp);

  query->interface_description = fwp[0x28];

  temp = fwp[0x2A];
  if (temp != 0x00)
    query->max_multi_byte_write = (1 << temp);
  else
    query->max_multi_byte_write = 0;

  query->num_erase_blocks = fwp[0x2C];

  for(i=0; i < query->num_erase_blocks; i++) {
    query->erase_block[i].num_sectors = fwp[(0x2D+(4*i))];
    query->erase_block[i].num_sectors++;

    query->erase_block[i].sector_size = (long) 256 *
                        ( (long)256 * fwp[(0x30+(4*i))] +
	 	                fwp[(0x2F+(4*i))] );													 ( (long)256 * fwp[(0x30+(4*i))] +
																		fwp[(0x2F+(4*i))] );
  }

  /* Store primary table offset in variable for clarity */
  offset = query->primary_table_address;

  query->primary_extended_query[0] = fwp[(offset)];
  query->primary_extended_query[1] = fwp[(offset + 1)];
  query->primary_extended_query[2] = fwp[(offset + 2)];
  query->primary_extended_query[3] = '\0';

  if( query->primary_extended_query[0] != 'P' &&
    query->primary_extended_query[1] != 'R' &&
    query->primary_extended_query[2] != 'I') {
    return(2);
  }

  query->major_version = fwp[(offset + 3)];
  query->minor_version = fwp[(offset + 4)];

  query->sensitive_unlock      = (byte) (fwp[(offset+5)] & 0x0F);
  query->erase_suspend         = (byte) (fwp[(offset+6)] & 0x0F);
  query->sector_protect        = (byte) (fwp[(offset+7)] & 0x0F);
  query->sector_temp_unprotect = (byte) (fwp[(offset+8)] & 0x0F);
  query->protect_scheme        = (byte) (fwp[(offset+9)] & 0x0F);
  query->is_simultaneous       = (byte) (fwp[(offset+10)] & 0x0F);
  query->is_burst              = (byte) (fwp[(offset+11)] & 0x0F);
  query->is_page               = (byte) (fwp[(offset+12)] & 0x0F);

  return(1);
}


unsigned char  *get_flash_memptr(int sector)
{
  if(sector==0)
    return (char*)0x70000000;
  else if(sector==1)
    return (char*)0x70002000;
  else if(sector==2)
    return (char*)0x70003000;
  else if(sector==3)
    return (char*)0x70004000;
  else if(sector>3&&sector<34)
    return (char*)(0x70000000+(sector-3)*0x8000);

}

/*******************************************************/
/*  bob_flash_write()  */
/*******************************************************/
int bob_flash_write(int sector, unsigned offset, byte *buf, 
                int nbytes, int ub)
{
/*	 word far *flashptr; *//* flash window */
/*	 word far *src, *dst;*/
	 word  *flashptr; /* flash window */
	 word  *src, *dst;
	 int stat;
	 int retry = 0, retried = 0;
	 time_t tm,tm1;

	 flashptr = (word *)get_flash_memptr(sector);
	 dst = flashptr + offset/2;   /* (byte offset) */
	 src = (word *)buf;

	 if ((nbytes | offset) & 1) {
		return -1;
	 }
again2:

	 /* Check to see if we're in unlock bypass mode */
         if (ub == FALSE)
		flashptr[0] = 0xF0;  /* reset device to read mode */

	 while ((stat = flash_status(flashptr)) == STATUS_BUSY) {}
	 if (stat != STATUS_READY) {
		return (byte *)src - buf;
	 }

	 while (nbytes > 0) {
		if (ub == FALSE){
		  flashptr[0x555] = 0xAA;      /* unlock 1 */
		  flashptr[0x2AA] = 0x55;      /* unlock 2 */
		}
		flashptr[0x555] = 0xA0;
		*dst = *src;
		/*tm=time(0);*/
		tm1=tm;
		while ((stat = flash_status(flashptr)) == STATUS_BUSY) 
		{/*	if ( (time(0)-tm1) >= 1 ) {
	        		printf(".");
	        		tm1=time(0);		
			}*/
		/*	printf(".");*/
		}
		if (stat != STATUS_READY) 
		{	printf("break at 0x%x\n",((byte *)src - buf));
			break;
		}
		nbytes -= 2;
		dst++;src++;
	 }

/*	 if (stat != STATUS_READY || nbytes != 0) {
		if (retry-- > 0) {
		  ++retried;
		  --dst, --src;   
		  goto again2;     
		}
		if (ub == FALSE)
                  flash_command(FLASH_RESET,sector,0,0);
	 }
*/
	 return (byte *)src - buf;
}

int bob_flash_verify(int sector, unsigned offset, byte *buf, 
                int nbytes, int ub)
{
	 word  *flashptr; /* flash window */
	 word  *src, *dst;
	 int i;
	 int stat;
	 flash_command(FLASH_SELECT,sector,0,0);
	 flashptr = (word *)get_flash_memptr(sector);
	 dst = flashptr + offset/2;   /* (byte offset) */
	 src = (word *)buf;
	 while ( nbytes > 0) {
		if (  *dst!=*src ) {
                printf("Address %p should be 0x%x,actrually =0x%x.\n", dst,*src,*dst  );
                break;
                }
		
		/*tm=time(0);*/
/*		tm1=tm;*/
		while ((stat = flash_status(flashptr)) == STATUS_BUSY) 
		{/*	if ( (time(0)-tm1) >= 1 ) {
	        		printf(".");
	        		tm1=time(0);		
			}*/
		/*	printf(".");*/
		}
		if (stat != STATUS_READY) 
		{	printf("break\n");
			break;
		}
		nbytes -= 2;
		dst++ ; src++;
	 }
	 return (byte *)src - buf;	
}

⌨️ 快捷键说明

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