📄 doc_api.c
字号:
/*
* 文件名称: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 + -