www.pudn.com > MPC8241BSP.rar > flashchk.c
#define FLASH16_SMALL_BLOCK (int)32
#define FLASH16_SMALL_BLOCK_NO (int)31
#define FLASH32_SMALL_BLOCK (int)16
#define FLASH32_SMALL_BLOCK_NO (int)63
#ifndef BYTE
#define BYTE unsigned char
#endif
#ifndef UCHAR
#define UCHAR unsigned char
#endif
/*#define WORD unsigned short int */
#ifndef WORD
#define WORD unsigned short
#endif
#ifndef DWORD
#define DWORD unsigned long
#endif
#ifndef ULONG
#define ULONG unsigned long
#endif
#define FLASH16_BASE_ADDR 0xFF000000
#define FLASH16_SIZE 0x00800000
#define FLASH16_END_ADDR 0xFF800000
#define FLASH16_BLOCK_SIZE 0x00040000
#define FLASH32_BASE_ADDR 0xA0000000
#define FLASH32_SIZE 0x00800000
#define FLASH32_END_ADDR 0xA0800000
#define FLASH32_BLOCK_SIZE 0x00020000
unsigned long long int urs7=0x0080008000800080LL;
unsigned long long int urs1=0x0001000100010001LL;
unsigned long long int urs3=0x0008000800080008LL;
unsigned long long int urs4=0x0010001000100010LL;
unsigned long long int urs45=0x0030003000300030LL;
unsigned long long int urs5=0x0020002000200020LL;
int Flash16Prg(DWORD,DWORD,DWORD *,DWORD);
int Flash32Prg(DWORD,DWORD,DWORD *,DWORD);
UCHAR flashtest(void);
STATUS UnlockBlock( WORD * );
int FlashPrg(DWORD,DWORD,DWORD *,DWORD);
STATUS FlashWrite(WORD *,WORD *);
int EraseBlock(DWORD);
void FlashRead(UCHAR *,char *,int);
void EraseSection(DWORD,DWORD);
IMPORT void sysLongLongMove (ULONG destAddr, ULONG souAddr);
/*void sysLongLongMove (UINT32 destAddr, UINT32 souAddr)
{
}
*/
/************************************************************
* flashrom check for diagnose
* return 0: OK 1: Unblock error 2: erase error 3 write or verify error
*
***********************************************************/
UCHAR sysCheckFlash(void)
{
STATUS dwRet;
int ii,jj/*,kk,mm*/;
ULONG buf[2];
ULONG getbuf[2];
DWORD dwStartAddr;
/* int errflag=0;*/
UCHAR ret = 0;
buf[0]=0x55AAAA55;
buf[1]=0xAA5555AA;
printf("\nnow starting check flash1(28F160*4).....\n");
for (ii=0;ii<(FLASH16_SIZE/FLASH16_BLOCK_SIZE);ii++)
{
if (ii==FLASH16_SMALL_BLOCK_NO)
{
for (jj=0;jj<(FLASH16_BLOCK_SIZE/(FLASH16_SMALL_BLOCK*1024));jj++)
{
dwRet = UnlockBlock((WORD *)(FLASH16_BASE_ADDR+ii*FLASH16_BLOCK_SIZE+jj*FLASH16_SMALL_BLOCK*1024));
if (dwRet != OK){
printf("unlockblock block big %d small %d error!\n",FLASH16_SMALL_BLOCK_NO,jj);
ret = 1;
flashErrLed(CERRSTATUS_FLASH1,SLOWLY_FLASH);
ErrorLedOn();
return ret;
}
else
printf("unlockblock block big %d small %d success!\n",FLASH16_SMALL_BLOCK_NO,jj);
dwRet = EraseBlock((DWORD)(FLASH16_BASE_ADDR+ii*FLASH16_BLOCK_SIZE+jj*FLASH16_SMALL_BLOCK*1024));
if (dwRet != OK){
printf("Erase block big %d small %d error!\n",FLASH16_SMALL_BLOCK_NO,jj);
ret = 2;
flashErrLed(CERRSTATUS_FLASH1,SLOWLY_FLASH);
ErrorLedOn();
return ret;
}
else{
printf("Erase block big %d small %d success!\n",FLASH16_SMALL_BLOCK_NO,jj);
}
dwStartAddr = FLASH16_BASE_ADDR + ii*FLASH16_BLOCK_SIZE+jj*FLASH16_SMALL_BLOCK*1024;
FlashPrg(dwStartAddr,0,(DWORD *)buf,8);
FlashRead((UCHAR *)getbuf,(char *)dwStartAddr,8);
if( ( getbuf[0] != buf[0] ) || ( getbuf[1] != buf[1] ) ){
printf("error flash write in address %lx!\n",(dwStartAddr));
ret = 3;
flashErrLed(CERRSTATUS_FLASH1,SLOWLY_FLASH);
ErrorLedOn();
return ret;
}
getbuf[0]=0;
getbuf[1]=0;
}
}
else
{
dwRet = UnlockBlock((WORD *)(FLASH16_BASE_ADDR+ii*FLASH16_BLOCK_SIZE));
if (dwRet != OK){
printf("unlockblock block %d error!\n",ii);
ret = 4;
flashErrLed(CERRSTATUS_FLASH1,SLOWLY_FLASH);
ErrorLedOn();
return ret;
}
else{
printf("unlockblock block %d success!\n",ii);
}
dwRet = EraseBlock((DWORD)(FLASH16_BASE_ADDR+ii*FLASH16_BLOCK_SIZE));
if (dwRet == ERROR){
printf("Eraseblock %d error!\n",ii);
ret = 5;
flashErrLed(CERRSTATUS_FLASH1,SLOWLY_FLASH);
ErrorLedOn();
return ret;
}
else{
printf("EraseBlock %d success!\n",ii);
}
dwStartAddr = FLASH16_BASE_ADDR + ii*FLASH16_BLOCK_SIZE;
FlashPrg(dwStartAddr,0,(DWORD *)buf,8);
FlashRead((UCHAR *)getbuf,(char *)dwStartAddr,8);
if( ( getbuf[0] != buf[0] ) || ( getbuf[1] != buf[1] ) ){
printf("error flash write in address %lx!\n",(dwStartAddr));
ret = 6;
flashErrLed(CERRSTATUS_FLASH1,SLOWLY_FLASH);
ErrorLedOn();
return ret;
}
getbuf[0]=0;
getbuf[1]=0;
}
}
flashRunLed(ONETIME,SLOWLY_FLASH);
printf("\nflash1 check successful!\n");
/******************************TEST FOR FLASH32***********************************/
printf("\nnow starting check flash2(28F320*2).....\n");
for (ii=0;ii<(FLASH32_SIZE/FLASH32_BLOCK_SIZE);ii++)
{
if (ii==FLASH32_SMALL_BLOCK_NO)
{
for (jj=0;jj<(FLASH32_BLOCK_SIZE/(FLASH32_SMALL_BLOCK*1024));jj++)
{
dwRet = UnlockBlock((WORD *)(FLASH32_BASE_ADDR+ii*FLASH32_BLOCK_SIZE+jj*FLASH32_SMALL_BLOCK*1024));
if (dwRet != OK){
printf("unlockblock block big %d small %d error!\n",FLASH32_SMALL_BLOCK_NO,jj);
ret = 7;
flashErrLed(CERRSTATUS_FLASH2,SLOWLY_FLASH);
ErrorLedOn();
return ret;
}
else
printf("unlockblock block big %d small %d success!\n",FLASH32_SMALL_BLOCK_NO,jj);
dwRet = EraseBlock((DWORD)(FLASH32_BASE_ADDR+ii*FLASH32_BLOCK_SIZE+jj*FLASH32_SMALL_BLOCK*1024));
if (dwRet != OK){
printf("Erase block big %d small %d error!\n",FLASH32_SMALL_BLOCK_NO,jj);
ret = 8;
flashErrLed(CERRSTATUS_FLASH2,SLOWLY_FLASH);
ErrorLedOn();
return ret;
}
else
printf("Erase block big %d small %d success!\n",FLASH32_SMALL_BLOCK_NO,jj);
dwStartAddr = FLASH32_BASE_ADDR + ii*FLASH32_BLOCK_SIZE+jj*FLASH32_SMALL_BLOCK*1024;
FlashPrg(dwStartAddr,0,(DWORD *)buf,8);
FlashRead((UCHAR *)getbuf,(char *)dwStartAddr,8);
if( ( getbuf[0] != buf[0] ) || ( getbuf[1] != buf[1] ) ){
printf("error flash write in address %lx!\n",(dwStartAddr));
ret = 9;
flashErrLed(CERRSTATUS_FLASH2,SLOWLY_FLASH);
ErrorLedOn();
return ret;
}
getbuf[0]=0;
getbuf[1]=0;
}
}
else
{
dwRet = UnlockBlock((WORD *)(FLASH32_BASE_ADDR+ii*FLASH32_BLOCK_SIZE));
if (dwRet != OK){
printf("unlockblock block %d error!\n",ii);
ret = 10;
flashErrLed(CERRSTATUS_FLASH2,SLOWLY_FLASH);
ErrorLedOn();
return ret;
}
else
printf("unlockblock block %d success!\n",ii);
dwRet = EraseBlock((DWORD)(FLASH32_BASE_ADDR+ii*FLASH32_BLOCK_SIZE));
if (dwRet == ERROR){
printf("Eraseblock %d error!\n",ii);
ret = 11;
flashErrLed(CERRSTATUS_FLASH2,SLOWLY_FLASH);
ErrorLedOn();
return ret;
}
else
printf("EraseBlock %d success!\n",ii);
dwStartAddr = FLASH32_BASE_ADDR + ii*FLASH32_BLOCK_SIZE;
FlashPrg(dwStartAddr,0,(DWORD *)buf,8);
FlashRead((UCHAR *)getbuf,(char *)dwStartAddr,8);
if( ( getbuf[0] != buf[0] ) || ( getbuf[1] != buf[1] ) ){
printf("error flash write in address %lx!\n",(dwStartAddr));
ret = 12;
flashErrLed(CERRSTATUS_FLASH2,SLOWLY_FLASH);
ErrorLedOn();
return ret;
}
getbuf[0]=0;
getbuf[1]=0;
}
}
ret = 0;
flashRunLed(ONETIME,SLOWLY_FLASH);
printf("\nflash2 check successful!\n");
return ret;
}
/****************************************************************
* FunctionName :UnlockBlock *
* Function :unlock flash *
* Parameters :tpAddr--address of flash to be unlocked *
* Result :if success,return OK,else return ERROR *
* Global Vars : *
* Author/Date : *
* ModifiedRecord: *
****************************************************************/
STATUS UnlockBlock( WORD *tpAddr )
{
unsigned long long int cmd1=0x6060606060606060LL;
unsigned long long int cmd2=0xD0D0D0D0D0D0D0D0LL;
unsigned long long int cmd3=0x7070707070707070LL;
unsigned long long int cmd4=0x9090909090909090LL;
unsigned long long int cmd5=0xFFFFFFFFFFFFFFFFLL;
unsigned long long int content;
DWORD *pAddr;
DWORD dwStartAddr;
dwStartAddr = (DWORD)tpAddr;
pAddr = (DWORD *)tpAddr;
if ((dwStartAddr >= FLASH16_BASE_ADDR) && (dwStartAddr < FLASH16_END_ADDR))
{
sysLongLongMove(dwStartAddr,(UINT32)&cmd1);
sysLongLongMove(dwStartAddr,(UINT32)&cmd2);
sysLongLongMove(dwStartAddr,(UINT32)&cmd3);
content = *((unsigned long long int *)pAddr);
if (content != urs7)
{
sysLongLongMove(dwStartAddr,(UINT32)&cmd5);
return (ERROR);
}
sysLongLongMove(dwStartAddr,(UINT32)&cmd4);
content = *((unsigned long long int *)(pAddr+2));
if ((content & urs1) != 0)
{
sysLongLongMove(dwStartAddr,(UINT32)&cmd5);
return (ERROR);
}
sysLongLongMove(dwStartAddr,(UINT32)&cmd5);
return (OK);
}
else if ((dwStartAddr >= FLASH32_BASE_ADDR) && (dwStartAddr < FLASH32_END_ADDR))
{
*pAddr = 0x60606060;
*pAddr = 0xD0D0D0D0;
*pAddr = 0x70707070;
if (*pAddr != 0x00800080)
{
*pAddr = 0xFFFFFFFF;
return (ERROR);
}
*pAddr = 0x90909090;
if ((*(pAddr+2) & 0x00010001) != 0)
{
*pAddr = 0xFFFFFFFF;
return (ERROR);
}
*pAddr = 0xFFFFFFFF;
return (OK);
}
else
{
return (ERROR);
}
}
/****************************************************************
* FunctionName :FlashPrg *
* Function :program flash *
* Parameters :ulAddress--start address of flash programmed *
* offset--program address offset *
* BufAddr--pointer to buffer to be read *
* DataLen--length of data to be written *
* Result :if success,return OK,else return ERROR *
* Global Vars : *
* Author/Date : *
* ModifiedRecord: *
****************************************************************/
int FlashPrg(DWORD ulAddress,DWORD offset,DWORD *BufAddr,DWORD DataLen)
{
int ret;
DWORD dwStartAddr;
dwStartAddr = ulAddress + offset;
if ((dwStartAddr >= FLASH16_BASE_ADDR) && (dwStartAddr < FLASH16_END_ADDR))
{
ret = Flash16Prg(ulAddress,offset,BufAddr,DataLen);
return (ret);
}
else if ((dwStartAddr >= FLASH32_BASE_ADDR) && (dwStartAddr < FLASH32_END_ADDR))
{
ret = Flash32Prg(ulAddress,offset,BufAddr,DataLen);
return (ret);
}
else
{
return (ERROR);
}
}
/****************************************************************
* FunctionName :Flash16Prg *
* Function :program flash *
* Parameters :ulAddress--start address of flash programmed *
* offset--program address offset *
* BufAddr--pointer to buffer to be read *
* DataLen--length of data to be written *
* Result :if success,return OK,else return ERROR *
* Global Vars : *
* Author/Date : *
* ModifiedRecord: *
****************************************************************/
int Flash16Prg(DWORD ulAddress,DWORD offset,DWORD *BufAddr,DWORD DataLen)
{
char bNum;
DWORD dwWriteAddr;
/* DWORD dwBlkAddr;*/
char bBuffer[8];
unsigned long long int cmd1=0x4040404040404040LL;
unsigned long long int cmd2=0x7070707070707070LL;
unsigned long long int cmd3=0x5050505050505050LL;
unsigned long long int cmd4=0xFFFFFFFFFFFFFFFFLL;
unsigned long long int content;
int ii;
bNum = (char)((ulAddress + offset) % 8);
dwWriteAddr = (ulAddress + offset) & 0xFFFFFFF8;
ii = 0;
while (1)
{
memset((char *)bBuffer,0xFF,8);
if (DataLen < (8 - bNum))
memcpy((char *)(bBuffer + bNum),(char *)((char *)BufAddr + ii),DataLen);
else
memcpy((char *)(bBuffer + bNum),(char *)((char *)BufAddr + ii),(8 - bNum));
sysLongLongMove(dwWriteAddr,(UINT32)&cmd1);
sysLongLongMove(dwWriteAddr,(UINT32)bBuffer);
do
{
sysLongLongMove(dwWriteAddr,(UINT32)&cmd2);
content = *((unsigned long long int *)dwWriteAddr);
}while ((content & urs7) != urs7);
content = *((unsigned long long int *)dwWriteAddr);
if ((content & urs3) == urs3)
{
sysLongLongMove(dwWriteAddr,(UINT32)&cmd3);
sysLongLongMove(dwWriteAddr,(UINT32)&cmd4);
return (ERROR);
}
content = *((unsigned long long int *)dwWriteAddr);
if ((content & urs4) == urs4)
{
sysLongLongMove(dwWriteAddr,(UINT32)&cmd3);
sysLongLongMove(dwWriteAddr,(UINT32)&cmd4);
return (ERROR);
}
sysLongLongMove(dwWriteAddr,(UINT32)&cmd4);
if (DataLen < (8 - bNum))
break;
else
{
DataLen = DataLen -(8 - bNum);
if (DataLen <= 0)
break;
else
ii = ii + (8 - bNum);
}
bNum = 0;
dwWriteAddr = dwWriteAddr + 8;
}
return (OK);
}
/****************************************************************
* FunctionName :Flash32Prg *
* Function :program flash *
* Parameters :ulAddress--start address of flash programmed *
* offset--program address offset *
* BufAddr--pointer to buffer to be read *
* DataLen--length of data to be written *
* Result :if success,return OK,else return ERROR *
* Global Vars : *
* Author/Date : *
* ModifiedRecord: *
****************************************************************/
int Flash32Prg(DWORD ulAddress,DWORD offset,DWORD *BufAddr,DWORD DataLen)
{
DWORD dwAddr;
/* STATUS retval;*/
DWORD *ptr;
char bBuffer[4];
char bNum;
int ii;
bNum = (ulAddress + offset) % 4;
dwAddr = (ulAddress + offset) & 0xFFFFFFFC;
ii = 0;
while (1)
{
memset((char *)bBuffer,0xFF,4);
if (DataLen < (4 - bNum))
memcpy((char *)(bBuffer + bNum),(char *)((char *)BufAddr + ii),DataLen);
else
memcpy((char *)(bBuffer + bNum),(char *)((char *)BufAddr + ii),(4 - bNum));
ptr = (DWORD *)dwAddr;
*ptr = 0x40404040;
*ptr = *((DWORD *)bBuffer);
do
{
*ptr = 0x70707070;
}while ((*ptr & 0x00800080) != 0x00800080);
if ((*ptr & 0x00080008) == 0x00080008)
{
*ptr = 0x50505050;
*ptr = 0xFFFFFFFF;
return (ERROR);
}
if ((*ptr & 0x00100010) == 0x00100010)
{
*ptr = 0x50505050;
*ptr = 0xFFFFFFFF;
return (ERROR);
}
*ptr = 0xFFFFFFFF;
if (DataLen < (4 - bNum))
break;
else
{
DataLen = DataLen -(4 - bNum);
if (DataLen <= 0)
break;
else
ii = ii + (4 - bNum);
}
bNum = 0;
dwAddr = dwAddr + 4;
}
return (OK);
}
/****************************************************************
* FunctionName :FlashWrite *
* Function :program flash *
* Parameters :pAddr--start address of flash written *
* buf--pointer to buffer to be read *
* Result :if success,return OK,else return ERROR *
* Global Vars : *
* Author/Date : *
* ModifiedRecord: *
****************************************************************/
STATUS FlashWrite(WORD *pAddr,WORD *buf)
{
STATUS retval = OK;
*pAddr = 0x4040;
*pAddr = *buf;
do{
*pAddr = 0x7070;
}while ((*pAddr & 0x0080) != 0x0080);
if ((*pAddr & 0x0008) == 0x0008)
{
*pAddr = 0x5050;
retval = ERROR;
}
if ((*pAddr & 0x0010) == 0x0010)
{
*pAddr = 0x5050;
retval = ERROR;
}
*pAddr = 0xFFFF;
taskDelay(10);
return( retval );
}
/****************************************************************
* FunctionName :EraseBlock *
* Function :erase flash block *
* Parameters :BaseAddr--start address of flash erased *
* Result :if success,return OK,else return ERROR *
* Global Vars : *
* Author/Date : *
* ModifiedRecord: *
****************************************************************/
int EraseBlock(DWORD BaseAddr)
{
unsigned long long int cmd1=0x2020202020202020LL;
unsigned long long int cmd2=0xd0d0d0d0d0d0d0d0LL;
unsigned long long int cmd3=0x7070707070707070LL;
unsigned long long int cmd4=0x5050505050505050LL;
unsigned long long int cmd5=0xFFFFFFFFFFFFFFFFLL;
unsigned long long int content;
int retval=OK;
DWORD *pBaseAddr;
if ((BaseAddr >= FLASH16_BASE_ADDR) && (BaseAddr < FLASH16_END_ADDR))
{
sysLongLongMove(BaseAddr,(UINT32)&cmd1);
sysLongLongMove(BaseAddr,(UINT32)&cmd2);
do
{
sysLongLongMove(BaseAddr,(UINT32)&cmd3);
content = *((unsigned long long int *)BaseAddr);
}while ((content & urs7) != urs7);
content = *((unsigned long long int *)BaseAddr);
if ((content & urs3) == urs3)
{
sysLongLongMove(BaseAddr,(UINT32)&cmd4);
retval = ERROR;
}
content = *((unsigned long long int *)BaseAddr);
if ((content & urs45) == urs45)
{
sysLongLongMove(BaseAddr,(UINT32)&cmd4);
retval = ERROR;
}
content = *((unsigned long long int *)BaseAddr);
if ((content & urs5) == urs5)
{
sysLongLongMove(BaseAddr,(UINT32)&cmd4);
retval = ERROR;
}
sysLongLongMove(BaseAddr,(UINT32)&cmd5);
taskDelay(100);
return (retval);
}
else if ((BaseAddr >= FLASH32_BASE_ADDR) && (BaseAddr < FLASH32_END_ADDR))
{
pBaseAddr = (DWORD *)BaseAddr;
*pBaseAddr = 0x20202020;
*pBaseAddr = 0xd0d0d0d0;
do
{
*pBaseAddr = 0x70707070;
}while ((*pBaseAddr & 0x00800080) != 0x00800080);
if ((*pBaseAddr & 0x00080008) == 0x00080008)
{
*pBaseAddr = 0x50505050;
retval = ERROR;
}
if ((*pBaseAddr & 0x00300030) == 0x00300030)
{
*pBaseAddr = 0x50505050;
retval = ERROR;
}
if ((*pBaseAddr & 0x00200020) == 0x00200020)
{
*pBaseAddr = 0x50505050;
retval = ERROR;
}
*pBaseAddr = 0xFFFFFFFF;
taskDelay(100);
return (retval);
}
else
return (ERROR);
}
/****************************************************************
* FunctionName :FlashRead *
* Function :Read data from flash *
* Parameters :pBuf--pointer to buffer for reading *
* dwStartAddr--reading address *
* dwSize--reading length *
* Result : *
* Global Vars : *
* Author/Date : *
* ModifiedRecord: *
****************************************************************/
void FlashRead(UCHAR *pBuf,char *dwStartAddr,int dwSize)
{
/* semTake(mm_SemFlash,WAIT_FOREVER); */
memcpy(pBuf,dwStartAddr,dwSize);
/* semGive(mm_SemFlash); */
return;
}
/****************************************************************
* FunctionName :EraseSection *
* Function :Erase one section *
* Parameters :dwSecStartAddr--start address of section *
* dwLength--length of section *
* Result : *
* Global Vars : *
* Author/Date : *
* ModifiedRecord: *
****************************************************************/
void EraseSection(DWORD dwSecStartAddr,DWORD dwLength)
{
UCHAR ii;
DWORD jj;
DWORD dwEraseAddr;
int dwRet;
if ((dwSecStartAddr >= FLASH16_BASE_ADDR) && (dwSecStartAddr < FLASH16_END_ADDR))
{
jj = dwLength / (DWORD)FLASH16_BLOCK_SIZE;
/* semTake(mm_SemFlash,WAIT_FOREVER); */
for (ii=0;ii<(UCHAR)jj;ii++)
{
dwEraseAddr = (DWORD)(dwSecStartAddr + ii*FLASH16_BLOCK_SIZE);
dwRet = EraseBlock(dwEraseAddr);
}
/* semGive(mm_SemFlash); */
return;
}
else if ((dwSecStartAddr >= FLASH32_BASE_ADDR) && (dwSecStartAddr < FLASH32_END_ADDR))
{
jj = dwLength / (DWORD)FLASH32_BLOCK_SIZE;
/* semTake(mm_SemFlash,WAIT_FOREVER); */
for (ii=0;ii<(UCHAR)jj;ii++)
{
dwEraseAddr = (DWORD)(dwSecStartAddr + ii*FLASH32_BLOCK_SIZE);
dwRet = EraseBlock(dwEraseAddr);
}
/* semGive(mm_SemFlash); */
return;
}
else
return;
}