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

📄 sm.c

📁 Falsh 读写的demo
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
*********************************************************************************************************
* File     : Sm.C
* Contents :
*
* $Date    : 09/18/06    Kimi    v0.1
* $Date    : 10/18/06    Kimi    v0.2
* $Date    : 11/02/06    Kimi    v1.0
*
* Copyright (c) 2006 Fameg, Inc. All rights reserved
*********************************************************************************************************
*/

#include "sm.h"

//----------------------------------------------------------------------------
// Description:
//   Set SegmentBase
//----------------------------------------------------------------------------
void  SmEraseAll (void)
{
    UINT16  j;
    UINT16  SmTotalBlocks = ((UINT16)1 << SmBlocksPerChipShift) * SmMaxChipsPerDevice;

    for (j = 0; j < SmTotalBlocks; j++)
        SmEraseBlock(j);
}

//----------------------------------------------------------------------------
// Description:
//   Set SegmentBase
//----------------------------------------------------------------------------
void  SmSetSegmentBase (BYTE Segment)
{
    SegmentBase = (((UINT16)(Segment / PLANE_NUMBER) << SmBlock2SegShift) * PLANE_NUMBER) + (Segment % PLANE_NUMBER);
}

//----------------------------------------------------------------------------
// Description:
//   Parse the active FLASH chip Status
//----------------------------------------------------------------------------
STATUS  SmParseStatus (STATUS Status)
{
    if ((Status & 0x40) == 0)
    {
        return STATUS_FLASH_ERROR;
    }
    else if ((Status & 0x80) == 0)
    {
        return STATUS_WRITE_PROTECT;
    }
    else if ((Status & 0x01) == 1)
    {
        return STATUS_FLASH_ERROR;
    }
    else
    {
        return STATUS_SUCCESS;
    }
}

//----------------------------------------------------------------------------
// Description:
//   Select the active FLASH chip
//----------------------------------------------------------------------------
void  SmSelectChip (BYTE Chip)
{
    switch (Chip)
    {
        case 0:
            APLIFARL        = 0xFC;
            ReadyBusy       = 0x02;
            break;
        case 1:
            APLIFARL        = 0xFA;
            ReadyBusy       = 0x04;
            break;
        case 2:
            APLIFARL        = 0xF6;
            ReadyBusy       = 0x08;
            break;
        case 3:
            APLIFARL        = 0xEE;
            ReadyBusy       = 0x10;
            break;
        default:
            ;
    }
}

//----------------------------------------------------------------------------
// Description:
//   Set the extra area of one block, especially the block address
//----------------------------------------------------------------------------
void  SmSetBlockExtra (UINT16 BlockAddr)
{
    BlockAddr      &= SmBlockSegMask;                  // Segment LBA between 0 and 999
// Block Address Field = (Segment LBA) * 2 + 0x1000 + P (P : EvenParityData)
    BlockAddr     <<= 1;
    BlockAddr      |= 0x1000;
    if (!EvenParity(BlockAddr))
    {
        BlockAddr  |= 0x0001;
    }

    SpareArea[BLOCK_STS]        = VALID_BLOCK;
    SpareArea[DATA_STS]         = VALID_DATA;

    SpareArea[BLOCK_ADDR1_L]    = ((TDataCast *)&BlockAddr)->ucByte[1];
    SpareArea[BLOCK_ADDR2_L]    = ((TDataCast *)&BlockAddr)->ucByte[1];
    SpareArea[BLOCK_ADDR1_H]    = ((TDataCast *)&BlockAddr)->ucByte[0];
    SpareArea[BLOCK_ADDR2_H]    = ((TDataCast *)&BlockAddr)->ucByte[0];
}

//----------------------------------------------------------------------------
// Description:
//   Set the FLASH address for the followed FLASH access
//----------------------------------------------------------------------------
void  SmSetFlashAddr (UINT32 Page)
{
    BYTE    Chip = Page >> SmPagesPerChipShift;        // Calculate Chip Number
    Page    = Page & SmChipPageMask;                   // Make Chip Address in the correct range

    SmSelectChip(Chip);                                // Select Corresponding Chip

    FlashAddress[FLASH_ADDR0]   = 0x00;
    FlashAddress[FLASH_ADDR1]   = 0x00;
    FlashAddress[FLASH_ADDR2]   = ((TDataCast *)&Page)->ucByte[3];
    FlashAddress[FLASH_ADDR3]   = ((TDataCast *)&Page)->ucByte[2];
    FlashAddress[FLASH_ADDR4]   = ((TDataCast *)&Page)->ucByte[1];
}

//----------------------------------------------------------------------------
// Description:
//   Complete the NAND FLASH Command Function (Key Function)
//----------------------------------------------------------------------------
STATUS  SmFlashCmd (BYTE Cmd)
{
    switch (Cmd)
    {
        case FLASH_READ_EX:
            FlashAddress[FLASH_ADDR1]   = 0x08;
            NanD_Command(0x00);
            NanD_Address(FlashAddress[FLASH_ADDR0]);
            NanD_Address(FlashAddress[FLASH_ADDR1]);
            NanD_Address(FlashAddress[FLASH_ADDR2]);
            NanD_Address(FlashAddress[FLASH_ADDR3]);
            NanD_Address(FlashAddress[FLASH_ADDR4]);
            NanD_Command(0x30);
            while (!(APLIFREADYSTAT & ReadyBusy));
            Nand_ReadSpare();
            break;
        case FLASH_READ:
            NanD_Command(0x00);
            NanD_Address(FlashAddress[FLASH_ADDR0]);
            NanD_Address(FlashAddress[FLASH_ADDR1]);
            NanD_Address(FlashAddress[FLASH_ADDR2]);
            NanD_Address(FlashAddress[FLASH_ADDR3]);
            NanD_Address(FlashAddress[FLASH_ADDR4]);
            NanD_Command(0x30);
            while (!(APLIFREADYSTAT & ReadyBusy));
            Nand_ReadSector();
            break;
        case FLASH_READ_NEXT_DATA:
            Nand_ReadSector();
            break;
        case FLASH_READ_ID:
            NanD_Command(0x90);
            NanD_Address(0x00);
            FlashId[0]                  = NanD_Read();
            FlashId[1]                  = NanD_Read();
            FlashId[2]                  = NanD_Read();
            FlashId[3]                  = NanD_Read();
            FlashId[4]                  = NanD_Read();
            break;
        case FLASH_READ_STS:
            NanD_Command(0x70);
            FlashSts                    = NanD_Read();
            break;
        case FLASH_PROG:
            NanD_Command(0x80);
            NanD_Address(FlashAddress[FLASH_ADDR0]);
            NanD_Address(FlashAddress[FLASH_ADDR1]);
            NanD_Address(FlashAddress[FLASH_ADDR2]);
            NanD_Address(FlashAddress[FLASH_ADDR3]);
            NanD_Address(FlashAddress[FLASH_ADDR4]);
            Nand_WriteSector();
            break;
        case FLASH_PROG_NEXT_DATA:
            Nand_WriteSector();
            break;
        case FLASH_PROG_EX:
            Nand_WriteSpare();
            NanD_Command(0x10);
            while (!(APLIFREADYSTAT & ReadyBusy));
            break;
        case FLASH_PAD:
            FlashAddress[FLASH_ADDR1]   = 0x08;
            NanD_Command(0x80);
            NanD_Address(FlashAddress[FLASH_ADDR0]);
            NanD_Address(FlashAddress[FLASH_ADDR1]);
            NanD_Address(FlashAddress[FLASH_ADDR2]);
            NanD_Address(FlashAddress[FLASH_ADDR3]);
            NanD_Address(FlashAddress[FLASH_ADDR4]);
            Nand_WriteSpare();
            NanD_Command(0x10);
            while (!(APLIFREADYSTAT & ReadyBusy));
            break;
        case FLASH_ERASE:
            NanD_Command(0x60);
            NanD_Address(FlashAddress[FLASH_ADDR2]);
            NanD_Address(FlashAddress[FLASH_ADDR3]);
            NanD_Address(FlashAddress[FLASH_ADDR4]);
            NanD_Command(0xD0);
            while (!(APLIFREADYSTAT & ReadyBusy));
            break;
        case FLASH_CP:
            NanD_Command(0x00);
            NanD_Address(FlashAddress[FLASH_ADDR0]);
            NanD_Address(FlashAddress[FLASH_ADDR1]);
            NanD_Address(FlashAddress[FLASH_ADDR2]);
            NanD_Address(FlashAddress[FLASH_ADDR3]);
            NanD_Address(FlashAddress[FLASH_ADDR4]);
            NanD_Command(0x35);
            while (!(APLIFREADYSTAT & ReadyBusy));
            break;
        case FLASH_CP_PROG:
            NanD_Command(0x85);
            NanD_Address(FlashAddress[FLASH_ADDR0]);
            NanD_Address(FlashAddress[FLASH_ADDR1]);
            NanD_Address(FlashAddress[FLASH_ADDR2]);
            NanD_Address(FlashAddress[FLASH_ADDR3]);
            NanD_Address(FlashAddress[FLASH_ADDR4]);
            NanD_Command(0x10);
            while (!(APLIFREADYSTAT & ReadyBusy));
            break;
        default:
            ;
    }
    SmCmdStatus = STATUS_SUCCESS;

    return STATUS_SUCCESS;
}

//----------------------------------------------------------------------------
// Description:
//   Read the FLASH ID and Quantity
//----------------------------------------------------------------------------
BYTE  SmReadId (void)
{
    BYTE    RetryCount, Id[4], Chip;

    for (Chip = 0; Chip < 4; Chip++)                   // Scan All Possible Chip
    {
        SmSelectChip(Chip);                            // Select Current Chip

        for (RetryCount = 0; RetryCount < 3; RetryCount++)
        {
            if (SmFlashCmd(FLASH_READ_ID) != STATUS_SUCCESS)
            {
                continue;
            }
            Id[Chip]    = FlashId[1];
            break;
        }
        if (Id[0] != 0xFF)
        {
            if (Chip == 0)
            {
                SmMaxChipsPerDevice = 1;
            }
            else if (Id[Chip] == Id[0])
            {
                SmMaxChipsPerDevice++;
            }
        }
    }
    return Id[0];
}

//----------------------------------------------------------------------------
// Description:
//   Read the FLASH status of Current Chip
//----------------------------------------------------------------------------
BYTE  SmReadStatus (void)
{
    BYTE    RetryCount, Status;

    for (RetryCount = 0; RetryCount < 3; RetryCount++)
    {
        if (SmFlashCmd(FLASH_READ_STS) != STATUS_SUCCESS)
        {
            continue;
        }

        Status  = FlashSts;
        break;
    }
    return Status;
}

//----------------------------------------------------------------------------
// Description:
//   Read one page of data from SmartMedia to FIFO
//----------------------------------------------------------------------------
STATUS  SmReadPage (UINT32 Page)
{
    STATUS  RetVal;
    BYTE    RetryCount;

    for (RetryCount = 0; RetryCount < 3; RetryCount++)
    {
// Add Read Redundant Area Code Begin
        SmSetFlashAddr(Page);                          // Prepare Address for sending

        SmFlashCmd(FLASH_READ_EX);                     // Combine with SmFlashCmd(FLASH_READ)?
// Add Read Redundant Area Code End

        SmSetFlashAddr(Page);

        if ((SmFlashCmd(FLASH_READ)) != STATUS_SUCCESS)
        {
            RetVal  = STATUS_FLASH_ERROR;
            continue;
        }

/*
*********************************************************************************************************
* ECC Detect Area
*********************************************************************************************************
*/

        if (SpareArea[DATA_STS] != VALID_DATA)
        {
            RetVal  = STATUS_DATA_ERROR;
            continue;
        }

        ChunkCounter++;
        return STATUS_SUCCESS;
    }
    return RetVal;
}

//----------------------------------------------------------------------------
// Description:
//   Write one page of data from FIFO to SmartMedia
//----------------------------------------------------------------------------
STATUS  SmWritePage (UINT32 Page)
{
    BYTE    RetryCount;
    STATUS  RetVal;

    for (RetryCount = 0; RetryCount < 3; RetryCount++)
    {
        if (SmNeedSetExtra)
        {
            SmSetBlockExtra(SmSrcBlockLog);            // Prepare Redundant Area Data
        }

        SmSetFlashAddr(Page);                          // Prepare Address for sending

        if ((SmFlashCmd(FLASH_PROG)) != STATUS_SUCCESS)
        {
            RetVal  = STATUS_FLASH_ERROR;
            continue;
        }

/*
*********************************************************************************************************
* ECC Generate Area
*********************************************************************************************************
*/

        ChunkCounter++;
        return STATUS_SUCCESS;
    }
    return RetVal;
}

//----------------------------------------------------------------------------
// Description:
//   Read next 512 bytes of data from the Smart Media device
//----------------------------------------------------------------------------
STATUS  SmReadNextSector (void)
{
    STATUS  RetVal;
    BYTE    RetryCount;

    for (RetryCount = 0; RetryCount < 3; RetryCount++)
    {
        if ((SmFlashCmd(FLASH_READ_NEXT_DATA)) != STATUS_SUCCESS)
        {
            RetVal  = STATUS_FLASH_ERROR;
            continue;
        }

/*
*********************************************************************************************************
* ECC Detect Area
*********************************************************************************************************
*/

        if (ChunkCounter == 3)
        {
            ChunkCounter    = 0;
            SectorStart++;
        }
        else
        {
            ChunkCounter++;
        }

        return STATUS_SUCCESS;
    }
    return RetVal;
}

//----------------------------------------------------------------------------
// Description:
//   Write next 512 bytes of data from the Smart Media device
//----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -