📄 smilsub.c
字号:
/***********************************************************************
* $Workfile: smilsub.c $
* $Revision: 1.1.1.1 $
* $Author: meterchen $
* $Date: 2003/11/10 17:00:55 $
*
* Project: NAND FLASH MANAGEMENT
*
* Description:
*
*
* Revision History:
*
***********************************************************************
*
* Copyright (c) 2003 CHENMENG
*
* All rights reserved
*
**********************************************************************/
#include "common.h"
#include "smil.h"
#include "hwcfg.h"
/******************************************/
int Check$DataBlank(unsigned char *);
int Check$FailBlock(unsigned char *);
int Check$DataStatus(unsigned char *);
int Load$LogBlockAddr(unsigned char *);
void Clr$RedundantData(unsigned char *);
void Set$LogBlockAddr(unsigned char *);
void Set$FailBlock(unsigned char *);
void Set$DataStaus(unsigned char *);
/******************************************/
void Ssfdc$Reset(void);
int Ssfdc$ReadCisSect(unsigned char *,unsigned char *);
void Ssfdc$WriteRedtMode(void);
void Ssfdc$ReadID(unsigned char *);
int Ssfdc$ReadSect(unsigned char *,unsigned char *);
int Ssfdc$WriteSect(unsigned char *,unsigned char *);
int Ssfdc$WriteSectForCopy(unsigned char *,unsigned char *);
int Ssfdc$EraseBlock(void);
int Ssfdc$ReadRedtData(unsigned char *);
int Ssfdc$WriteRedtData(unsigned char *);
int Ssfdc$CheckStatus(void);
int Set$SsfdcModel(unsigned char);
void Cnt$Reset(void);
int Cnt$PowerOn(void);
void Cnt$PowerOff(void);
void Cnt$LedOn(void);
void Cnt$LedOff(void);
int Check$CntPower(void);
int Check$CardExist(void);
int Check$CardStsChg(void);
int Check$SsfdcWP(void);
/******************************************/
int Check$ReadError(unsigned char *);
int Check$Correct(unsigned char *,unsigned char *);
int Check$CISdata(unsigned char *,unsigned char *);
void Set$RightECC(unsigned char *);
/***************************************************************************/
static void _Set$SsfdcRdCmd(unsigned char);
static void _Set$SsfdcRdAddr(unsigned char);
static void _Set$SsfdcRdChip(void);
static void _Set$SsfdcRdStandby(void);
static void _Start$SsfdcRdHwECC(void);
static void _Stop$SsfdcRdHwECC(void);
static void _Load$SsfdcRdHwECC(unsigned char);
static void _Set$SsfdcWrCmd(unsigned char);
static void _Set$SsfdcWrAddr(unsigned char);
static void _Set$SsfdcWrBlock(void);
static void _Set$SsfdcWrStandby(void);
static void _Start$SsfdcWrHwECC(void);
static void _Load$SsfdcWrHwECC(unsigned char);
static int _Check$SsfdcBusy(unsigned short);
static int _Check$SsfdcStatus(void);
static void _Reset$SsfdcErr(void);
static void _Read$SsfdcBuf(unsigned char *);
static void _Write$SsfdcBuf(unsigned char *);
static void _Read$SsfdcByte(unsigned char *);
static void _ReadRedt$SsfdcBuf(unsigned char *);
static void _WriteRedt$SsfdcBuf(unsigned char *);
static unsigned char _Check$DevCode(unsigned char);
/*****/
static void _Set$ECCdata(unsigned char,unsigned char *);
static void _Calc$ECCdata(unsigned char *);
/***************************************************************************/
/* <hwcfg.h> macro definition
extern void _Hw$SetRdData(void);
extern void _Hw$SetRdCmd(void);
extern void _Hw$SetRdAddr(void);
extern void _Hw$SetRdStandby(void);
extern void _Hw$SetWrData(void);
extern void _Hw$SetWrCmd(void);
extern void _Hw$SetWrAddr(void);
extern void _Hw$SetWrStandby(void);
extern char _Hw$InData(void);
extern void _Hw$OutData(unsigned char);
extern void _Hw$VccOn(void);
extern void _Hw$VccOff(void);
extern void _Hw$LedOn(void);
extern void _Hw$LedOff(void);
extern void _Hw$EccRdReset(void);
extern void _Hw$EccRdStart(void);
extern void _Hw$EccRdStop(void);
extern void _Hw$EccRdRead(void);
extern void _Hw$EccWrReset(void);
extern void _Hw$EccWrStart(void);
extern void _Hw$EccWrStop(void);
extern void _Hw$EccWrRead(void);
extern char _Hw$ChkCardIn(void);
extern char _Hw$ChkStatus(void);
extern char _Hw$ChkWP(void);
extern char _Hw$ChkPower(void);
extern char _Hw$ChkBusy(void);
*/
extern void _Calculate$SwECC(unsigned char *, unsigned char *);
extern int _Correct$SwECC(unsigned char *, unsigned char *, unsigned char *);
/*****/
extern char Bit$Count(unsigned char);
extern char Bit$CountWord(unsigned short);
extern void StringCopy(char *, char *, int);
extern int StringCmp(char *, char *, int);
/*****/
extern void _Wait$Timer(unsigned short);
extern void _Set$Timer(unsigned short);
extern void _Stop$Timer(void);
extern int _Check$Timer(void);
/***************************************************************************/
struct SSFDCTYPE Ssfdc;
struct ADDRESS Media;
struct CIS_AREA CisArea;
/*****/
static unsigned char EccBuf[6];
/***************************************************************************/
#define EVEN 0 /* Even Page for 256byte/page */
#define ODD 1 /* Odd Page for 256byte/page */
/***************************************************************************
SmartMedia Redundant buffer data Controll Subroutine
***************************************************************************/
int Check$DataBlank(unsigned char *redundant)
{
char i;
for(i=0; i<REDTSIZE; i++)
if(*redundant++!=0xFF) return(ERROR);
return(SUCCESS);
}
/***************************************************************************/
int Check$FailBlock(unsigned char *redundant)
{
redundant+=REDT_BLOCK;
if(*redundant==0xFF) return(SUCCESS);
if(! *redundant) return(ERROR);
if(Bit$Count(*redundant)<7) return(ERROR);
return(SUCCESS);
}
/***************************************************************************/
int Check$DataStatus(unsigned char *redundant)
{
redundant+=REDT_DATA;
if(*redundant==0xFF) return(SUCCESS);
if(! *redundant) return(ERROR);
if(Bit$Count(*redundant)<5) return(ERROR);
return(SUCCESS);
}
/***************************************************************************/
int Load$LogBlockAddr(unsigned char *redundant)
{
unsigned short addr1,addr2;
addr1=(unsigned short)*(redundant+REDT_ADDR1H)*0x0100+(unsigned short)*(redundant+REDT_ADDR1L);
addr2=(unsigned short)*(redundant+REDT_ADDR2H)*0x0100+(unsigned short)*(redundant+REDT_ADDR2L);
if(addr1==addr2)
if((addr1 &0xF000)==0x1000)
{ Media.LogBlock=(addr1 &0x0FFF)/2; return(SUCCESS); }
if(Bit$CountWord(addr1^addr2)!=0x01) return(ERROR);
if((addr1 &0xF000)==0x1000)
if(! (Bit$CountWord(addr1) &0x01))
{ Media.LogBlock=(addr1 &0x0FFF)/2; return(SUCCESS); }
if((addr2 &0xF000)==0x1000)
if(! (Bit$CountWord(addr2) &0x01))
{ Media.LogBlock=(addr2 &0x0FFF)/2; return(SUCCESS); }
return(ERROR);
}
/***************************************************************************/
void Clr$RedundantData(unsigned char *redundant)
{
char i;
for(i=0; i<REDTSIZE; i++) *(redundant+i)=0xFF;
}
/***************************************************************************/
void Set$LogBlockAddr(unsigned char *redundant)
{
unsigned short addr;
*(redundant+REDT_BLOCK)=0xFF;
*(redundant+REDT_DATA) =0xFF;
addr=Media.LogBlock*2+0x1000;//add fixed pattern(D4=1)
if((Bit$CountWord(addr)%2)) addr++;//add even parity bit
*(redundant+REDT_ADDR1H)=*(redundant+REDT_ADDR2H)=(unsigned char)(addr/0x0100);
*(redundant+REDT_ADDR1L)=*(redundant+REDT_ADDR2L)=(unsigned char)addr;
}
/***************************************************************************/
void Set$FailBlock(unsigned char *redundant)
{
char i;
for(i=0; i<REDTSIZE; i++)
*redundant++=(unsigned char)((i==REDT_BLOCK)?0xF0:0xFF);
}
/***************************************************************************/
void Set$DataStaus(unsigned char *redundant)
{
redundant+=REDT_DATA;
*redundant=0x00;
}
/***************************************************************************
SmartMedia Function Command Subroutine
***************************************************************************/
void Ssfdc$Reset(void)
{
_Set$SsfdcRdCmd(RST_CHIP);
_Check$SsfdcBusy(BUSY_RESET);
_Set$SsfdcRdCmd(READ);
_Check$SsfdcBusy(BUSY_READ);
_Set$SsfdcRdStandby();
}
int Ssfdc$ReadCisSect(unsigned char *buf,unsigned char *redundant)
{
unsigned char zone,sector;
unsigned short block;
zone=Media.Zone; block=Media.PhyBlock; sector=Media.Sector;
Media.Zone=0;
Media.PhyBlock=CisArea.PhyBlock;
Media.Sector=CisArea.Sector;
if(Ssfdc$ReadSect(buf,redundant)) {
Media.Zone=zone; Media.PhyBlock=block; Media.Sector=sector;
return(ERROR);
}
Media.Zone=zone; Media.PhyBlock=block; Media.Sector=sector;
return(SUCCESS);
}
void Ssfdc$WriteRedtMode(void)
{
_Set$SsfdcRdCmd(RST_CHIP);
_Check$SsfdcBusy(BUSY_RESET);
_Set$SsfdcRdCmd(READ_REDT);
_Check$SsfdcBusy(BUSY_READ);
_Set$SsfdcRdStandby();
}
void Ssfdc$ReadID(unsigned char *buf)
{
_Set$SsfdcRdCmd(READ_ID);
_Set$SsfdcRdChip();
_Read$SsfdcByte(buf++);
_Read$SsfdcByte(buf++);
_Read$SsfdcByte(buf++);
_Read$SsfdcByte(buf);
_Set$SsfdcRdStandby();
}
int Ssfdc$ReadSect(unsigned char *buf,unsigned char *redundant)
{
_Set$SsfdcRdCmd(READ);
_Set$SsfdcRdAddr(EVEN);
if(_Check$SsfdcBusy(BUSY_READ))
{ _Reset$SsfdcErr(); return(ERROR); }
_Start$SsfdcRdHwECC();
_Read$SsfdcBuf(buf);
_Stop$SsfdcRdHwECC();
_ReadRedt$SsfdcBuf(redundant);
_Load$SsfdcRdHwECC(EVEN);
if(_Check$SsfdcBusy(BUSY_READ))
{ _Reset$SsfdcErr(); return(ERROR); }
if((Ssfdc.Attribute &MPS)==PS256) {
_Set$SsfdcRdCmd(READ);
_Set$SsfdcRdAddr(ODD);
if(_Check$SsfdcBusy(BUSY_READ))
{ _Reset$SsfdcErr(); return(ERROR); }
_Start$SsfdcRdHwECC();
_Read$SsfdcBuf(buf+0x0100);
_Stop$SsfdcRdHwECC();
_ReadRedt$SsfdcBuf(redundant+0x0008);
_Load$SsfdcRdHwECC(ODD);
if(_Check$SsfdcBusy(BUSY_READ))
{ _Reset$SsfdcErr(); return(ERROR); }
}
_Calc$ECCdata(buf);
_Set$SsfdcRdStandby();
return(SUCCESS);
}
int Ssfdc$WriteSect(unsigned char *buf,unsigned char *redundant)
{
_Calc$ECCdata(buf);
_Set$SsfdcWrCmd(WRDATA);
_Set$SsfdcWrAddr(EVEN);
_Start$SsfdcWrHwECC();
_Write$SsfdcBuf(buf);
_Load$SsfdcWrHwECC(EVEN);
_Set$ECCdata(EVEN,redundant);
_WriteRedt$SsfdcBuf(redundant);
_Set$SsfdcWrCmd(WRITE);
if(_Check$SsfdcBusy(BUSY_PROG))
{ _Reset$SsfdcErr(); return(ERROR); }
if((Ssfdc.Attribute &MPS)==PS256) {
_Set$SsfdcWrCmd(RDSTATUS);
if(_Check$SsfdcStatus()) { /* Patch */
_Set$SsfdcWrStandby(); /* for 256byte/page */
_Set$SsfdcRdStandby(); /* Next Status Check is ERROR */
return(SUCCESS);
}
_Set$SsfdcWrCmd(WRDATA);
_Set$SsfdcWrAddr(ODD);
_Start$SsfdcWrHwECC();
_Write$SsfdcBuf(buf+0x0100);
_Load$SsfdcWrHwECC(ODD);
_Set$ECCdata(ODD,redundant);
_WriteRedt$SsfdcBuf(redundant+0x0008);
_Set$SsfdcWrCmd(WRITE);
if(_Check$SsfdcBusy(BUSY_PROG))
{ _Reset$SsfdcErr(); return(ERROR); }
}
_Set$SsfdcWrStandby();
_Set$SsfdcRdStandby();
return(SUCCESS);
}
int Ssfdc$WriteSectForCopy(unsigned char *buf,unsigned char *redundant)
{
_Set$SsfdcWrCmd(WRDATA);
_Set$SsfdcWrAddr(EVEN);
_Write$SsfdcBuf(buf);
_WriteRedt$SsfdcBuf(redundant);
_Set$SsfdcWrCmd(WRITE);
if(_Check$SsfdcBusy(BUSY_PROG))
{ _Reset$SsfdcErr(); return(ERROR); }
if((Ssfdc.Attribute &MPS)==PS256) {
_Set$SsfdcWrCmd(RDSTATUS);
if(_Check$SsfdcStatus()) { /* Patch */
_Set$SsfdcWrStandby(); /* for 256byte/page */
_Set$SsfdcRdStandby(); /* Next Status Check is ERROR */
return(SUCCESS);
}
_Set$SsfdcWrCmd(WRDATA);
_Set$SsfdcWrAddr(ODD);
_Write$SsfdcBuf(buf+0x0100);
_WriteRedt$SsfdcBuf(redundant+0x0008);
_Set$SsfdcWrCmd(WRITE);
if(_Check$SsfdcBusy(BUSY_PROG))
{ _Reset$SsfdcErr(); return(ERROR); }
}
_Set$SsfdcWrStandby();
_Set$SsfdcRdStandby();
return(SUCCESS);
}
int Ssfdc$EraseBlock(void)
{
_Set$SsfdcWrCmd(ERASE1);
_Set$SsfdcWrBlock();
_Set$SsfdcWrCmd(ERASE2);
if(_Check$SsfdcBusy(BUSY_ERASE))
{ _Reset$SsfdcErr(); return(ERROR); }
_Set$SsfdcWrStandby();
_Set$SsfdcRdStandby();
return(SUCCESS);
}
int Ssfdc$ReadRedtData(unsigned char *redundant)
{
_Set$SsfdcRdCmd(READ_REDT);
_Set$SsfdcRdAddr(EVEN);
if(_Check$SsfdcBusy(BUSY_READ))
{ _Reset$SsfdcErr(); return(ERROR); }
_ReadRedt$SsfdcBuf(redundant);
if(_Check$SsfdcBusy(BUSY_READ))
{ _Reset$SsfdcErr(); return(ERROR); }
if((Ssfdc.Attribute &MPS)==PS256) {
_Set$SsfdcRdCmd(READ_REDT);
_Set$SsfdcRdAddr(ODD);
if(_Check$SsfdcBusy(BUSY_READ))
{ _Reset$SsfdcErr(); return(ERROR); }
_ReadRedt$SsfdcBuf(redundant+0x0008);
if(_Check$SsfdcBusy(BUSY_READ))
{ _Reset$SsfdcErr(); return(ERROR); }
}
_Set$SsfdcRdStandby();
return(SUCCESS);
}
int Ssfdc$WriteRedtData(unsigned char *redundant)
{
_Set$SsfdcWrCmd(WRDATA);
_Set$SsfdcWrAddr(EVEN);
_WriteRedt$SsfdcBuf(redundant);
_Set$SsfdcWrCmd(WRITE);
if(_Check$SsfdcBusy(BUSY_PROG))
{ _Reset$SsfdcErr(); return(ERROR); }
if((Ssfdc.Attribute &MPS)==PS256) {
_Set$SsfdcWrCmd(RDSTATUS);
if(_Check$SsfdcStatus()) {
_Set$SsfdcWrStandby();
_Set$SsfdcRdStandby();
return(SUCCESS);
}
_Set$SsfdcWrCmd(WRDATA);
_Set$SsfdcWrAddr(ODD);
_WriteRedt$SsfdcBuf(redundant+0x0008);
_Set$SsfdcWrCmd(WRITE);
if(_Check$SsfdcBusy(BUSY_PROG))
{ _Reset$SsfdcErr(); return(ERROR); }
}
_Set$SsfdcWrStandby();
_Set$SsfdcRdStandby();
return(SUCCESS);
}
int Ssfdc$CheckStatus(void)
{
_Set$SsfdcRdCmd(RDSTATUS);
if(_Check$SsfdcStatus())
{ _Set$SsfdcRdStandby(); return(ERROR); }
_Set$SsfdcRdStandby();
return(SUCCESS);
}
/***************************************************************************
NAND Memory (SmartMedia) Control Subroutine for Read Data
***************************************************************************/
static void _Set$SsfdcRdCmd(unsigned char cmd)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -