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

📄 s29gl128m.c

📁 这是一款amd公司的128Mbitflash芯片。 该代码实现了vxworks下对FLASH的访问操作
💻 C
字号:
   /***********************************************************************/
/*                                                                     */
/* Module Name   : S29GL128M.c                                        */
/*                                                                     */
/* Description   : Implementation of a flash module for the SPANSION      */
/*                 S29GL128M flash chip.                               */
/*                                                                     */
/*                                                                     */
/* Document Ref. : - Datasheets for the S29GL128M.                     */
/*                                                                     */
/* Function List : Exported                                            */
/* Note          : The flash memory sub-system consists of 4 S29GL128M */
/*                 flash chips,forming a 64-bit data bus.              */
/*                                                                     */
/* modification history :                                              */
/***********************************************************************/


#include "stdio.h"
#include "vxworks.h"
#include "ioLib.h"
#include "fioLib.h"
#include "sp.h"
#include "S29GL128M.h"

IMPORT void sysFlashWrite64( unsigned long ToAddr, unsigned long FromAddr);	/* sysAlib.s */
IMPORT void sysFlashRead64( unsigned long ToAddr, unsigned long FromAddr);	/* sysAlib.s */

/*
static FLASH_REG64 bufferStart[FLASH_UNIT_WORD];*/
/*static FLASH_REG64 bufferEnd[FLASH_UNIT_WORD];*/

#define S29GL128MDUGVER
#ifdef S29GL128MDUGVER
#define flS29GL128MLog(x0,x1,x2,x3,x4,x5,x6)  logMsg("==FLASH Debug : "x0" ==\n",x1,x2,x3,x4,x5,x6)
#else
#define flS29GL128MLog(x0,x1,x2,x3,x4,x5,x6)
#endif /* S29GL128MDUGVER */

#define INIT_TEST
#define WRITE_TEST
#define CHECKING_TEST
#define ERASE_TEST

void Delay(UINT32 nuSecs);
STATUS S29GL128MWrite(unsigned long offset, unsigned long Ramaddr, unsigned long dataLen);
STATUS S29GL128MErase(unsigned long offset, unsigned long nBlock);
STATUS S29GL128MInitialization(void);
STATUS S29GL128MRead(UINT32 offset, FLASH_REG64 *bufAddr, UINT32 dataLen);
void WriteBufferAbortResetFlash();
void ResetFlash();
FLASH_REG64 ReadBlkSR(unsigned long offset);


/******************************************************************************
*
* S29GL128MWrite:  save data to FLASH
* Input:      offset, address offset to be written 
*                Ramaddr, Address of data to write
*                dataLen, length of data to be read, 1 is 4 word
* Output:        none
* return:        OK or ERROR
*
******************************************************************************/

STATUS S29GL128MWrite
	(
		unsigned long offset,
		unsigned long Ramaddr,
		unsigned long dataLen
	)
{
	FLASH_REG64 temp;
	unsigned long wordtemp, loop, ii;
	unsigned long wtmp[2];

	unsigned long flashA;
	unsigned long ramA;
	unsigned long ramLow = 0, ramHigh = 0;
	
	ii =0;

    if(offset < 0)
        return ERROR;

    if((offset + dataLen * FLASH_ACCESS_OFFSET) > ROM_FLASH_SIZE)
        return ERROR;

    if((offset % FLASH_ACCESS_OFFSET) != 0)
        return ERROR;

	
    ramA     = Ramaddr;
	wordtemp = dataLen;
	flashA   = FLASHSTARTADDRESS + offset;
        
	while(wordtemp > 0)
	{
		temp.HighData = FLASH_FIRST_UNLOCK_CMD;
		temp.LowData  = FLASH_FIRST_UNLOCK_CMD;
		sysFlashWrite64(FLASHSTARTADDRESS + FLASH_FIRST_UNLOCK_OFFSET, ((unsigned long)(&temp)));
		temp.HighData = FLASH_SECOND_UNLOCK_CMD;
		temp.LowData  = FLASH_SECOND_UNLOCK_CMD;
		sysFlashWrite64(FLASHSTARTADDRESS + FLASH_SECOND_UNLOCK_OFFSET, ((unsigned long)(&temp)));
		temp.HighData = FLASH_PROGRAM_CMD;
		temp.LowData  = FLASH_PROGRAM_CMD;
		sysFlashWrite64(FLASHSTARTADDRESS + FLASH_FIRST_UNLOCK_OFFSET, ((unsigned long)(&temp)));

		
		temp.HighData = flashA;
		temp.LowData  = flashA;
		sysFlashWrite64(flashA, ramA);

		wtmp[0] = *(long *)(ramA);
		wtmp[1] = *(long *)(ramA + 4);

		loop  = 0;
		while(loop++ < FLASH_WRITE_LOOP)
		{
			WriteUsDelay(10);
			sysFlashRead64(((unsigned long)(&temp)), flashA);
			if((temp.HighData == wtmp[1]) && (temp.LowData == wtmp[0]))
				break;/* PASS */
		}	

		if(loop >= FLASH_WRITE_LOOP)
		{
			WriteBufferAbortResetFlash();
			return ERROR;
		}
	        
		wordtemp--;
		flashA   		+= FLASH_ACCESS_OFFSET;
		ramA     		+= 8;
		ii ++;
	}
	
	ResetFlash();


    flashA = FLASHSTARTADDRESS + offset;
    ramA = Ramaddr;
    ii = 0;

    Delay(1000);

    for(loop = 0; loop < dataLen; loop++)
    {
		sysFlashRead64(((unsigned long)(&temp)), FLASHSTARTADDRESS + offset + loop * FLASH_ACCESS_OFFSET);
		ramLow = *(unsigned long *)ramA;
		ramA += 4;
		ramHigh = *(unsigned long *)ramA;
		ramA += 4;
		if((temp.LowData != ramLow) || (temp.HighData != ramHigh))
		{
				return ERROR;
		}
		ii ++;
    }
    return OK;
}

/*************************************************************************
* S29GL128MErase
*
* Erase one or more contiguous Flash erasable blocks
*
* Parameters:
*    offset             The offset address of erasing
*    nBlock         : Number of blocks to erase
*
* Returns:
*    OK on success, failed otherwise
*/
STATUS S29GL128MErase
	(
	unsigned long offset,
	unsigned long nBlock
	)
{
	FLASH_REG64 temp;
	STATUS rcval = ERROR;
	unsigned long Flashaddr =  FLASHSTARTADDRESS + offset;
	unsigned long i = 0, ii = 0;

	unsigned long FlashEraseEndAdr = Flashaddr + nBlock * FLASH_SECTOR_SIZE;

	if (Flashaddr & (FLASH_ACCESS_OFFSET - 1))
	{
		return ERROR;
	}
	if( nBlock < 0 ||
		nBlock > FLASH_SECTOR_NUM ||
		Flashaddr < FLASHSTARTADDRESS ||
		Flashaddr > FLASHENDADDRESS
	   )
	{
#ifdef ERASE_TEST
        printf("->Error in the parameter!\n");
        printf("->The parameter : Flashaddr = 0x%08lX,block = %ld\n\n",Flashaddr,nBlock);
#endif
		return ERROR;
	}
#ifdef ERASE_TEST
	printf("->Erase Flash address start at  = 0x%08lX,block = %ld\n",Flashaddr,nBlock);
	printf("->Erasing..........");
#endif

	/* For each block..
	 */

	Flashaddr = Flashaddr & FLASH_MASK;

	while ((Flashaddr < FlashEraseEndAdr)&&(Flashaddr < FLASHENDADDRESS))
	{
#ifdef ERASE_TEST
	        printf("%3ld\b\b\b", ++ii);
#endif	
		/* Send erase command and confirmation. */
		temp.HighData = FLASH_FIRST_UNLOCK_CMD;
		temp.LowData  = FLASH_FIRST_UNLOCK_CMD;
		sysFlashWrite64(FLASHSTARTADDRESS + FLASH_FIRST_UNLOCK_OFFSET, ((unsigned long)(&temp)));
		temp.HighData = FLASH_SECOND_UNLOCK_CMD;
		temp.LowData  = FLASH_SECOND_UNLOCK_CMD;
		sysFlashWrite64(FLASHSTARTADDRESS + FLASH_SECOND_UNLOCK_OFFSET, ((unsigned long)(&temp)));
		temp.HighData = FLASH_ERASE_CMD;
		temp.LowData  = FLASH_ERASE_CMD;
		sysFlashWrite64(FLASHSTARTADDRESS + FLASH_FIRST_UNLOCK_OFFSET, ((unsigned long)(&temp)));

		temp.HighData = FLASH_FIRST_UNLOCK_CMD;
		temp.LowData  = FLASH_FIRST_UNLOCK_CMD;
		sysFlashWrite64(FLASHSTARTADDRESS + FLASH_FIRST_UNLOCK_OFFSET, ((unsigned long)(&temp)));
		temp.HighData = FLASH_SECOND_UNLOCK_CMD;
		temp.LowData  = FLASH_SECOND_UNLOCK_CMD;
		sysFlashWrite64(FLASHSTARTADDRESS + FLASH_SECOND_UNLOCK_OFFSET, ((unsigned long)(&temp)));
		temp.HighData = FLASH_ERASE_CONFIRM_CMD;
		temp.LowData  = FLASH_ERASE_CONFIRM_CMD;
		sysFlashWrite64(Flashaddr, ((unsigned long)(&temp)));

	  	i = 0;
		while(i++ < FLASH_ERASE_BLOCK_LOOP)
		{
		       WriteUsDelay(1000);
			sysFlashRead64(((unsigned long)(&temp)), Flashaddr);
			if((temp.HighData == temp.LowData) && (temp.HighData == 0xFFFFFFFF))
				break;
		}
		
		/* Send Read Array command. Return the flash into read array mode. */
		ResetFlash();

		if(i >= FLASH_ERASE_BLOCK_LOOP)
		{
			rcval = ERROR;
			break;
		}

		rcval = OK;
		/* Move up to the next block. */
		Flashaddr += FLASH_SECTOR_SIZE;
	}
	
#ifdef ERASE_TEST
	if(rcval == OK)
		printf(" OK! \n");
	else
		printf(" ERROR! \n");
#endif
	
	/* Send Read Array command. Return the flash into read array mode. */
	ResetFlash();
	return rcval;
}


/****************************************************/
STATUS flashManID(FLASH_REG64 *rst)
{
	FLASH_REG64 temp;

    temp.HighData = FLASH_FIRST_UNLOCK_CMD;
    temp.LowData  = FLASH_FIRST_UNLOCK_CMD;
    sysFlashWrite64(FLASHSTARTADDRESS + FLASH_FIRST_UNLOCK_OFFSET, ((unsigned long)(&temp)));
    temp.HighData = FLASH_SECOND_UNLOCK_CMD;
    temp.LowData  = FLASH_SECOND_UNLOCK_CMD;
    sysFlashWrite64(FLASHSTARTADDRESS + FLASH_SECOND_UNLOCK_OFFSET, ((unsigned long)(&temp)));
    temp.HighData = FLASH_IDENTIFIER_CMD;
    temp.LowData  = FLASH_IDENTIFIER_CMD;
    sysFlashWrite64(FLASHSTARTADDRESS + FLASH_FIRST_UNLOCK_OFFSET, ((unsigned long)(&temp)));

    sysFlashRead64(((unsigned long)(&temp)), (FLASHSTARTADDRESS + FLASH_MAN_ID_OFFSET));

    ResetFlash();

    *rst = temp;
    if((temp.LowData == temp.HighData) && (temp.LowData == FLASH_MAN_ID))
		return OK;
    else
		return ERROR;

}

/****************************************************/
STATUS flashDevID(FLASH_REG64 *rst)
{
	FLASH_REG64 temp[3];


    temp[0].HighData = FLASH_FIRST_UNLOCK_CMD;
    temp[0].LowData  = FLASH_FIRST_UNLOCK_CMD;
    sysFlashWrite64(FLASHSTARTADDRESS + FLASH_FIRST_UNLOCK_OFFSET, ((unsigned long)(&temp[0])));
    temp[0].HighData = FLASH_SECOND_UNLOCK_CMD;
    temp[0].LowData  = FLASH_SECOND_UNLOCK_CMD;
    sysFlashWrite64(FLASHSTARTADDRESS + FLASH_SECOND_UNLOCK_OFFSET, ((unsigned long)(&temp[0])));
    temp[0].HighData = FLASH_IDENTIFIER_CMD;
    temp[0].LowData  = FLASH_IDENTIFIER_CMD;
    sysFlashWrite64(FLASHSTARTADDRESS + FLASH_FIRST_UNLOCK_OFFSET, ((unsigned long)(&temp[0])));

    sysFlashRead64(((unsigned long)(&temp[0])), (FLASHSTARTADDRESS + FLASH_DEV_ID1_OFFSET));
    sysFlashRead64(((unsigned long)(&temp[1])), (FLASHSTARTADDRESS + FLASH_DEV_ID2_OFFSET));
    sysFlashRead64(((unsigned long)(&temp[2])), (FLASHSTARTADDRESS + FLASH_DEV_ID3_OFFSET));
	
    ResetFlash();

    rst[0] = temp[0];
    rst[1] = temp[1];
    rst[2] = temp[2];
    
    if((temp[0].LowData != temp[0].HighData) || (temp[0].LowData != FLASH_DEV1_ID))
		return ERROR;
    if((temp[1].LowData != temp[1].HighData) || (temp[1].LowData != FLASH_DEV2_ID))
		return ERROR;
    if((temp[2].LowData != temp[2].HighData) || (temp[2].LowData != FLASH_DEV3_ID))
		return ERROR;
    return OK;

}

/****************************************************/
STATUS S29GL128MInitialization(void)
{
	FLASH_REG64 temp;
	FLASH_REG64 tmp[3];
	unsigned long address;
	
#ifdef INIT_TEST
	int finish=0;
#endif

	/*Reset Device*/

	WriteBufferAbortResetFlash();
	ResetFlash();
	
	/* read ManID */

	if(OK != flashManID(tmp))
		return ERROR;

	/* read Device ID */
	
	if(OK != flashDevID(tmp))
		return ERROR;

#ifdef INIT_TEST
	printf("->Initializing now. And complete :%3d",finish);
#endif
	
	
	for(address = FLASHSTARTADDRESS;address < FLASHENDADDRESS;address += FLASH_SECTOR_SIZE/FLASH_ACCESS_OFFSET)
	{
	
		/* read block lock configuration 0-blk unlocked 1-blk locked */

		temp = ReadBlkSR((address & FLASH_MASK) + 2 * FLASH_ACCESS_OFFSET);
		if((temp.HighData == FLASH_CODE_LOCK_MASK) || (temp.LowData == FLASH_CODE_LOCK_MASK))
		{
			ResetFlash();
			return ERROR;
		}
	}

	ResetFlash();
	
#ifdef INIT_TEST
	printf("\n");
#endif
	return OK;
}

/******************************************************************************
*
* ReadBlkSR:  read sector group protect verify
* Input:      offset, address offset to be read
* Output:        none
* return:        FLASH_REG64 temp, sector group protect verify value
*
******************************************************************************/

FLASH_REG64 ReadBlkSR(unsigned long offset)
{
    FLASH_REG64 temp;
    unsigned long Flashaddr = FLASHSTARTADDRESS + offset;

    temp.HighData = FLASH_FIRST_UNLOCK_CMD;
    temp.LowData  = FLASH_FIRST_UNLOCK_CMD;
    sysFlashWrite64(FLASHSTARTADDRESS + FLASH_FIRST_UNLOCK_OFFSET, ((unsigned long)(&temp)));
    temp.HighData = FLASH_SECOND_UNLOCK_CMD;
    temp.LowData  = FLASH_SECOND_UNLOCK_CMD;
    sysFlashWrite64(FLASHSTARTADDRESS + FLASH_SECOND_UNLOCK_OFFSET, ((unsigned long)(&temp)));
    temp.HighData = FLASH_IDENTIFIER_CMD;
    temp.LowData  = FLASH_IDENTIFIER_CMD;
    sysFlashWrite64(FLASHSTARTADDRESS + FLASH_FIRST_UNLOCK_OFFSET, ((unsigned long)(&temp)));

    sysFlashRead64(((unsigned long)(&temp)), Flashaddr);

    return temp;
}


/******************************************************************************
*
* S29GL128MRead:   Read FLASH Data
* Input:      offset, address offset of data to be read
*                bufAddr, buffer pointer
*                dataLen, length of data to be read, 1 is 4 word
* Output:        none
* return:        OK or ERROR
*
******************************************************************************/

STATUS S29GL128MRead(UINT32 offset, FLASH_REG64 *bufAddr, UINT32 dataLen)
{
    UINT32 i;

    if(offset < 0)
        return ERROR;

    if((offset + dataLen * FLASH_ACCESS_OFFSET) > ROM_FLASH_SIZE)
        return ERROR;

    if((offset % FLASH_ACCESS_OFFSET) != 0)
        return ERROR;

    if(bufAddr == NULL)
        return ERROR;

    ResetFlash();

    for(i = 0; i < dataLen; i++)
    {
        sysFlashRead64(((unsigned long)(bufAddr + i)),FLASHSTARTADDRESS + offset + i * FLASH_ACCESS_OFFSET);
    }
    
    return OK;
}





void ResetFlash()
{
    FLASH_REG64 temp;

    temp.HighData = FLASH_RESET_CMD;
    temp.LowData  = FLASH_RESET_CMD;
    sysFlashWrite64(FLASHSTARTADDRESS, ((unsigned long)(&temp)));
    return ;
}

void WriteBufferAbortResetFlash()
{
    FLASH_REG64 temp;

    temp.HighData = FLASH_FIRST_UNLOCK_CMD;
    temp.LowData  = FLASH_FIRST_UNLOCK_CMD;
    sysFlashWrite64(FLASHSTARTADDRESS + FLASH_FIRST_UNLOCK_OFFSET, ((unsigned long)(&temp)));
    temp.HighData = FLASH_SECOND_UNLOCK_CMD;
    temp.LowData  = FLASH_SECOND_UNLOCK_CMD;
    sysFlashWrite64(FLASHSTARTADDRESS + FLASH_SECOND_UNLOCK_OFFSET, ((unsigned long)(&temp)));
    temp.HighData = FLASH_RESET_CMD;
    temp.LowData  = FLASH_RESET_CMD;
    sysFlashWrite64(FLASHSTARTADDRESS + FLASH_FIRST_UNLOCK_OFFSET, ((unsigned long)(&temp)));
    return ;
}

⌨️ 快捷键说明

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