📄 s29gl128m.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 + -