📄 fapi.c
字号:
if( i<y || i>=(y+length))
if(fcopy_back(x+(unsigned long)i,z+(unsigned long)i)!=0)
{
if(find_backup(z)!=0)
{
SCI_Str("\r\n==>z= ");
SCI_Hex( z );
De_ChipSelect_F1
return(1);
}
else
{ // assume second time must OK
SCI_Str("\r\n==>z= ");
SCI_Hex( z );
fcopy_back(x+(unsigned long)i,z+(unsigned long)i);
}
}
else
{
// SCI_Str("\r\n==>Copy success!");
}
}
ferase_blk((unsigned int)x); // erase orginal block
// copy back the backup-ed block with modify page to the erased block
for (i=0;i<19;i++)
{
// SCI_Str("\r\n==>i= ");
// SCI_HexB( i );
if( i<y || i>=(y+length))
if(fcopy_back(z+(unsigned long)i,x+(unsigned long)i)!=0)
{
if(find_backup(z)!=0)
{
De_ChipSelect_F1
// SCI_Str("\r\n==>Next backup-ed z= ");
// SCI_Hex( z );
// SCI_Str("\r\n==>NO_BACKUP_BLK=");
// SCI_Hex( NO_BACKUP_BLK );
return(NO_BACKUP_BLK);
}
else
// assume second time must OK
fcopy_back(z+(unsigned long)i,x+(unsigned long)i);
}
}
ferase_blk_nowait((unsigned int)z); // erase backup sector
De_ChipSelect_F1
TurnOffLed(); // LED indication
return(0);
}
//***********************************************************************
//** Search for BACKUP BLOCK, only called by BackupFlash()
//***********************************************************************
//** This function have following actions
//** 1. Mask out the bad backup blk from spare blk table
//** 2. Search for new backup blk from the undated spare blk table
//** 3. updated the spare blk table to flash memory
//** 4. Mask out and update the bad backup blk from the Bad block tbl in flash memory
//***********************************************************************
//** input - current Addr (Block Address)
//** output - non-zero error
//***********************************************************************
//** Note: This function should be modified to suit the product specification
//***********************************************************************
const unsigned char and_bit[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};
unsigned char find_backup(unsigned long Addr)
{
unsigned char i;
unsigned int j;
unsigned char spare_tbl[512];
Addr = Addr/32; // convert to blk address
// clear buffer
for (j=0;j<512;j++)
spare_tbl[j]=0xff;
//** locate spare blk address
flash_rw.addr = SPARE_PAGE;
flash_rw.length = (NUM_OF_SPARE*2);
flash_rw.buff_ptr = &spare_tbl[0];
fread_data(0);
// display data
SCI_Str("\r\nCurrent Backup BLK: ");
SCI_HexS((unsigned short)backup_even);
SCI_Str(" ");
SCI_HexS((unsigned short)backup_odd);
SCI_Str("\r\nBad Backup Blk: ");
SCI_HexS((unsigned short)Addr);
// mask out bad block from spare block table
i = 0;
j = (unsigned int)spare_tbl[i] | (unsigned int)(spare_tbl[i+1]<<8);
while (j!=0xffff)
{
if(j==Addr)
{
// block found, mask it out from spare block table
spare_tbl[i] = 0;
spare_tbl[i+1] = 0;
break;
}
i += 2;
j = (unsigned int)spare_tbl[i] | (unsigned int)(spare_tbl[i+1]<<8);
}
// looking for backup block
backup_odd = 0;
backup_even = 0;
i = 0;
j = (unsigned int)spare_tbl[i] | (unsigned int)(spare_tbl[i+1]<<8);
while ((backup_odd & backup_even)==0 || j!=0xffff)
{
if (j!=0)
{
if ((j&0x01)==0 && backup_even==0)
backup_even = (unsigned long)j*32;
else if ((j&0x01)==1 && backup_odd==0)
backup_odd = (unsigned long)j*32;
}
i += 2;
j = (unsigned int)spare_tbl[i] | (unsigned int)(spare_tbl[i+1]<<8);
if (i>=NUM_OF_SPARE)
break;
}
// report error, bcos no more spare block
if ((backup_odd & backup_even) == 0)
{
SCI_Str("\r\nRuntime No Backup BLK!!!!");
errorcode = NO_BACKUP_BLK;
return(NO_BACKUP_BLK);
}
SCI_Str("\r\nBackup BLK Updated!!!");
SCI_Str("\r\nNew Backup BLK: ");
SCI_HexS((unsigned short)backup_even);
SCI_Str(" ");
SCI_HexS((unsigned short)backup_odd);
SCI_Str("\r\nNEW Spare Tbl: ");
SCI_HexS((unsigned short)flash_rw.addr);
SCI_Str("\r\n");
for (j=0;j<(NUM_OF_SPARE*2);j++)
{
SCI_HexB(spare_tbl[j++]);
SCI_HexB(spare_tbl[j]);
SCI_Str(" ");
}
// direct replace is prossible due to no change for the data, also block "0" always good
flash_rw.addr = SPARE_PAGE;
flash_rw.length = 512;
flash_rw.buff_ptr = &spare_tbl[0];
fwrite_data(0);
// update BAD BLOCK tbl, same length, same buff_ptr
flash_rw.addr = BAD_BLK_TBL;
fread_data(0);
// mask out bad block, same addr, same length, same buff_ptr
spare_tbl[(unsigned int)(Addr/8)] = spare_tbl[(unsigned int)(Addr/8)] & and_bit[(unsigned char)(Addr%8)];
fwrite_data(0);
ferase_blk((unsigned int)backup_odd);
ferase_blk((unsigned int)backup_even);
return(0);
}
//***********************************************************************
//** Search for next SPARE BLOCK, only called by WriteFlash()
//***********************************************************************
//** This function have following actions
//** 1. Search for new blk from spare blk table
//** 2. mask out update spare blk table and search new backup blk
//** 3. updated the spare blk table to flash memory
//** 4. Mask out and update the bad blk from the Bad block tbl in flash memory
//** 5. move bad blk data to new blk
//***********************************************************************
//** input - current bad Addr (Block Address)
//** output - zero = on spare found.
//***********************************************************************
//** Note: This function should be modified to suit the product specification
//***********************************************************************
unsigned long find_spare(unsigned long Addr, unsigned char *buf)
{
volatile unsigned char i, temp_page;
unsigned int j, temp_blk;
unsigned char spare_tbl[512];
unsigned char ecc[16];
temp_page = (unsigned char)(Addr%32);
Addr = Addr/32; // Convert to blk address
SCI_Str("\r\nBad Block found: ");
SCI_HexS((unsigned short)Addr);
// clear buffer
for (j=0;j<512;j++)
spare_tbl[j]=0xff;
//** locate spare blk address
flash_rw.addr = SPARE_PAGE;
flash_rw.length = (NUM_OF_SPARE*2);
flash_rw.buff_ptr = &spare_tbl[0];
fread_data(0);
// mask out bad block from spare block table, also alocate new backup blk
temp_blk = 0;
backup_odd = 0;
backup_even = 0;
i = 0;
j = (unsigned int)spare_tbl[i] | (unsigned int)(spare_tbl[i+1]<<8);
while (j!=0xffff)
{
if (j!=0)
{
if (temp_blk==0) {
temp_blk = j; // buffer the space blk addr
spare_tbl[i] = 0;
spare_tbl[i+1] = 0;
j = 0;
} else {
if ((j&0x01)==0 && backup_even==0)
backup_even = (unsigned long)j*32;
else if ((j&0x01)==1 && backup_odd==0)
backup_odd = (unsigned long)j*32;
}
}
i += 2;
j = (unsigned int)spare_tbl[i] | (unsigned int)(spare_tbl[i+1]<<8);
}
// report error, bcos no more spare block
if ((backup_odd & backup_even) == 0)
{
SCI_Str("\r\nRuntime No Backup BLK!!!!");
errorcode = NO_BACKUP_BLK;
return(0);
}
SCI_Str("\r\nNew BLK found: ");
SCI_HexS((unsigned short)temp_blk);
SCI_Str(" New Backup BLK: ");
SCI_HexS((unsigned short)backup_even);
SCI_Str(" ");
SCI_HexS((unsigned short)backup_odd);
// direct replace is prossible due to no change for the data, also block "0" always good
flash_rw.addr = SPARE_PAGE;
flash_rw.length = 512;
flash_rw.buff_ptr = &spare_tbl[0];
fwrite_data(0);
// update BAD BLOCK tbl, same length, same buff_ptr
flash_rw.addr = BAD_BLK_TBL;
fread_data(0);
// mask out bad block in BAD BLOCK tbl, same addr, same length, same buff_ptr
spare_tbl[(unsigned char)(Addr/8)] = spare_tbl[(unsigned char)(Addr/8)] & and_bit[(unsigned char)(Addr%8)];
fwrite_data(0);
ferase_blk((unsigned int)backup_odd);
ferase_blk((unsigned int)backup_even);
//****** update physical BLK alocation table
j = (unsigned char)(Addr/256); // remember which page want to modify
// check which page in the blk alocation table
flash_rw.addr = j+BLK_TBL_OFFSET;
flash_rw.length = 512;
flash_rw.buff_ptr = &spare_tbl[0];
fread_data(0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -