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

📄 doc_api.c

📁 DiskOnChip for 8051 MCU 的 API 源代码和文档
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
* 文件名称:DOC_API.C
* 内容摘要:在 51 MCU 上对 DOC 进行读、写、擦除操作的 API 的实现
* 
* 当前版本:1.0
* 作    者:庄渭峰
* 完成日期:2003年2月6日
*
* 原 作 者:M-Systems 公司
* 版    本:BDK 1.25
*/

#include "doc_api.h"
#include "doc_def.h"
#include <string.h>

#ifdef EDC_MODE
#include "doc_ecc.h"
#endif /* EDC_MODE */

/*-------------------------------------------------------------------
 * Memory access functions
 *-------------------------------------------------------------------*/
#define docWrite8bitReg(offset,data)  (*((volatile byte *)docWin + offset)) = ((byte)(data))
#define docRead8bitReg(offset)        (byte)(*((volatile byte *)docWin + offset))

/*---------------------------------------------------------------------
 * Function prototypes
 *---------------------------------------------------------------------*/
static void      command     (byte code1);
static void      setAddress  (dword address);
static FLStatus  waitForReady(void);
static byte      readStatus  (void);
static void      selectDev   (byte dev);
static void      selectFloor (byte floor);
static void      readFlash   (byte *buf, word len);
static void      writeSignals(byte val);
static byte      busy        (void);
static void      setAsicMode (byte mode);
#ifdef EDC_MODE
static void      readSyndrom (byte *buf, word len);
       void      eccOFF(void);
static void      eccONread(void);
static byte      eccError(void);
#endif /* EDC_MODE */

static void      writeFlash(byte *buf, word len);
static FLStatus  writeExecute(void);
static void      writeCommand(enum PointerOp cmd, dword addr);
#ifdef EDC_MODE
static void      eccONwrite(void);
byte zeroes3[3] = { 0x00, 0x00, 0x00 };
byte syndromEDC[SYNDROM_BYTES];
#endif /* EDC_MODE */

/*---------------------------------------------------------------------
 * Global data, first initialization is in readFlashId function.
 *---------------------------------------------------------------------*/
byte     *docWin;            /* pointer to DOC 2000 memory window */
word     Nio;                /* pointer to DOC / MDOC IO window   */
word     ECCstatus;          /* pointer to ECC status Reg */
DOCInfo  docInfo;

void pause( void )
{
    byte i;
    for ( i = 0; i < 1; i++ );
}

#ifndef DOC_IS_FIXED
/*--------------------------------------------------------------------
 * readFlashID - Select chip number given by 'dev', reset it
 * and read vendor and chip ID.
 *--------------------------------------------------------------------*/
FLStatus readFlashID( byte floor, byte dev )
{
    byte         vendorId, chipId;
    static byte  firstChipId;
    int          i;

    setAsicMode(ASIC_NORMAL_MODE);

    /* select docWin_io according to ASIC type */
    if( docInfo.flags & MDOC_ASIC )
    {
        Nio = Nio_MDOC;
        ECCstatus = NECCstatus_MDOC;
    }
    else
    {
        Nio = Nio_DOC;
        ECCstatus = NECCstatus_DOC;
    }

    /* select 'dev' flash device and reset it */
    selectDev(dev);
    command(RESET_FLASH);

    if( waitForReady() != flOK )
    {
        return(flDOCNotReady);
    }

    /* send READ_ID command accompanied by 1-byte address */
    command(READ_ID);
    writeSignals(FLASH_IO | ALE | CE | WP);
    docWrite8bitReg(Nio,0);
    if( docInfo.flags & MDOC_ASIC )
    {
        docWrite8bitReg(NWritePipeTerm,0);
    }
    writeSignals(FLASH_IO |       CE | WP);

    /* read vendor ID  */
    pause( );                        /* wait for 1 ms */
    docRead8bitReg(NslowIO);         /* read CDSN_slow_IO ignoring the data */
    for(i=0;( i < 2 ); i++)          /* perform 2 reads from CDSN_control   */
    {
        docRead8bitReg(NNop);        /* to create delay               */
    }

    vendorId = docRead8bitReg(Nio);  /* finally read vendor ID */

    /* read chip ID */
    pause( );                        /* wait for 1 ms */
    docRead8bitReg(NslowIO);         /* read CDSN_slow_IO ignoring the data */
    for(i=0;( i < 2 ); i++)          /* perform 2 reads from CDSN_control   */
    {
        docRead8bitReg(NNop);        /* to create delay               */
    }

    chipId = docRead8bitReg(Nio);    /* finally read chip ID */

    writeSignals(FLASH_IO | WP);

    if( (floor == 0) && (dev == 0) )
    {
        /* set initial parameters */
        docInfo.pageSize          = CHIP_PAGE_SIZE;
        docInfo.erasableBlockSize = PAGES_PER_BLOCK * CHIP_PAGE_SIZE;
        docInfo.pagesPerBlock     = PAGES_PER_BLOCK;
        docInfo.chipSize          = CHIP_SIZE;  /* 2 MByte */
        docInfo.noOfBlocks        = BLOCKS_PER_FLASH;

        firstChipId = chipId;
        /* set flash parameters */
        switch( vendorId )
        {
            case 0x98:                                   /* Toshiba */
            case 0x01:                                   /* AMD */
            case 0x04:                                   /* Fujitsu */
                docInfo.flags            |= FULL_PAGE;
                /* no break here */
            case 0xEC:                                   /* Samsung */
                switch( chipId )
                {
                    case 0x64:                              /* 2 Mb */
                    case 0xEA:
                        docInfo.pageSize          = CHIP_PAGE_SIZE;  /* 0x100; */
                        docInfo.erasableBlockSize = PAGES_PER_BLOCK * docInfo.pageSize;
                        break;

                    case 0xE6:                              /* 8 Mb */
                        docInfo.chipSize         *= 2;
                        docInfo.noOfBlocks       *= 2;               /* 1024 */
                        /* no break here */
                    case 0xE3:                              /* 4 Mb */
                    case 0xE5:
                    case 0x6B:
                        docInfo.pageSize          = CHIP_PAGE_SIZE * 2; /* 0x200; */
                        docInfo.erasableBlockSize = PAGES_PER_BLOCK * docInfo.pageSize;
                        docInfo.flags            |= BIG_PAGE;
                        docInfo.chipSize         *= 2;
                        break;

                    case 0x76:                              /* 64 Mb */
                        docInfo.flags            |= BIG_ADDR;
                        docInfo.noOfBlocks       *= 2;               /* 4096 */
                        docInfo.chipSize         *= 2;
                        /* no break here */
                    case 0x75:                              /* 32 Mb */
                        docInfo.chipSize         *= 2;
                        docInfo.noOfBlocks       *= 2;               /* 2048 */
                        /* no break here */
                    case 0x73:                              /* 16 Mb */
                        docInfo.pageSize          = CHIP_PAGE_SIZE * 2; /* 0x200; */
                        docInfo.erasableBlockSize = PAGES_PER_BLOCK * docInfo.pageSize * 2;
                        docInfo.flags            |= BIG_PAGE;
                        docInfo.chipSize         *= 8;
                        docInfo.noOfBlocks       *= 2;               /* 1024 */
                        docInfo.pagesPerBlock    *= 2;               /* 32 */
                        break;

                    default:
                        return( flUnknownMedia );
                }
                break;

            default:
                return( flUnknownMedia );
        }
    }
    else
    {
        if( chipId != firstChipId )
        {
            return( flUnknownMedia );
        }
    }
    return( flOK );
}
#endif /* DOC_IS_FIXED */

/*-------------------------------------------------------------------
 * command - Latch a command.
 *-------------------------------------------------------------------*/
static void command( byte code1 )
{
    writeSignals(FLASH_IO | CLE | CE);
    docWrite8bitReg(Nio,code1);
    if( docInfo.flags & MDOC_ASIC )
    {
        docWrite8bitReg(NWritePipeTerm,code1);
    }
    writeSignals(FLASH_IO       | CE);
}

/*-------------------------------------------------------------------
 * setAddress - Latch an address.
 *-------------------------------------------------------------------*/
static void setAddress( dword address )
{
    address &= (docInfo.chipSize - 1);    /* address within flash device */
    if ( docInfo.flags & BIG_PAGE )
    {
        /*
           bits  0..7     unchanged
           bit      8     discarded
           bits 31..9 ->  bits 30..8
        */
        address = ((address >> 9) << 8) | ((byte)address);
    }

    writeSignals(FLASH_IO | ALE | CE);

    docWrite8bitReg(Nio,(byte)(address));
    docWrite8bitReg(Nio,(byte)(address >> 8));
    docWrite8bitReg(Nio,(byte)(address >> 16));
    if( docInfo.flags & BIG_ADDR )
    {
        docWrite8bitReg(Nio,(byte)(address >> 24));
    }
    if( docInfo.flags & MDOC_ASIC )
    {
        docWrite8bitReg(NWritePipeTerm,0);
    }

    writeSignals(FLASH_IO | ECC_IO | CE);
}

/*-------------------------------------------------------------------
 * writeSignals - write to CDSN_control_reg
 *-------------------------------------------------------------------*/
static void writeSignals( byte val )
{
    int i;

    docWrite8bitReg(Nsignals,val);
    /* after writing to CDSN_control perform 2 reads from there */
    for(i=0;( i < 2 );i++)
    {
        docRead8bitReg(NNop);
    }
}

/*-------------------------------------------------------------------
 * waitForReady - Returns FALSE on timeout error, otherwise TRUE.
 *-------------------------------------------------------------------*/
static FLStatus waitForReady( void )
{
    int i;

    for(i=0;( i < BUSY_DELAY );i++)
    {
        if( busy() )
        {
            continue;
        }
        return( flOK );                    /* ready at last */
    }
    return( flDOCNotReady );               /* timeout error */
}

/*-------------------------------------------------------------------
 * busy - Returns zero if the selected flash device is Ready.
 *-------------------------------------------------------------------*/
static byte busy( void )
{
    int i;
    byte stat;

    /* before polling for BUSY status perform 4 read operations from CDSN_control_reg */
    for(i = 0;( i < 4 ); i++ )
    {
        docRead8bitReg(NNop);
    }

    /* read BUSY status */
    stat = docRead8bitReg(Nsignals);

    /* after BUSY status is obtained perform 2 read operations from CDSN_control_reg */
    for(i = 0;( i < 2 ); i++ )
    {
        docRead8bitReg(NNop);
    }

    return( !(stat & RB) );
}

/*-------------------------------------------------------------------
 * mapWin - Map address to appropriate flash
 *-------------------------------------------------------------------*/
static void mapWin( dword address )
{
    selectFloor((byte)(address / docInfo.floorSize));
    selectDev((byte)((address % docInfo.floorSize) / docInfo.chipSize));
}

/*-------------------------------------------------------------------
 * selectDev - Select a flash device with in the floor
 *-------------------------------------------------------------------*/
static void selectDev( byte dev )
{
    docWrite8bitReg(NdeviceSelector,dev);
}

/*-------------------------------------------------------------------
 * selectFloor - Select a flash device floor
 *-------------------------------------------------------------------*/
static void selectFloor( byte floor )
{
    docWrite8bitReg(NASICselect,floor);
}

/*-------------------------------------------------------------------
 * setAsicMode - Set the ASIC mode.
 *-------------------------------------------------------------------*/
static void setAsicMode( byte mode )
{
    docWrite8bitReg(NDOCcontrol,mode);
    docWrite8bitReg(NDOCcontrol,mode);
    pause( );
}

/*
* 函数名称: DOC_ReadOnePage
* 功能描述: 读 DOC 的一页
* 输入参数: pageNum: 页号(有效范围:[0, docInfo.noOfPages-1])
*           buf:     存放从 DOC 读出的数据的缓冲区的首地址
*           len:     数据长度(应不大于页长度即 512 字节,若大于 512 则只有前 512 个字节从 DOC 读出)
*           modes:   模式标志,当未定义 EDC_MODE 时可取 0;当定义 EDC_MODE 时,可取 EDC_FLAG 或 0
* 输出参数: 无
* 返 回 值: flOK          — 成功,无错误
*           flOutOfMedia  — 页号超出 DOC 容量范围
*           flDOCNotReady — DOC 未准备好

⌨️ 快捷键说明

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