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

📄 zlg_ffs.c

📁 zlg nand flash 写平衡 在LINUX XIA
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************Copyright (c)**************************************************
**                               Guangzou ZLG-MCU Development Co.,LTD.
**                                      graduate school
**                                 http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name:			ZLG_FFS.c
** Last modified Date:  2004-11-08
** Last Version:		1.0
** Descriptions:		k9f2808 driver
**
**------------------------------------------------------------------------------------------------------
** Created by:			Chenmingji
** Created date:		2004-11-08
** Version:				1.0
** Descriptions:		The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
********************************************************************************************************/
#define IN_ZLG_FFS

#include "config.h"
//#include <stdlib.h>

#define  BAD_BLOCK       0
#define  FREE_BLOCK      1
#define  USR_BLOCK       2

#define  USR_BLOCK_ADD   0x20

/*********************************************************************************************************
        设置坏块
*********************************************************************************************************/
        static uint8 FFSSetBadBlock(FFSDisk *Index, uint16 BlockIndex)
{
    uint8 *bufa;
    const FlashDriver *Drive;
    unsigned int BytsPerSec;
    
    if (Index != NULL)
    {
        Drive = Index->Drive;
        bufa = (uint8 *)(Drive->BufA);
        BytsPerSec = Drive->BytsPerSec;
        if (Drive->SectorRead(Drive->Index, bufa, BlockIndex / (BytsPerSec * 8)) == TRUE)
        {
            bufa[BlockIndex % BytsPerSec] &= ~(1 << (BlockIndex % 8));
            Index->BlockState[BlockIndex] = BAD_BLOCK;
            Index->BlockEaseSum[BlockIndex] = ~0;
            return Drive->SectorWrite(Drive->Index, bufa, BlockIndex / (BytsPerSec * 8));
        }
    }
    return FALSE;
}

/* 扇区扩展数据结构:                                   */
/* buf[0..3]:  块索引,0x00000000和0xffffffff为空闲    */
/* buf[4..4]:  有效标志:'Z'                            */
/* buf[5..5]:  使用标志:0:已经使用                     */
/* buf[5..7]:  保留原始状态                            */
/* buf[8..11]: 擦除次数,低字节在前                    */
/* buf[12..15]:保留                                    */

/*********************************************************************************************************
        擦除块
*********************************************************************************************************/
        static uint8 FFSBlockErase(FFSDisk *Index, uint16 BlockIndex)
{
    const FlashDriver *Drive;
    uint32 temp1, temp2;
    uint8 *BufA;
    
    Drive = Index->Drive;
    BufA = Drive->BufA;
    if (Drive->ExSectorRead(Drive->Index, BufA, BlockIndex * (Drive->SecsPreBlock)) == FALSE)
    {
        goto err;
    }
    BufA[0] = 0xff;
    BufA[1] = 0xff;
    BufA[2] = 0xff;
    BufA[3] = 0xff;

    temp1 = (BufA[11] << 8) | BufA[10];
    temp1 = temp1 << 16;
    temp1 |= ((BufA[9] << 8) | BufA[8]);

    if (BufA[4] == 'Z')
    {
        temp1++;
    }
    else
    {
        temp1 = 0;
    }
    Drive->BufA[4] = 'Z';
    Drive->BufA[5] = 0xff;
    
    BufA[8] = temp1;
    BufA[9] = temp1 >> 8;
    BufA[10] = temp1 >> 16;
    BufA[11] = temp1 >> 24;

    Index->BlockEaseSum[BlockIndex] = temp1;
    Index->BlockState[BlockIndex] = FREE_BLOCK;
    if (Drive->BlockErase(Drive->Index, BlockIndex * Drive->SecsPreBlock) == FALSE)
    {
        goto err;
    }
    
    temp1 = Drive->SecsPreBlock;
    temp2 = BlockIndex * temp1;

    do
    {
        if (Drive->ExSectorWrite(Drive->Index, BufA, temp2) == FALSE)
        {
            goto err;
        }
        if (Drive->ExSectorCheck(Drive->Index, BufA, temp2) == FALSE)
        {
            goto err;
        }

    /* 校验 */    
        if ((Drive->ExSectorRead(Drive->Index, BufA, temp2++)) == FALSE)
        {
            goto err;
        }
        if (BufA[0] != 0xff)
        {
            goto err;
        }
        if (BufA[1] != 0xff)
        {
            goto err;
        }
        if (BufA[2] != 0xff)
        {
            goto err;
        }
        if (BufA[3] != 0xff)
        {
            goto err;
        }

        if (BufA[4] != 'Z')
        {
            goto err;
        }

        if (BufA[5] != 0xff)
        {
            goto err;
        }
    } while (--temp1 != 0);

    return TRUE;
err:
    return FFSSetBadBlock(Index, BlockIndex);
}


/*********************************************************************************************************

*********************************************************************************************************/

const static uint8 logo[16] = {'Z', 'L', 'G', '\\', 'F', 'F', 'S', 0,
                        'V',  0,   1,   0,   1,   0,   0,   0 };
const static uint8 logo1[16] = {0xb3, 0xc2, 0xc3, 0xf7, 0xbc, 0xc6, 0, 0,
                         '2', '0', '0', '4', '1', '1',  0,   0 };

        static uint8 NFFormatA(FFSDisk *Index)
{
    uint32 i, temp;
    unsigned int j, k;
    const FlashDriver *Drive;
    uint8 *bufa;

    Drive = Index->Drive;
    temp = Drive->BlockPreDisk;
    /* 设置坏块表 */
    Drive->BlockErase(Drive->Index, 0);
    bufa = Drive->BufA;

    j = Drive->BytsPerSec;
    do
    {
        *bufa++ = 0xff;
    } while ( --j != 0);
    
    bufa = Drive->BufA;
    for (i = 1; i < Drive->BlockPreDisk; i++)
    {
        
        if ((Drive->BlockCheck(Drive->Index, i)) != TRUE)
        {
            bufa[(i / 8) % (Drive->BytsPerSec)] &= ~(1 << (i % 8));
        }
        if ((i % (Drive->BytsPerSec * 8)) == 0)
        {
            bufa = Drive->BufA;
            Drive->SectorWrite(Drive->Index, bufa, i / (Drive->BytsPerSec * 8));

            j = Drive->BytsPerSec;
            do
            {
                *bufa++ = 0xff;
            } while (--j != 0);
            bufa = Drive->BufA;
        }
    }
    /* 设置logo */
    Drive->ExSectorWrite(Drive->Index, (uint8 *)logo, 0);
    Drive->ExSectorWrite(Drive->Index, (uint8 *)logo, Drive->SecsPreBlock - 1);

    /* 初始化扇区 */
    
    k = 0;
    bufa = Drive->BufA;
    Drive->SectorRead(Drive->Index, bufa, 0);
    for (i = 1; i < Drive->BlockPreDisk; i++)
    {
        if ((i % (Drive->BytsPerSec * 8)) == 0)
        {
            k++;
            Drive->SectorRead(Drive->Index, bufa, k);
        }
        if ((bufa[i % (Drive->BytsPerSec)] & (1 << (i % 8))) != 0)
        {
            FFSBlockErase(Index, i);
            Drive->SectorRead(Drive->Index, bufa, k);
        }
    }

    /* 初始化第0扇区 */
    
    k = 0;
    bufa = Drive->BufA;
    Drive->SectorRead(Drive->Index, bufa, 0);
    for (i = 1; i < Drive->BlockPreDisk; i++)
    {
        if ((i % (Drive->BytsPerSec * 8)) == 0)
        {
            k++;
            Drive->SectorRead(Drive->Index, bufa, k);
        }
        if ((bufa[(i / 8) % (Drive->BytsPerSec)] & (1 << (i % 8))) != 0)
        {
            temp = (Drive->SecsPreBlock) * i;
            Drive->ExSectorRead(Drive->Index, bufa, temp);
            bufa[0] = 0x01;
            bufa[1] = 0x00;
            bufa[2] = 0x00;
            bufa[3] = 0x00;
            if (Drive->ExSectorWrite(Drive->Index, bufa, temp) ==FALSE)
            {
                FFSSetBadBlock(Drive->Index, temp / Drive->SecsPreBlock);
                break;
            }
            if (Drive->ExSectorCheck(Drive->Index, bufa, temp) ==FALSE)
            {
                FFSSetBadBlock(Drive->Index, temp / Drive->SecsPreBlock);
                break;
            }
            break;
        }
    }
    return TRUE;
}
     
     static uint8 NFFormatB(FFSDisk *Index)        
{
    uint32 i, BlockPreDisk;
    unsigned int BytsPerSec;
    unsigned int k;
    const FlashDriver *Drive;
    uint8 *bufa;

    if (Index == NULL)
    {
        return FALSE;
    }
    
    Drive = Index->Drive;
    bufa = Drive->BufA;
    BytsPerSec = Drive->BytsPerSec;
    BlockPreDisk = Drive->BlockPreDisk;

    /* 初始化扇区 */
    k = 0;
    Drive->SectorRead(Drive->Index, bufa, 0);
    for (i = 1; i < BlockPreDisk; i++)
    {
        if ((i % (BytsPerSec * 8)) == 0)
        {
            k++;
            Drive->SectorRead(Drive->Index, bufa, k);
        }
        if ((bufa[(i / 8) % BytsPerSec] & (1 << (i % 8))) != 0)
        {
            FFSBlockErase(Index, i);
            Drive->SectorRead(Drive->Index, bufa, k);
        }
    }
    /* 初始化第0扇区 */
    
    k = 0;
    bufa = Drive->BufA;
    Drive->SectorRead(Drive->Index, bufa, 0);
    for (i = 1; i < Drive->BlockPreDisk; i++)
    {
        if ((i % (Drive->BytsPerSec * 8)) == 0)
        {
            k++;
            Drive->SectorRead(Drive->Index, bufa, k);
        }
        if ((bufa[i % (Drive->BytsPerSec)] & (1 << (i % 8))) != 0)
        {
            i = (Drive->SecsPreBlock) * i;
            Drive->ExSectorRead(Drive->Index, bufa, i);
            bufa[0] = 0x01;
            bufa[1] = 0x00;
            bufa[2] = 0x00;
            bufa[3] = 0x00;
            if (Drive->ExSectorWrite(Drive->Index, bufa, i) == FALSE)
            {
                FFSSetBadBlock(Drive->Index, i / Drive->SecsPreBlock);
                break;
            }
            if (Drive->ExSectorCheck(Drive->Index, bufa, i) == FALSE)
            {
                FFSSetBadBlock(Drive->Index, i / Drive->SecsPreBlock );
                break;
            }
            break;
        }
    }    
    return TRUE;
}

        static uint8 NFFormat(FFSDisk *Index)
{
    uint8 *buf;
    
    buf = Index->Drive->BufA;
    if (Index != NULL)
    if (Index->Drive->ExSectorRead(Index->Drive->Index, buf, 0) == TRUE)
    {
        if (buf[0] != 'Z'  ||
            buf[1] != 'L'  ||
            buf[2] != 'G'  ||
            buf[3] != '\\' ||
            buf[4] != 'F'  ||
            buf[5] != 'F'  ||
            buf[6] != 'S'  ||
            buf[7] != 0)
        {
            return NFFormatA(Index);
        }
        else
        {
            return NFFormatB(Index);
        }
    }
    return FALSE;
}

/*********************************************************************************************************
        初始化
*********************************************************************************************************/
        static uint8 FFSDiskInit(FFSDisk *Index)
{
    uint32 i, temp, temp1, temp2, temp3;
    unsigned int j, k, m, n, BytsPerSec;
    const FlashDriver *Drive;
    uint8 *bufa;
    uint32 *VBlockInfo;
    

    /* 检查参数有效性 */
    if (Index == NULL)
    {
        return DISK_INIT_NOT_OK;
    }
    Drive = Index->Drive;

    if (Drive == NULL ||
        Drive->SectorRead == NULL    ||
        Drive->ExSectorRead == NULL  ||
        Drive->SectorWrite == NULL   ||
        Drive->ExSectorWrite == NULL ||
        Drive->BlockErase == NULL    ||
        //Drive->SecCopy == NULL       ||
        Drive->SectorCheck == NULL   ||
        Drive->ExSectorCheck == NULL
        )
    {
        return DISK_INIT_NOT_OK;
    }

    bufa = Drive->BufA;

    if (Drive->ExSectorRead(Drive->Index, bufa, 0) == FALSE)
    {
        return DISK_INIT_NOT_OK;
    }

    /* 没有低级格式化就低级格式化  */
    if (bufa[0] != 'Z'  ||
        bufa[1] != 'L'  ||
        bufa[2] != 'G'  ||
        bufa[3] != '\\' ||
        bufa[4] != 'F'  ||
        bufa[5] != 'F'  ||
        bufa[6] != 'S'  ||
        bufa[7] != 0)
    {
        NFFormatA(Index);
    }

    /* 获取必须的内存空间 */
    i = Drive->BlockPreDisk;

⌨️ 快捷键说明

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