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

📄 sm.c

📁 Falsh 读写的demo
💻 C
📖 第 1 页 / 共 3 页
字号:
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 + -