📄 sm.c
字号:
if (BlockAddr == ERROR_BLOCK)
{
continue;
}
if (BlockAddr == FREE_BLOCK)
{
#ifdef SM_FAST
FreeTabAddr = (TabSegmentBase + i) >> 3;
#else
FreeTabAddr = i >> 3;
#endif
SmFreeTab[FreeTabAddr] |= (BYTE)1 << (i & 0x07);
continue;
}
#ifdef SM_FAST
TableAddr = TabSegmentBase + BlockAddr;
#else
TableAddr = BlockAddr;
#endif
if (SmBlockTab[TableAddr] == FREE_BLOCK)
{
SmBlockTab[TableAddr] = j;
}
else
{
if (SmEraseBlock(j) == STATUS_SUCCESS)
{
#ifdef SM_FAST
FreeTabAddr = (TabSegmentBase + i) >> 3;
#else
FreeTabAddr = i >> 3;
#endif
SmFreeTab[FreeTabAddr] |= (BYTE)1 << (i & 0x07);
}
}
}
#ifdef SM_FAST
if (Segment != 0)
#endif
{
SmBlockTabSeg = Segment;
}
}
//----------------------------------------------------------------------------
// Description:
// Copy one block to another block
//----------------------------------------------------------------------------
STATUS SmCopyBlock (UINT16 SrcBlock, UINT16 DestBlock, TCOPY_MODE Mode)
{
UINT32 SrcPage = (UINT32)SrcBlock << SmPage2BlockShift;
UINT32 DestPage = (UINT32)DestBlock << SmPage2BlockShift;
BYTE i;
for (i = 0; i < SmPagesPerBlock; i++)
{
if ((Mode == COPY_ALL) ||
((Mode == COPY_DIRTY) && !SmCleanPage[i]) ||
((Mode == COPY_CLEAN) && SmCleanPage[i]))
{
SmSetFlashAddr(SrcPage + i);
if (SmFlashCmd(FLASH_CP) != STATUS_SUCCESS)
{
return STATUS_FLASH_ERROR;
}
SmSetFlashAddr(DestPage + i);
if (SmFlashCmd(FLASH_CP_PROG) != STATUS_SUCCESS)
{
return STATUS_FLASH_ERROR;
}
if (SmReadStatus() & 0x01)
{
return STATUS_FLASH_ERROR;
}
}
}
return STATUS_SUCCESS;
}
//----------------------------------------------------------------------------
// Description:
// Error handling
//----------------------------------------------------------------------------
STATUS SmRepairBlock (void)
{
BYTE Segment = SmSrcBlockLog >> SmBlock2SegShift;
UINT16 NewDestBlock;
STATUS Status;
while (true)
{
NewDestBlock = SmAllocateBlock(Segment);
if (NewDestBlock == FREE_BLOCK)
{
return STATUS_NO_BLOCK;
}
Status = SmCopyBlock(SmDestBlock, NewDestBlock, COPY_CLEAN);
if (Status == STATUS_SUCCESS)
{
SmMarkInvalidBlock(SmDestBlock);
SmDestBlock = NewDestBlock;
SmUpdateBlockTab(SmSrcBlockLog, SmDestBlock);
}
else if (Status == STATUS_FLASH_ERROR)
{
SmMarkInvalidBlock(NewDestBlock);
continue;
}
break;
}
return Status;
}
//----------------------------------------------------------------------------
// Description:
// Pad one blank page with block address
//----------------------------------------------------------------------------
STATUS SmPadPage (BYTE p)
{
STATUS Status;
UINT32 Page = ((UINT32)SmDestBlock << SmPage2BlockShift) + p;
while (true)
{
SmNeedSetExtra = true; // SmLog2PhyBlock May Destroy Redundant Area Data
SmSetBlockExtra(SmSrcBlockLog);
// Just Write Redundant Area
SmSetFlashAddr(Page);
SmFlashCmd(FLASH_PAD);
Status = SmParseStatus(SmReadStatus());
if (Status == STATUS_SUCCESS)
{
break;
}
else if (Status == STATUS_FLASH_ERROR)
{
Status = SmRepairBlock();
if (Status != STATUS_SUCCESS)
{
return Status;
}
}
else
{
return Status;
}
}
return STATUS_SUCCESS;
}
//----------------------------------------------------------------------------
// Description:
// Flush one block to the FLASH
//----------------------------------------------------------------------------
STATUS SmFlushBlock (void)
{
STATUS Status;
BYTE i;
if (SmDestBlock == FREE_BLOCK)
{
return STATUS_SUCCESS;
}
if (SmSrcBlock != FREE_BLOCK)
{
while (true)
{
Status = SmCopyBlock(SmSrcBlock, SmDestBlock, COPY_DIRTY);
if (Status == STATUS_SUCCESS)
{
break;
}
else if (Status == STATUS_FLASH_ERROR)
{
Status = SmRepairBlock(); // Save Destination Block and New Destination Block
if (Status != STATUS_SUCCESS)
{
return Status;
}
}
else
{
return Status;
}
}
SmFreeBlock(SmSrcBlock);
SmSrcBlock = FREE_BLOCK;
}
else
{
if (!SmCleanPage[0])
{
SmPadPage(0);
}
if (!SmCleanPage[SmBlockPageMask])
{
SmPadPage(SmBlockPageMask);
}
}
SmDestBlock = FREE_BLOCK;
for (i = 0; i < MAX_PAGES_PER_BLOCK; i++)
{
SmCleanPage[i] = false;
}
SmFlushTimer = 0;
SmFlushFlag = false;
SmJustWrite = false;
return STATUS_SUCCESS;
}
//----------------------------------------------------------------------------
// Description:
// Read one sector of data from the Smart Media device
//----------------------------------------------------------------------------
STATUS SmReadSector (void)
{
STATUS Status;
UINT32 PhyPageAddr;
UINT16 LogBlock, LogBlockSeg, TargetPhyBlock;
if (SmMediaStatus != STATUS_SUCCESS)
{
return SmMediaStatus;
}
if (SmJustWrite)
{
SmFlushBlock();
}
LogBlock = SectorStart >> SmPage2BlockShift;
LogBlockSeg = LogBlock + SmLog2TabAddrGap(LogBlock);
TargetPhyBlock = SmLog2PhyBlock(LogBlockSeg);
PageIndex = (BYTE)SectorStart & SmBlockPageMask;
PhyPageAddr = ((UINT32)TargetPhyBlock << SmPage2BlockShift) + PageIndex;
// Need Any Code for TargetPhyBlock == FREE_BLOCK
Status = SmReadPage(PhyPageAddr);
return Status;
}
//----------------------------------------------------------------------------
// Description:
// Write one sector of data to the Smart Media device
//----------------------------------------------------------------------------
STATUS SmWriteSector (void)
{
UINT32 PhyPageAddr;
BYTE Segment;
UINT16 LogBlock, LogBlockSeg, TargetPhyBlock;
STATUS Status;
if (SmMediaStatus != STATUS_SUCCESS)
{
return SmMediaStatus;
}
LogBlock = SectorStart >> SmPage2BlockShift;
LogBlockSeg = LogBlock + SmLog2TabAddrGap(LogBlock);
TargetPhyBlock = SmLog2PhyBlock(LogBlockSeg); // Make New Mapping Table
PageIndex = (BYTE)SectorStart & SmBlockPageMask;
Segment = LogBlockSeg >> SmBlock2SegShift;
// Save New Logical Segment
if ((TargetPhyBlock != SmDestBlock) ||
(TargetPhyBlock == FREE_BLOCK) ||
(SmCleanPage[PageIndex]))
// Note, SmDestBlock Must Have A Physical Block, So TargetPhyBlock == FREE_BLOCK Must Exist
// Allocate A Block in New Segment
{
Status = SmFlushBlock();
if (Status != STATUS_SUCCESS)
{
return Status;
}
SmSrcBlockLog = LogBlockSeg; // Update New Logical Segment and Block
SmSrcBlock = TargetPhyBlock; // Update New Source Block
TargetPhyBlock = SmAllocateBlock(Segment); // Allocate A Block in New Segment
if (TargetPhyBlock == FREE_BLOCK)
{
return STATUS_NO_BLOCK;
}
SmDestBlock = TargetPhyBlock; // Update New Destination Block
SmUpdateBlockTab(SmSrcBlockLog, SmDestBlock);
// Update New Mapping Table
}
PhyPageAddr = ((UINT32)TargetPhyBlock << SmPage2BlockShift) + PageIndex;
SmFlushTimer = 0;
SmFlushFlag = false;
SmNeedSetExtra = true;
Status = SmWritePage(PhyPageAddr);
return STATUS_SUCCESS;
}
//----------------------------------------------------------------------------
// Description:
// Get the index of FLASH chip type
//----------------------------------------------------------------------------
BYTE SmGetFlashTypeIndex (BYTE Id)
{
BYTE i = 0;
while (SmDeviceTab[i].DeviceId != 0x00)
{
if (Id == SmDeviceTab[i].DeviceId)
{
return i;
}
i++;
}
return 0xff;
}
//----------------------------------------------------------------------------
// Description:
// Read system information of SmartMedia
//----------------------------------------------------------------------------
STATUS SmReadFlashInfo (void)
{
BYTE Id;
UINT16 i;
// Read Device ID and get system information
Id = SmReadId();
SmDeviceIndex = SmGetFlashTypeIndex(Id);
if (SmDeviceIndex == 0xff)
{
return STATUS_NO_MEDIA;
}
for (i = 0; i < MAX_PAGES_PER_BLOCK; i++)
{
SmCleanPage[i] = false;
}
SmPage2BlockShift = SmDeviceTab[SmDeviceIndex].PagesShift;
SmBlocksPerChipShift = SmDeviceTab[SmDeviceIndex].BlocksShift;
SmPagesPerChipShift = SmBlocksPerChipShift + SmPage2BlockShift;
SmAvailableBlocks = SmDeviceTab[SmDeviceIndex].AvailableBlocks * SmMaxChipsPerDevice;
SmPagesPerBlock = 1 << SmPage2BlockShift;
SmBlockPageMask = SmPagesPerBlock - 1;
SmChipPageMask = ((UINT32)1 << SmPagesPerChipShift) - 1;
for (i = 0; i < SM_MAX_SEGMENTS_PER_DEVICE; i++)
{
SmFreeBlockPtr[i] = 0;
}
SmSrcBlock = FREE_BLOCK;
SmDestBlock = FREE_BLOCK;
#ifdef SM_FAST
SmBlockTabSeg = 0xFF;
#endif
#ifdef ERASE_ALL
SmEraseAll();
#endif
SmReadBlockTab(0);
SmAvailableBlocks = SmAvailableBlocks; // We don't need config data block
SmAvailableSectors = ((UINT32)SmAvailableBlocks << SmPage2BlockShift) - 1;
SmDeviceLastPage = ((UINT32)1 << SmPagesPerChipShift) * SmMaxChipsPerDevice - 1;
return STATUS_SUCCESS;
}
//----------------------------------------------------------------------------
// Description:
//
//----------------------------------------------------------------------------
void SmMediaChange (void)
{
if (SmMediaStatus == STATUS_NO_MEDIA)
{
SmMediaStatus = SmReadFlashInfo();
}
else
{
SmAvailableSectors = 0;
SmMediaStatus = STATUS_NO_MEDIA;
}
}
//----------------------------------------------------------------------------
// Description:
//
//----------------------------------------------------------------------------
void SmInit (void)
{
SmMediaChange();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -