📄 sm.c
字号:
STATUS SmWriteNextSector (void)
{
STATUS RetVal;
BYTE RetryCount;
for (RetryCount = 0; RetryCount < 3; RetryCount++)
{
if ((SmFlashCmd(FLASH_PROG_NEXT_DATA)) != STATUS_SUCCESS)
{
RetVal = STATUS_FLASH_ERROR;
continue;
}
/*
*********************************************************************************************************
* ECC Generate Area
*********************************************************************************************************
*/
if (ChunkCounter == 3)
{
// Add Code For Writing Redundant Area Begin
SmFlashCmd(FLASH_PROG_EX);
// Add Code For Writing Redundant Area End
SmJustWrite = true;
ChunkCounter = 0;
RetVal = SmParseStatus(SmReadStatus());
if (RetVal == STATUS_SUCCESS)
{
SmCleanPage[PageIndex] = true;
SectorStart++;
}
else if (RetVal == STATUS_FLASH_ERROR)
{
RetVal = SmRepairBlock();
}
break;
}
else
{
ChunkCounter++;
return STATUS_SUCCESS;
}
}
return RetVal;
}
//----------------------------------------------------------------------------
// Description:
// Mark one block to be invalid
//----------------------------------------------------------------------------
void SmMarkInvalidBlock (UINT16 Block)
{
Block = Block;
// Need Any code for BLOCK_STS and Write Page
}
//----------------------------------------------------------------------------
// Description:
// Erase one block of FLASH
//----------------------------------------------------------------------------
STATUS SmEraseBlock (UINT16 Block)
{
BYTE RetryCount;
STATUS RetVal;
UINT32 Page = (UINT32)Block << SmPage2BlockShift;
// Need Any code for CIS Block
for (RetryCount = 0; RetryCount < 3; RetryCount++)
{
SmSetFlashAddr(Page);
if (SmFlashCmd(FLASH_ERASE) != STATUS_SUCCESS)
{
RetVal = STATUS_FLASH_ERROR;
continue;
}
RetVal = SmParseStatus(SmReadStatus());
if (RetVal == STATUS_SUCCESS)
{
return STATUS_SUCCESS;
}
else
{
continue;
}
}
return RetVal;
}
//----------------------------------------------------------------------------
// Description:
// Translate the logical block to physical block
//----------------------------------------------------------------------------
UINT16 SmLog2PhyBlock (UINT16 LogBlockSeg)
{
UINT16 TableAddr;
BYTE Segment = LogBlockSeg >> SmBlock2SegShift;
#ifdef SM_FAST
if (Segment == 0)
{
SegmentBase = 0;
TableAddr = LogBlockSeg & SmBlockSegMask;
}
else
{
if (Segment != SmBlockTabSeg)
{
SmReadBlockTab(Segment);
}
else
{
SmSetSegmentBase(Segment);
}
TableAddr = TabSegment1Base + (LogBlockSeg & SmBlockSegMask);
}
#else
if (Segment != SmBlockTabSeg)
{
SmReadBlockTab(Segment);
}
TableAddr = LogBlockSeg & SmBlockSegMask;
#endif
return ((SmBlockTab[TableAddr]));
}
//----------------------------------------------------------------------------
// Description:
// Update the block table for dedicated block
//----------------------------------------------------------------------------
void SmUpdateBlockTab (UINT16 LogBlock, UINT16 PhyBlock)
{
UINT16 TableAddr;
BYTE Segment = LogBlock >> SmBlock2SegShift;
#ifdef SM_FAST
if (Segment == 0)
{
TableAddr = LogBlock & SmBlockSegMask;
}
else
{
if (Segment != SmBlockTabSeg)
{
return;
}
TableAddr = TabSegment1Base + (LogBlock & SmBlockSegMask);
}
SmBlockTab[TableAddr] = PhyBlock;
#else
if (Segment != SmBlockTabSeg)
{
return;
}
TableAddr = LogBlock & SmBlockSegMask;
SmBlockTab[TableAddr] = PhyBlock;
#endif
}
//----------------------------------------------------------------------------
// Description:
// Get one block address from header area
//----------------------------------------------------------------------------
UINT16 SmGetAddr (void)
{
UINT16 Addr, A1, A2;
bit Parity1, Parity2;
// Get Segment LBA from Spare Area
((TDataCast *)&A1)->ucByte[0] = SpareArea[BLOCK_ADDR1_H];
((TDataCast *)&A1)->ucByte[1] = SpareArea[BLOCK_ADDR1_L];
((TDataCast *)&A2)->ucByte[0] = SpareArea[BLOCK_ADDR2_H];
((TDataCast *)&A2)->ucByte[1] = SpareArea[BLOCK_ADDR2_L];
Parity1 = EvenParity(A1);
Parity2 = EvenParity(A2);
if (Parity1 && Parity2)
{
if (A1 != A2)
{
return ERROR_BLOCK;
}
else if (A1 == FREE_BLOCK)
{
return FREE_BLOCK;
}
else
{
Addr = A1;
}
}
else if (Parity1 && (!Parity2))
{
if (A1 == FREE_BLOCK)
{
return FREE_BLOCK;
}
else
{
Addr = A1;
}
}
else if ((!Parity1) && Parity2)
{
if (A2 == FREE_BLOCK)
{
return FREE_BLOCK;
}
else
{
Addr = A2;
}
}
else
{
return ERROR_BLOCK;
}
Addr >>= 1;
Addr &= SmBlockSegMask;
return Addr;
}
//----------------------------------------------------------------------------
// Description:
// Read and verify the block address
//----------------------------------------------------------------------------
UINT16 SmReadBlockAddr (UINT16 Block)
{
UINT16 Addr1, Addr2;
UINT32 Page;
BYTE RetryCount;
Page = (UINT32)Block << SmPage2BlockShift; // Block to Page Address
for (RetryCount = 0; RetryCount < 3; RetryCount++)
{
// Read Segment LBA from the first page in the physical block
SmSetFlashAddr(Page);
if (SmFlashCmd(FLASH_READ_EX) != STATUS_SUCCESS)
continue;
if (SpareArea[BLOCK_STS] != VALID_BLOCK)
continue;
Addr1 = SmGetAddr();
// Read Segment LBA from the last page in the physical block
SmSetFlashAddr(Page + SmBlockPageMask);
if (SmFlashCmd(FLASH_READ_EX) != STATUS_SUCCESS)
continue;
if (SpareArea[BLOCK_STS] != VALID_BLOCK)
continue;
Addr2 = SmGetAddr();
if ((Addr1 == Addr2) && (Addr1 != ERROR_BLOCK))
{
return Addr1;
}
}
if (SmEraseBlock(Block) == STATUS_SUCCESS) // If Erase Pass return FREE_BLOCK
{
return FREE_BLOCK;
}
return ERROR_BLOCK; // If Erase Fail return ERROR_BLOCK
}
//----------------------------------------------------------------------------
// Description:
// Allocate one free block
//----------------------------------------------------------------------------
UINT16 SmAllocateBlock (BYTE Segment)
{
UINT16 FreePtr = SmFreeBlockPtr[Segment];
UINT16 i = FreePtr, Next;
UINT16 FreeTabAddr;
BYTE FreeBitMask;
#ifdef SM_FAST
UINT16 TabSegmentBase = Segment ? TabSegment1Base : 0;
if (Segment == 0)
{
SegmentBase = 0;
}
else
{
if (Segment != SmBlockTabSeg)
{
SmReadBlockTab(Segment);
}
else
{
SmSetSegmentBase(Segment);
}
}
#else
if (Segment != SmBlockTabSeg) // Must have
{
SmReadBlockTab(Segment);
}
#endif
do
{
Next = i + 1;
if (Next == SegmentTop)
{
Next = 0;
}
#ifdef SM_FAST
FreeTabAddr = (TabSegmentBase + (i & SmBlockSegMask)) >> 3;
#else
FreeTabAddr = (i & SmBlockSegMask) >> 3;
#endif
FreeBitMask = (BYTE)1 << (i & 0x07);
if (SmFreeTab[FreeTabAddr] & FreeBitMask)
{
SmFreeBlockPtr[Segment] = Next;
SmFreeTab[FreeTabAddr] &= ~FreeBitMask;
return (SegmentBase + (i * PLANE_NUMBER));
}
i = Next;
} while (i != FreePtr);
return FREE_BLOCK;
}
//----------------------------------------------------------------------------
// Description:
// Free one block
//----------------------------------------------------------------------------
void SmFreeBlock (UINT16 Block)
{
BYTE Segment = SmSrcBlockLog >> SmBlock2SegShift;
UINT16 FreeTabAddr;
STATUS Status;
UINT16 i;
#ifdef SM_FAST
UINT16 TabSegmentBase;
#endif
// Need Any Code for CIS Block
Status = SmEraseBlock(Block);
if (Status == STATUS_SUCCESS)
{
#ifdef SM_FAST
if (Segment == 0)
{
TabSegmentBase = 0;
i = Block / PLANE_NUMBER;
}
else
{
if (Segment != SmBlockTabSeg)
{
return;
}
TabSegmentBase = TabSegment1Base;
i = (Block - SegmentBase) / PLANE_NUMBER;
}
FreeTabAddr = (TabSegmentBase + (i & SmBlockSegMask)) >> 3;
SmFreeTab[FreeTabAddr] |= (BYTE)1 << (i & 0x07);
#else
if (Segment != SmBlockTabSeg)
{
return;
}
i = (Block - SegmentBase) / PLANE_NUMBER;
FreeTabAddr = (i & SmBlockSegMask) >> 3;
SmFreeTab[FreeTabAddr] |= (BYTE)1 << (i & 0x07);
#endif
}
}
//----------------------------------------------------------------------------
// Description:
// Gather the block address table from the FLASH header areas
//----------------------------------------------------------------------------
void SmReadBlockTab (BYTE Segment)
{
UINT16 StartBlock, BlockAddr, TableAddr, FreeTabAddr;
UINT16 i, j;
#ifdef SM_FAST
UINT16 TabSegmentBase = Segment ? TabSegment1Base : 0;
#endif
SmSetSegmentBase(Segment);
#ifdef SM_FAST
memset(SmBlockTab + TabSegmentBase, 0xff, sizeof(UINT16) << SmBlock2SegShift);
memset(SmFreeTab + (TabSegmentBase >> 3), 0x00, SmBlocksPerSeg >> 3);
#else
memset(SmBlockTab, 0xff, sizeof(UINT16) << SmBlock2SegShift);
memset(SmFreeTab, 0x00, SmBlocksPerSeg >> 3);
#endif
StartBlock = 0;
i = StartBlock; // Relative Block Address
j = SegmentBase + (StartBlock * PLANE_NUMBER);
// Search the FLASH for block addresses
for (; i < SmBlocksPerSeg; i++, j += PLANE_NUMBER)
{
BlockAddr = SmReadBlockAddr(j);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -