flash_amd.c
来自「ADS下的bios工程」· C语言 代码 · 共 712 行 · 第 1/2 页
C
712 行
else if (t & 0x40) { if (d & 0x20) { /* timeout */ return STATUS_TIMEOUT; } else { return STATUS_BUSY; } } if (retry--) goto again; /* may have been write completion */ return STATUS_ERROR;}/*********************************************************************//* BEGIN API WRAPPER FUNCTIONS *//*********************************************************************//* Flash_sector_erase() will erase a single sector dictated by the *//* sector parameter. *//* Note: this function will merely BEGIN the erase program. Code *//* execution will immediately return to the calling function *//*********************************************************************/unsigned char flash_sector_erase(unsigned char sector){ flash_command(FLASH_SERASE,sector,0,0); return(1);}/*********************************************************************//* Flash_sector_erase_int() is identical to flash_sector_erase(), *//* except it will wait until the erase is completed before returning *//* control to the calling function. This can be used in cases which *//* require the program to hold until a sector is erased, without *//* adding the wait check external to this function. *//*********************************************************************/unsigned char flash_sector_erase_int(unsigned char sector){ int stat; flash_command(FLASH_SERASE,sector,0,0); while ((stat = flash_status(get_flash_memptr(sector))) == STATUS_BUSY) { } if (stat != STATUS_READY) { dbgout("%s[%d] : status(%x)\n", __FUNCTION__, __LINE__, stat); return (unsigned char)stat; /* ??? */ } return(1);}/*********************************************************************//* flash_reset() will reset the flash device to reading array data. *//* It is good practice to call this function after autoselect *//* sequences had been performed. *//*********************************************************************/unsigned char flash_reset(void){ flash_command(FLASH_RESET, 1, 0, 0); /* ???(0) */ return(1);}/*********************************************************************//* flash_get_device_id() will perform an autoselect sequence on the *//* flash device, and return the device id of the component. *//* This function automatically resets to read mode. *//*********************************************************************/unsigned short flash_get_device_id(unsigned char sector){ unsigned short *fwp; /* flash window */ unsigned short answer; fwp = (unsigned short *)get_flash_memptr(sector); flash_command(FLASH_AUTOSEL,sector,0,0); fwp++; answer = *fwp; flash_command(FLASH_RESET,sector,0,0); /* just to be safe */ return( (unsigned short) answer );}/*********************************************************************//* flash_get_manuf_code() will perform an autoselect sequence on the *//* flash device, and return the manufacturer code of the component. *//* This function automatically resets to read mode. *//*********************************************************************/unsigned char flash_get_manuf_code(unsigned char sector){ unsigned short *fwp; /* flash window */ unsigned short answer; fwp = (unsigned short *)get_flash_memptr(sector); flash_command(FLASH_AUTOSEL,sector,0,0); answer = *fwp; flash_command(FLASH_RESET,sector,0,0); /* just to be safe */ return( (unsigned char) (answer & 0x00FF) );}/*********************************************************************//* flash_sector_protect_verify() performs an autoselect command *//* sequence which checks the status of the sector protect CAM *//* to check if the particular sector is protected. Function will *//* return a '0' is the sector is unprotected, and a '1' if it is *//* protected. *//*********************************************************************/unsigned char flash_sector_protect_verify(unsigned char sector){ volatile unsigned short *fwp; /* flash window */ unsigned char answer; fwp = (volatile unsigned short *)get_flash_memptr(sector); flash_command(FLASH_AUTOSEL,sector,0,0); fwp += ((meminfo->sec[sector].base)/2); fwp += 2; answer = (unsigned char) (*fwp & 0x0001); /* Only need DQ0 to check */ flash_command(FLASH_RESET,sector,0,0); return( (unsigned char) answer );}/*********************************************************************//* flash_get_status() will return the current operational status of *//* the flash device. A list of return codes is outlined in flash.h *//* Note: for DL parts, status will be bank dependent. *//*********************************************************************/unsigned char flash_get_status(unsigned char sector){ unsigned short *fwp; fwp = (unsigned short *)get_flash_memptr(sector); return flash_status(fwp);}/*********************************************************************//* flash_chip_erase() will perform a complete erasure of the flash *//* device. *//*********************************************************************/unsigned char flash_chip_erase(unsigned char sector){ flashptr = (unsigned short *)get_flash_memptr(sector); flashptr[0] = 0xF0; /* reset device to read mode */ flash_command(FLASH_CERASE,sector,0,0); return(1);}/*********************************************************************//* flash_write_word() will program a single word of data at the *//* specified offset from the beginning of the sector parameter. *//* Note: this offset must be word aligned, or else errors are *//* possible (this can happen when dealing with odd offsets due to *//* only partial programming. *//* Note: It is good practice to check the desired offset by first *//* reading the data, and checking to see if it contains 0xFFFF *//*********************************************************************/unsigned char flash_write_word(unsigned char sector, unsigned short offset, unsigned short data){ flash_command(FLASH_PROG, sector, offset, data); return (1);}/*********************************************************************//* flash_read_word() reads a single word of data from the specified *//* offset from the sector parameter. This function will auto align *//* the offset to return word data. *//*********************************************************************/unsigned short flash_read_word(unsigned char sector, unsigned short offset){ unsigned short *fwp; flash_command(FLASH_SELECT,sector,0,0); fwp = (unsigned short *)get_flash_memptr(sector); if (offset & 0x0001){ /* Is odd? *//* ??? */ offset--; } fwp += offset; return( (unsigned short) *fwp );}/*********************************************************************//* flash_write_string() functions like flash_write_word(), except *//* that it accepts a pointer to a buffer to be programmed. This *//* function will align the data to a word offset, then bulk program *//* the flash device with the provided data. *//* The maximum buffer size is currently only limited to the data *//* size of the numbytes parameter (which in the test system is *//* 16 bits = 65535 words *//* Since the current maximum flash sector size is 64kbits, this *//* should not present a problem. *//*********************************************************************/unsigned char flash_write_string(unsigned char sector, unsigned short offset, unsigned char *buffer, unsigned int numbytes){ unsigned int value=0; if(numbytes == 0) value = (unsigned int) strlen(buffer); else value = numbytes; if (value & 0x0001) value--; /* Need to make sure we don't overrun buffer */ flash_write(sector, offset, buffer, value, FALSE); return (1);}/*********************************************************************//* flash_erase_suspend() will suspend an erase process in the *//* specified sector. Array data can then be read from other sectors *//* (or any other sectors in other banks), and the erase can be *//* resumed using the flash_erase_resume function. *//* Note: multiple sectors can be queued for erasure, so long as the *//* 80 uS erase suspend window has not terminated (see AMD data sheet *//* concerning erase_suspend restrictions). *//*********************************************************************/unsigned char flash_erase_suspend(unsigned char sector){ flash_command(FLASH_ESUSPEND, sector, 0, 0); return (1);}/*********************************************************************//* flash_erase_resume() will resume all pending erases in the bank *//* in which the sector parameter is located. *//*********************************************************************/unsigned char flash_erase_resume(unsigned char sector){ flash_command(FLASH_ERESUME, sector, 0, 0); return (1);}/*********************************************************************//* flash_get_sector_size() is provided for cases in which the size *//* of a sector is required by a host application. The sector size *//* (in bytes) is returned in the data location pointed to by the *//* 'size' parameter. *//*********************************************************************/unsigned char flash_get_sector_size(unsigned char sector, unsigned int *size){ *size = meminfo->sec[sector].size; return(1);}/*********************************************************************//* UNLOCK BYPASS FUNCTIONS *//*********************************************************************//* Unlock bypass mode is useful whenever the calling application *//* wished to program large amounts of data in minimal time. Unlock *//* bypass mode remove half of the bus overhead required to program *//* a single word, from 4 cycles down to 2 cycles. Programming of *//* individual bytes does not gain measurable benefit from unlock *//* bypass mode, but programming large strings can see a significant *//* decrease in required programming time. *//*********************************************************************//*********************************************************************//* flash_ub() places the flash into unlock bypass mode. This *//* is REQUIRED to be called before any of the other unlock bypass *//* commands will become valid (most will be ignored without first *//* calling this function. *//*********************************************************************/ unsigned char flash_ub(unsigned char sector){ flash_command(FLASH_UB, sector, 0, 0); return(1);}/*********************************************************************//* flash_write_word_ub() programs a single word using unlock bypass *//* mode. Note that the calling application will see little benefit *//* from programming single words using this mode (outlined above) *//*********************************************************************/unsigned char flash_write_word_ub(unsigned char sector, unsigned short offset, unsigned short data){ flash_command(FLASH_UBPROG, sector, offset, data); return (1);}/*********************************************************************//* flash_write_string_ub() behaves in the exact same manner as *//* flash_write_string() (outlined above), expect that it utilizes *//* the unlock bypass mode of the flash device. This can remove *//* significant overhead from the bulk programming operation, and *//* when programming bulk data a sizeable performance increase can be *//* observed. *//*********************************************************************/unsigned char flash_write_string_ub(unsigned char sector, unsigned short offset, unsigned char *buffer, unsigned short numbytes){ unsigned short value=0; if(numbytes == 0) value = (unsigned short) 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. *//*********************************************************************/unsigned char 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(unsigned short *num){ *num = meminfo->nsect;}/*********************************************************************/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?