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 + -
显示快捷键?