📄 fapi.c
字号:
// update blk location
spare_tbl[(Addr%256)*2] = (unsigned char)temp_blk;
spare_tbl[((Addr%256)*2)+1] = (unsigned char)(temp_blk>>8);
// backup whole block to another block, except the being modify page
for(i=0;i<32;i++)
{
if (i!=j+BLK_TBL_OFFSET) // no backup for the modified page
fcopy_back((unsigned long)i,backup_even+(unsigned long)i);
}
ferase_blk(0); // erase orginal block
// copy back the backup-ed block with modify page to the erased block
for (i=0;i<32;i++)
{
if(i==j+BLK_TBL_OFFSET)
fwrite_data(0);
else
fcopy_back(backup_even+(unsigned long)i,(unsigned long)i);
}
ferase_blk((unsigned int)backup_even); // erase backup sector
// erase the new block going to storage data
ferase_blk((unsigned int)(temp_blk*32)); // erase blk first
/*
// Move bad block data to new block
for(i=0;i<32;i++)
{
if(i!=temp_page)
fcopy_back((Addr*32)+(unsigned long)i, (unsigned long)(temp_blk*32)+(unsigned long)i);
}
flash_rw.addr = (unsigned long)(temp_blk*32)+(unsigned long)temp_page;
flash_rw.buff_ptr = buf;
fwrite_sector();
*/
PORT.P3DR.BIT.P34DR = 1;
PORT.P3DR.BIT.P34DR = 0;
for (i=0;i<32;i++)
{
if(i!=temp_page) // move other data to new block
{
// read from current bad block (Source)
flash_rw.buff_ptr = &spare_tbl[0];
flash_rw.ecc_ptr = &ecc[16];
flash_rw.length = 512;
flash_rw.addr = (Addr*32)+(unsigned long)i;
fread_sector();
// write to new block (Destination)
ChipSelect_F1
flash_rw.buff_ptr = &spare_tbl[0];
flash_rw.ecc_ptr = &ecc[16];
flash_rw.length = 512;
flash_rw.addr = (unsigned long)(temp_blk*32)+(unsigned long)i;
SCI_HexS((unsigned short)flash_rw.addr);
SCI_Str(" ");
fwrite_sector(); // suppose no error in this write
}
}
SCI_Str("\r\nInfo: ");
SCI_Hex((unsigned long)flash_rw.buff_ptr);
SCI_Str(" ");
SCI_HexS((unsigned short)flash_rw.length);
SCI_Str(" ");
SCI_Hex(flash_rw.addr);
SCI_Str("\r\n");
for (j=0;j<512;j++)
{
SCI_HexB(spare_tbl[j++]);
SCI_HexB(spare_tbl[j]);
SCI_Str(" ");
}
// write data to actual address
flash_rw.buff_ptr = buf;
flash_rw.ecc_ptr = &ecc[16];
flash_rw.length = 512;
flash_rw.addr = (unsigned long)(temp_blk*32)+(unsigned long)temp_page;
SCI_HexB(fwrite_sector()); // suppose no error in this write
// De_ChipSelect_F1
return((unsigned long)temp_blk*32);
}
//***********************************************************************
//** API Write data from DOSCSIcommand.c
//** input - Start Addr and number of sectors to backup
//***********************************************************************
long SCSI_WRITE (void)
{
long workValue;
SCI_Str("\n==>SCSI_WRITE: ");
/* set up data buffer pointers */
//write cmd must be executed just after block data received!! (NO cache)
Cache->WriteCache.Addr = ConvRealn(&cbwDataGVar->cbwType.cmd2,4);
Cache->WriteCache.Addr *= BPS_SIZE;
workValue = ConvRealn((unsigned char*)&cbwDataGVar->cbwType.cmd7,2);
workValue *= BPS_SIZE;
// setting up next buffer size to store data
BufPtr[DATA_INFO].sPtr = &Cache->WriteCache.Buf[0];
if ((Cache->WriteCache.Addr&WR_AREA)==0) // for 8K buffer
{
// beginning of blk
if (workValue>=WR_BUFF_SIZE) { //
BufPtr[DATA_INFO].ePtr = &Cache->WriteCache.Buf[WR_BUFF_SIZE]; // buffer size
Cache->WriteCache.Modified = WR_PAGES;
} else {
//** data at the beginning of blk and < max buff, write all data
BufPtr[DATA_INFO].ePtr = &Cache->WriteCache.Buf[workValue];
Cache->WriteCache.Modified = (unsigned char)(workValue/512);
}
} else {
// do below if data not in the beginning of blk
Cache->WriteCache.Modified = WR_PAGES-(unsigned char)((Cache->WriteCache.Addr&WR_AREA)/512); // for 8K buffer
// check data size
if (workValue>=(Cache->WriteCache.Modified*512)) {
BufPtr[DATA_INFO].ePtr = &Cache->WriteCache.Buf[Cache->WriteCache.Modified*512];
} else {
BufPtr[DATA_INFO].ePtr = &Cache->WriteCache.Buf[workValue];
Cache->WriteCache.Modified = (unsigned char)(workValue/512);
}
}
SCI_Str("\r\n==>WriteProtect: ");
SCI_HexB( write_protect );
//** Decide to Backup/Erase block here
if (write_protect==0)
{
if ((Cache->WriteCache.Addr&0x3e00)==0) { // if beginning of blk
if (cbwDataGVar->cbwType.dCBWDataTransferLength>=0x4000) // if more than 1 Blk (16K)
EraseFlash(Cache->WriteCache.Addr, 0); // just erase that block
else
BackupFlash(Cache->WriteCache.Addr, cbwDataGVar->cbwType.dCBWDataTransferLength); // backup afterward
} else { // if not beginning of blk
if (cbwDataGVar->cbwType.dCBWDataTransferLength>=(0x4000-(Cache->WriteCache.Addr&0x3e00)))
BackupFlash(Cache->WriteCache.Addr, 0x4000-Cache->WriteCache.Addr&0x3e00);
else
BackupFlash(Cache->WriteCache.Addr, cbwDataGVar->cbwType.dCBWDataTransferLength);
} // end of chk beginning of blk
}
Cache->WriteCache.Modified_BLK = (Cache->WriteCache.Addr&0xffffc000); // indicated blk is backuped/erased
SCI_Str("SCSI_WRITE: <==\r\n");
return (workValue);
}
//***********************************************************************
//** API Read data from DOSCSIcommand.c
//** input - Start Addr and number of sectors to backup
//***********************************************************************
void SCSI_READ (void)
{
// 512byte dual buffer
// store data in buffer
if ((Cache->ReadCache.Addr&0x200)==0) {
ReadFlash(Cache->ReadCache.Addr, &Cache->ReadCache.Buf[0]);
BufPtr[DATA_INFO].sPtr = &Cache->ReadCache.Buf[0];
BufPtr[DATA_INFO].ePtr = &Cache->ReadCache.Buf[RD_BUFF_SIZE];
} else {
ReadFlash(Cache->ReadCache.Addr, &Cache->ReadCache.BufOdd[0]);
BufPtr[DATA_INFO].sPtr = &Cache->ReadCache.BufOdd[0];
BufPtr[DATA_INFO].ePtr = &Cache->ReadCache.BufOdd[RD_BUFF_SIZE];
}
Cache->ReadCache.Modified = 1; // data ready transfer to USB controller
Cache->ReadCache.Addr += BPS_SIZE;
Cache->ReadCache.Sectors--;
}
//***********************************************************************
//** API Read data from DoBOTMSClass
//** input - Start Addr and number of sectors to backup
//***********************************************************************
void BULK_READ (void)
{
// prepare next sector while DMAC transfer current sector to USB controller
if(Cache->ReadCache.Sectors!=0)
{
if ((Cache->ReadCache.Addr&0x200)==0) {
while (DMAC.ETCR0B == 7);
ReadFlash(Cache->ReadCache.Addr, &Cache->ReadCache.Buf[0]);
BufPtr[DATA_INFO].sPtr = &Cache->ReadCache.Buf[0];
BufPtr[DATA_INFO].ePtr = &Cache->ReadCache.Buf[512];
} else {
while (DMAC.ETCR0B == 7);
ReadFlash(Cache->ReadCache.Addr, &Cache->ReadCache.BufOdd[0]);
BufPtr[DATA_INFO].sPtr = &Cache->ReadCache.BufOdd[0];
BufPtr[DATA_INFO].ePtr = &Cache->ReadCache.BufOdd[512];
}
Cache->ReadCache.Modified = 1; // data ready transfer to USB controller
Cache->ReadCache.Addr += BPS_SIZE;
Cache->ReadCache.Sectors--;
} // prepare data end
}
//***********************************************************************
//** API Write data from DoBOTMSClass
//** input - Start Addr and number of sectors to backup
//***********************************************************************
void BULK_WRITE (void)
{
unsigned long data_left;
//*** make sure data write is modular of 512 bytes!!!!
//*** write data size according to WriteCache.Modified which already calculated
//** write data (more than 1 page) according WriteCache.Modified (no. of page to write)
// suppost the block is ready to write data (i.e. already erased/backup-ed
// perform write to flash process only NOT WRITE PROTECT
if (write_protect==0)
WriteFlash(Cache->WriteCache.Addr, &Cache->WriteCache.Buf[0]); // write first 16 sectors
Cache->WriteCache.Addr += (Cache->WriteCache.Modified*512);
//** setting up next buffer size to store data also backup/erase block if needed
BufPtr[DATA_INFO].sPtr = &Cache->WriteCache.Buf[0];
if ((Cache->WriteCache.Addr&WR_AREA)==0) // buffer size
{
if (cbwDataGVar->cbwType.dCBWDataTransferLength>=WR_BUFF_SIZE) { // buffer size
//** data at the beginning of blk and > max buff, write max buffer
BufPtr[DATA_INFO].ePtr = &Cache->WriteCache.Buf[WR_BUFF_SIZE]; // buffer size
Cache->WriteCache.Modified = WR_PAGES;
} else {
//** data at the beginning of blk and < max buff, write all data
BufPtr[DATA_INFO].ePtr = &Cache->WriteCache.Buf[cbwDataGVar->cbwType.dCBWDataTransferLength];
Cache->WriteCache.Modified = (unsigned char)(cbwDataGVar->cbwType.dCBWDataTransferLength/512);
}
}
else // do below if data not in the beginning of blk
{
// check how many blk to next beginning of blk
Cache->WriteCache.Modified = WR_PAGES-(unsigned char)((Cache->WriteCache.Addr&WR_AREA)/512); // for 8K buffer
// check data size
if (cbwDataGVar->cbwType.dCBWDataTransferLength>=(Cache->WriteCache.Modified*512)) {
BufPtr[DATA_INFO].ePtr = &Cache->WriteCache.Buf[Cache->WriteCache.Modified*512];
} else {
BufPtr[DATA_INFO].ePtr = &Cache->WriteCache.Buf[cbwDataGVar->cbwType.dCBWDataTransferLength];
Cache->WriteCache.Modified = (unsigned char)(cbwDataGVar->cbwType.dCBWDataTransferLength/512);
}
}
//** Decide to Backup/Erase block here
data_left = cbwDataGVar->cbwType.dCBWDataTransferLength;
if (Cache->WriteCache.Modified_BLK != (Cache->WriteCache.Addr&0xffffc000)) // chk new block
{
if (write_protect==0)
{
if ((Cache->WriteCache.Addr&0x3e00)==0) // if beginning of blk
{
if (data_left>=0x4000) // if more than 1 Blk (16K)
EraseFlash(Cache->WriteCache.Addr, 0); // just erase that block
else
BackupFlash(Cache->WriteCache.Addr, data_left); // backup afterward
} else { // do below if not beginning of blk
if (data_left>=(0x4000-(Cache->WriteCache.Addr&0x3e00)))
BackupFlash(Cache->WriteCache.Addr, 0x4000-Cache->WriteCache.Addr&0x3e00); //
else
BackupFlash(Cache->WriteCache.Addr, data_left);
} // end of chk beginning of blk
}
Cache->WriteCache.Modified_BLK = (Cache->WriteCache.Addr&0xffffc000); // indicated blk has been backuped/erased
} // DO backup or erase once in one block
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -