📄 am29lv160db.c
字号:
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&§or<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 + -