⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sm.c

📁 Falsh 读写的demo
💻 C
📖 第 1 页 / 共 3 页
字号:

        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 + -