📄 smt_fat.c
字号:
/********************************************************************************/
/* */
/* Copyright (C) SEIKO EPSON CORP. 2000 */
/* */
/* File name : smt_fat.c */
/* This is smart media FAT file system library */
/* */
/* Revision history */
/* 2000.04.07 H.Ogura start */
/* 2001.09.26 A.Saito Modify FAT33 Function/Global */
/* variable name. */
/* Modify Function smtInitDev, */
/* smtRdSect,smtWtSect */
/* 2002.07.25 A.Saito Commend out callin smtChkRdDat() in smtWtSect() */
/* 2002.08.01 A.Saito Modify smtInitDev() */
/* 2002.09.04 A.Saito Append functions smtOpenLib(), smtCloseLib(), */
/* smtGetCacheRAMSize(), smtCacheRAMEntry() */
/* 2003.02.13 A.Saito Modify smtWtSect(), smtVefiryCheck() */
/* 2003.02.24 A.Saito Modify smtWtSect(), smtWtEvac() */
/* 2003.03.29 A.Saito Append smtPageReadWrap() */
/* Modify smtPageRead calling */
/* Modify smtWtSect(),smtChkDupli(),smtRdSect(), */
/* smtDupliSect() */
/* Modify Logical Block addressSetting to */
/* smtSetProlDat() */
/* 2003.03.24 A.Saito Add function "smtBlockCopy() */
/* Modify how to use R/W buffer */
/* 2003.06.05 A.Saito Modify Comment */
/* Remove prototype declaration of functions */
/* 2004.03.01 David.ji Add mcp support, add function point *pSmt_xxx */
/* add global variable bSmtType */
/********************************************************************************/
/********************************************************************************/
/* The tab size of this file is 4. */
/********************************************************************************/
#include <stdlib.h>
#include "smt.h"
#include "mcp_ctl.h"
#include "adv_ctl.h"
#include "smt_dat.h"
/********************************************************/
/* PROTOTYPE */
/********************************************************/
/********************************************************/
/* GLOBAL */
/********************************************************/
const struct SMT_DEV_INFO *smt_pDevInf; // Device information pointer
struct SMT_BLK_ATBL smtBlkTbl[2]; // Block allocation table
struct SMT_ERR_INFO smtErrInf; // Error information structure
union SMT_RW_BUFF smtRead; // Read buffer
union SMT_RW_BUFF smtWrite; // Write buffer
// Temporary buffer for veriry check
unsigned char smtVerifyBuff[SMT_DAT_MAX];
unsigned long smtBadBlkCnt; // Bad block counter
union SMT_PROLIX_BUFF smtProlBuff;
unsigned short ulTranBuf[SMT_S_DATA/2];
/*-----------------------------------------------------*/
/* point to smt_ctl function */
/*-----------------------------------------------------*/
unsigned char bSmtType;
int (* pSmt_EraseChk)(void );
int (* pSmt_MediaReset)(void );
int (* pSmt_BlockErase)( unsigned long );
int (* pSmt_IdRead)(unsigned char* , unsigned char* );
int (* pSmt_PageRead)(unsigned char, unsigned long, unsigned long, char *);
int (* pSmt_PageProgram)(unsigned long, unsigned long, const char *, unsigned char);
int (* pSmt_ProlixProgram)(unsigned long, unsigned long, const char *);
int (* pSmt_ReadyCheck)(unsigned long);
int (* pSmt_StatusRead)(unsigned char *);
char (* pSmt_CardDetect)(void);
char (* pSmt_WriteProtect)(void);
/************************************************************************
* smtChgPgNum
* Type : unsigned long
* Ret val : Page address
* Argument : unsigned long ulZone ... Zone address
* unsigned long ulPhyBlk ... Physics block address
* unsigned long ulPhySct ... Physics sector address
* Function : This function makes physics page address.
************************************************************************/
unsigned long smtChgPgNum(
unsigned long ulZone, // Zone address
unsigned long ulPhyBlk, // Physics block address
unsigned long ulPhySct // Physics sector address
)
{
unsigned long ulShift; // Bit shift size
unsigned long ulPage; // Page address
ulShift = 0; // A page address is made.
while(SMT_M_MASK(ulShift) < smt_pDevInf->pSizeInf->uwBlkSize)
{
ulShift++;
}
ulPhyBlk += ulZone * SMT_ZON_MAX;
ulPage = ulPhySct;
ulPage |= (ulPhyBlk << ulShift);
return(ulPage);
}
/************************************************************************
* smtChgLogNum
* Type : unsigned long
* Ret val : Logic block address
* Argument : unsigned char bHiBlk ... "Block Address Area" (High)
* unsigned char bLoBlk ... "Block Address Area" (Low)
* Function : This function makes a logic block address from
* "Block Address Area".
************************************************************************/
unsigned long smtChgLogNum(
unsigned char bHiBlk, // The high byte of the address.
unsigned char bLoBlk // The low byte of the address.
)
{
return((((bHiBlk << 8) | bLoBlk) >> 1) & 0x7FF); // A logic block address is made.
}
/************************************************************************
* smtChgPhyNum
* Type : unsigned long
* Ret val : Physical address
* 0xFFF = There is no appropriate block.
* Argument : unsigned long ulLogBlk ... Logic block address
* Function : This function makes physics block address.
************************************************************************/
unsigned long smtChgPhyNum(
unsigned long ulLogBlk
)
{
int iLoop1, iLoop2; // Loop counter
unsigned long ulZone; // Zone address
unsigned long ulPhyBlk; // Physics block address
unsigned long ulPage; // Page address
unsigned char bHiBlk; // The high byte of the address.
unsigned char bLoBlk; // The low byte of the address.
ulZone = ulLogBlk / SMT_LZN_MAX; // Physics block address is acquired from
if(!ulZone) // - block allocation table.
{
ulPhyBlk = (unsigned long)smtBlkTbl[0].bBlkCnvInf[ulLogBlk % SMT_LZN_MAX];
}
else
{
if(ulZone != smtBlkTbl[1].ulZoneNum)
{
smtChgBlkTbl(ulZone);
}
ulPhyBlk = (unsigned long)smtBlkTbl[1].bBlkCnvInf[ulLogBlk % SMT_LZN_MAX];
}
iLoop1 = 0; // Data are actually read, and the upper bit
while(iLoop1 < 4) // - of physics block address is complemented.
{
ulPage = ulPhyBlk + (iLoop1 << 8);
ulPage = smtChgPgNum(ulZone, ulPage, 0x00);
if(pSmt_PageRead(SMT_C_DREAD_3, 0x00, ulPage, smtRead.stBuff.bProlix) != SMT_E_SUCCESS)
{
smtErrInf.iSmtErr = SMT_E_PAGREAD;
return(SMT_E_FAILURE);
}
iLoop2 = 0;
while(iLoop2 < 2)
{
if(!iLoop2)
{
bHiBlk = smtRead.stDatBuff.bBlkAdr1[0];
bLoBlk = smtRead.stDatBuff.bBlkAdr1[1];
}
else
{
bHiBlk = smtRead.stDatBuff.bBlkAdr2[0];
bLoBlk = smtRead.stDatBuff.bBlkAdr2[1];
}
if(smtChkPrty((bHiBlk << 8) | bLoBlk) == SMT_E_SUCCESS)
{
if(smtChgLogNum(bHiBlk, bLoBlk) == (ulLogBlk % SMT_LZN_MAX))
{
ulPhyBlk |= (iLoop1 << 8);
return(ulPhyBlk);
}
}
iLoop2++;
}
iLoop1++;
}
ulPhyBlk |= 0x0F00; // There is no appropriate block. (0x0FFF)
return(ulPhyBlk);
}
/************************************************************************
* smtChgBlkTbl
* Type : int
* Ret val : Error code
* Argument : unsigned long ulZone ... Zone address
* Function : This function changes block allocation table in
* another zone.
************************************************************************/
int smtChgBlkTbl(
unsigned long ulZone // Zone address
)
{
unsigned long ulPhyBlk; // Physics block address
unsigned long ulPhyBlkMax; // Max value of physics block address.
unsigned char bCheckBit; // Check bit information
smtClrBlkTbl(ulZone); // Block allocation table is changed in
if(ulZone != smtBlkTbl[1].ulZoneNum) // - the specified zone.
{
if(smt_pDevInf->pSizeInf->ulNumBlk < SMT_ZON_MAX)
{
ulPhyBlkMax = smt_pDevInf->pSizeInf->ulNumBlk;
}
else
{
ulPhyBlkMax = SMT_ZON_MAX;
}
bCheckBit = 0x01;
ulPhyBlk = 0;
while(ulPhyBlk < ulPhyBlkMax)
{
if(smtCrtBlkTbl(ulZone, ulPhyBlk, bCheckBit) != SMT_E_SUCCESS)
{
return(SMT_E_FAILURE);
}
bCheckBit <<= 1;
if(!bCheckBit)
{
bCheckBit = 0x01;
}
ulPhyBlk++;
}
}
return(SMT_E_SUCCESS);
}
/************************************************************************
* smtChgBlkNum
* Type : unsigned long
* Ret val : "Block Address Area" store data
* Argument : unsigned long ulLogBlk ... Logic block address
* Function : This function, a logic block address is changed into
* the "Block Address Area" data.
************************************************************************/
unsigned long smtChgBlkNum(
unsigned long ulLogBlk // Logic block address
)
{
int iLoop; // Loop counter
unsigned long ulLbaData; // Block address area data
unsigned char bParity; // Parity value
ulLogBlk %= SMT_LZN_MAX; // A logic block address is changed into
ulLbaData = 0x1000 | (ulLogBlk << 1); // - the "Block Address Area" data.
bParity = 0;
iLoop = 0;
while(iLoop < 16)
{
if(ulLogBlk & SMT_M_MASK(iLoop))
{
bParity++;
}
iLoop++;
}
if(!(bParity % 2))
{
ulLbaData++;
}
return(ulLbaData);
}
/************************************************************************
* smtInitDev
* Type : int
* Ret val : Error code
* SMT_SUCCESS ( 0) ... Successful
* SMT_FAILURE (-1) ... Failure
* Argument : FatFcs_t pstFcs ... File control structure
* FatFile_t pfpFile ... FAT File structure
* FatFile_t pfpFp ... Fat File structure array
* FatSecBuf_t pstSecBuf ... Sector Buffer structure
* unsigned char bMaxFiles... Open file max
* unsigned char bMaxBuffers... Open buffer max
* Function : This function does the initialization of device
* information.
************************************************************************/
int smtInitDev(
FatInitParams_t *pstParams
)
{
int iRetVal; // Return value
unsigned char bMaker; // Maker code
unsigned char bDevice; // Device code
unsigned long ulCisBlk; // CIS block address
long lCacheSize; // Cache area size
//////////////////
/// INITIALIZE ///
//////////////////
iRetVal = SMT_E_SUCCESS; // Return value is initialized.
smtBadBlkCnt = 0; // Global memory is initialized.
smtErrInf.bDrvNum = SMT_DRVNUM;
smtErrInf.iFatErr = SMT_E_SUCCESS;
smtErrInf.iSmtErr = SMT_E_SUCCESS;
smtErrInf.iSctNum = SMT_SCTINI;
////////////////////////////////////////
/// ENTRY SmartMedia Ctl FUNCTION ///
////////////////////////////////////////
switch(bSmtType){
case SMT_T_MCP:
pSmt_IdRead = mcpIdRead;
pSmt_EraseChk = mcpEraseChk;
pSmt_CardDetect = mcpCardDetect;
pSmt_MediaReset = mcpMediaReset;
pSmt_BlockErase = mcpBlockErase;
pSmt_PageRead = mcpPageRead;
pSmt_PageProgram = mcpPageProgram;
pSmt_ProlixProgram = mcpProlixProgram;
pSmt_WriteProtect = mcpWriteProtect;
break;
case SMT_T_CARD:
pSmt_IdRead = smtIdRead;
pSmt_EraseChk = smtEraseChk;
pSmt_CardDetect = smtCardDetect;
pSmt_MediaReset = smtMediaReset;
pSmt_BlockErase = smtBlockErase;
pSmt_PageRead = smtPageRead;
pSmt_PageProgram = smtPageProgram;
pSmt_ProlixProgram = smtProlixProgram;
pSmt_WriteProtect = smtWriteProtect;
break;
case SMT_T_ADV:
pSmt_IdRead = advIdRead;
pSmt_EraseChk = advEraseChk;
pSmt_CardDetect = advCardDetect;
pSmt_MediaReset = advMediaReset;
pSmt_BlockErase = advBlockErase;
pSmt_PageRead = advPageRead;
pSmt_PageProgram = advPageProgram;
pSmt_ProlixProgram = advProlixProgram;
pSmt_WriteProtect = advWriteProtect;
}
////////////////////////////////////////
/// ENTRY SECTOR READ/WRITE FUNCTION ///
////////////////////////////////////////
fatReadEntry(smtRdSect);
fatWriteEntry(smtWtSect);
///////////////////////////
/// CARD DETECT CHECK //
///////////////////////////
if(pSmt_CardDetect() == SMT_FALSE) // It has a card detection check.
{
smtErrInf.iSmtErr = SMT_E_NOTDTCT;
return(SMT_E_FAILURE);
}
////////////////////////
/// MEDIA RESET //
////////////////////////
if(pSmt_MediaReset() != SMT_E_SUCCESS) // A smart media is reset.
{
smtErrInf.iSmtErr = SMT_E_MDRESET;
return(SMT_E_FAILURE);
}
//////////////////////////////
/// GET DEVICE INFORMATION ///
//////////////////////////////
bMaker = bDevice = 0x00; // A media ID and device information are
pSmt_IdRead(&bMaker, &bDevice); // - acquired.
if((bMaker == 0x00)||(bDevice == 0x00))
{
smtErrInf.iSmtErr = SMT_E_MIDREAD;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -