📄 smc_log.c
字号:
/*
**********************************************************************
* Micrium, Inc.
* 949 Crestview Circle
* Weston, FL 33327-1848
*
* uC/FS
*
* (c) Copyright 2001 - 2003, Micrium, Inc.
* All rights reserved.
*
***********************************************************************
----------------------------------------------------------------------
File : smc_log.c
Purpose : Generic logical sector read/write access module for SMC
----------------------------------------------------------------------
Known problems or limitations with current version
----------------------------------------------------------------------
None.
---------------------------END-OF-HEADER------------------------------
*/
/*********************************************************************
*
* #include Section
*
**********************************************************************
*/
#include "fs_port.h"
#include "fs_dev.h"
#include "fs_conf.h"
#if FS_USE_SMC_DRIVER
#include "smc.h"
/*********************************************************************
*
* #define macros
*
**********************************************************************
*/
#define Set_X_Bit(a,b) (a[(unsigned char)((b)/8)]|= _FS_SMC_BitData[(b)%8])
#define Clr_X_Bit(a,b) (a[(unsigned char)((b)/8)]&=~_FS_SMC_BitData[(b)%8])
#define Chk_X_Bit(a,b) (a[(unsigned char)((b)/8)] & _FS_SMC_BitData[(b)%8])
/*********************************************************************
*
* Local Variables
*
**********************************************************************
*/
static const char _FS_SMC_BitData[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 };
static unsigned int _FS_SMC_ErrCode[FS_SMC_MAXUNIT];
static unsigned char _FS_SMC_SectBuf[SECTSIZE];
static unsigned char _FS_SMC_WorkBuf[SECTSIZE];
static unsigned char _FS_SMC_Redundant[REDTSIZE];
static unsigned char _FS_SMC_WorkRedund[REDTSIZE];
static unsigned short _FS_SMC_Log2Phy[FS_SMC_MAXUNIT][2][MAX_LOGBLOCK];
static unsigned char _FS_SMC_Assign[FS_SMC_MAXUNIT][2][MAX_BLOCKNUM/8];
static unsigned short _FS_SMC_AssignStart[FS_SMC_MAXUNIT][2];
static unsigned short _FS_SMC_AssignZone[FS_SMC_MAXUNIT];
static unsigned short _FS_SMC_ReadBlock[FS_SMC_MAXUNIT];
static unsigned short _FS_SMC_WriteBlock[FS_SMC_MAXUNIT];
static unsigned int _FS_SMC_MediaChange[FS_SMC_MAXUNIT];
static unsigned int _FS_SMC_SectCopyMode[FS_SMC_MAXUNIT];
/*********************************************************************
*
* Local functions
*
**********************************************************************
*/
/*********************************************************************
*
* _FS_SMC_Bit_Count
*/
static char _FS_SMC_Bit_Count(unsigned char cdata)
{
char bitcount=0;
while(cdata) {
bitcount+=(cdata &0x01);
cdata /=2;
}
return(bitcount);
}
/*********************************************************************
*
* _FS_SMC_Bit_CountWord
*/
static char _FS_SMC_Bit_CountWord(unsigned short cdata)
{
char bitcount=0;
while(cdata) {
bitcount+=(cdata &0x01);
cdata /=2;
}
return(bitcount);
}
/*********************************************************************
*
* _FS_SMC_Chk_DataBlank
*/
static int _FS_SMC_Chk_DataBlank(unsigned char *redundant)
{
char i;
for(i=0; i<REDTSIZE; i++)
if(*redundant++!=0xFF) return(ERROR);
return(SUCCESS);
}
/*********************************************************************
*
* _FS_SMC_Chk_FailBlock
*/
static int _FS_SMC_Chk_FailBlock(unsigned char *redundant)
{
redundant+=REDT_BLOCK;
if(*redundant==0xFF) return(SUCCESS);
if(! *redundant) return(ERROR);
if(_FS_SMC_Bit_Count(*redundant)<7) return(ERROR);
return(SUCCESS);
}
/*********************************************************************
*
* _FS_SMC_Chk_CisBlock
*/
static int _FS_SMC_Chk_CisBlock(unsigned char *redundant)
{
if(! (*(redundant+REDT_ADDR1H)|*(redundant+REDT_ADDR1L)))
return(SUCCESS);
if(! (*(redundant+REDT_ADDR2H)|*(redundant+REDT_ADDR2L)))
return(SUCCESS);
return(ERROR);
}
/*********************************************************************
*
* _FS_SMC_Chk_DataStatus
*/
static int _FS_SMC_Chk_DataStatus(unsigned char *redundant)
{
redundant+=REDT_DATA;
if(*redundant==0xFF) return(SUCCESS);
if(! *redundant) return(ERROR);
if(_FS_SMC_Bit_Count(*redundant)<5) return(ERROR);
return(SUCCESS);
}
/*********************************************************************
*
* _FS_SMC_Load_LogBlockAddr
*/
static int _FS_SMC_Load_LogBlockAddr(FS_u32 id,unsigned char *redundant)
{
unsigned short addr1,addr2;
addr1=*(redundant+REDT_ADDR1H)*0x100+*(redundant+REDT_ADDR1L);
addr2=*(redundant+REDT_ADDR2H)*0x100+*(redundant+REDT_ADDR2L);
if(addr1==addr2)
if((addr1 &0xF000)==0x1000)
{ FS__SMC_cardparam[id].LogBlock=(addr1 &0x0FFF)/2; return(SUCCESS); }
if(_FS_SMC_Bit_CountWord(addr1^addr2)>1) return(ERROR);
if((addr1 &0xF000)==0x1000)
if(! (_FS_SMC_Bit_CountWord(addr1) &0x0001))
{ FS__SMC_cardparam[id].LogBlock=(addr1 &0x0FFF)/2; return(SUCCESS); }
if((addr2 &0xF000)==0x1000)
if(! (_FS_SMC_Bit_CountWord(addr2) &0x0001))
{ FS__SMC_cardparam[id].LogBlock=(addr2 &0x0FFF)/2; return(SUCCESS); }
return(ERROR);
}
/*********************************************************************
*
* _FS_SMC_Clr_RedundantData
*/
static void _FS_SMC_Clr_RedundantData(unsigned char *redundant)
{
char i;
for(i=0; i<REDTSIZE; i++) *(redundant+i)=0xFF;
}
/*********************************************************************
*
* _FS_SMC_Set_LogBlockAddr
*/
static void _FS_SMC_Set_LogBlockAddr(FS_u32 id,unsigned char *redundant)
{
unsigned short addr;
*(redundant+REDT_BLOCK)=0xFF;
*(redundant+REDT_DATA) =0xFF;
addr=FS__SMC_cardparam[id].LogBlock*2+0x1000;
if((_FS_SMC_Bit_CountWord(addr)%2)) addr++;
*(redundant+REDT_ADDR1H)=*(redundant+REDT_ADDR2H)=addr/0x100;
*(redundant+REDT_ADDR1L)=*(redundant+REDT_ADDR2L)=(unsigned char)addr;
}
/*********************************************************************
*
* _FS_SMC_Set_FailBlock
*/
static void _FS_SMC_Set_FailBlock(unsigned char *redundant)
{
char i;
for(i=0; i<REDTSIZE; i++)
*redundant++=((i==REDT_BLOCK)?0xF0:0xFF);
}
/*********************************************************************
*
* _FS_SMC_Set_DataStatus
*/
static void _FS_SMC_Set_DataStatus(unsigned char *redundant)
{
redundant+=REDT_DATA;
*redundant=0x00;
}
/*********************************************************************
*
* _FS_SMC_Init_Media
*/
static void _FS_SMC_Init_Media(FS_u32 id)
{
_FS_SMC_ErrCode[id]=NO_ERROR;
_FS_SMC_MediaChange[id]=(unsigned int) ERROR;
_FS_SMC_SectCopyMode[id]=COMPLETED;
FS__SMC_PHY_Cnt_Reset(id);
}
/*********************************************************************
*
* _FS_SMC_Chk_MediaPower
*/
static int _FS_SMC_Chk_MediaPower(FS_u32 id)
{
if(FS__SMC_PHY_Chk_CardStsChg(id)) _FS_SMC_MediaChange[id]=(unsigned int) ERROR;
if((! FS__SMC_PHY_Chk_CntPower(id))&&(! _FS_SMC_MediaChange[id])) return(SUCCESS);
if(FS__SMC_PHY_Chk_CardExist(id))
{ _FS_SMC_MediaChange[id]=(unsigned int) ERROR; _FS_SMC_ErrCode[id]=ERR_NoSmartMedia; return(ERROR); }
if(FS__SMC_PHY_Cnt_PowerOn(id))
{ _FS_SMC_MediaChange[id]=(unsigned int) ERROR; _FS_SMC_ErrCode[id]=ERR_NoSmartMedia; return(ERROR); }
FS__SMC_PHY_Reset(id);
return(SUCCESS);
}
/*********************************************************************
*
* _FS_SMC_Chk_MediaWP
*/
static int _FS_SMC_Chk_MediaWP(FS_u32 id)
{
if(FS__SMC_cardattrib[id].Attribute &MWP)
{ _FS_SMC_ErrCode[id]=ERR_WrtProtect; return(ERROR); }
return(SUCCESS);
}
/*********************************************************************
*
* _FS_SMC_MarkFail_PhyOneBlock
*/
static int _FS_SMC_MarkFail_PhyOneBlock(FS_u32 id)
{
unsigned char sect;
sect=FS__SMC_cardparam[id].Sector;
_FS_SMC_Set_FailBlock(_FS_SMC_WorkRedund);
FS__SMC_PHY_WriteRedtMode(id);
for(FS__SMC_cardparam[id].Sector=0; FS__SMC_cardparam[id].Sector<FS__SMC_cardattrib[id].MaxSectors; FS__SMC_cardparam[id].Sector++)
if(FS__SMC_PHY_WriteRedtData(id,_FS_SMC_WorkRedund)) {
FS__SMC_PHY_Reset(id);
FS__SMC_cardparam[id].Sector=sect;
_FS_SMC_ErrCode[id]=ERR_HwError;
return(ERROR);
} /* NO Status Check */
FS__SMC_PHY_Reset(id);
FS__SMC_cardparam[id].Sector=sect;
return(SUCCESS);
}
/*********************************************************************
*
* _FS_SMC_Set_PhyFmtValue
*/
static int _FS_SMC_Set_PhyFmtValue(FS_u32 id)
{
unsigned short idcode;
FS__SMC_PHY_ReadID(id,&idcode);
if(FS__SMC_PHY_Set_Model(id,(unsigned char)idcode))
return(ERROR);
if(FS__SMC_PHY_Chk_WP(id))
FS__SMC_cardattrib[id].Attribute|=WP;
return(SUCCESS);
}
/*********************************************************************
*
* _FS_SMC_Search_CIS
*/
static int _FS_SMC_Search_CIS(FS_u32 id,unsigned short *pcis)
{
FS__SMC_cardparam[id].Zone=0; FS__SMC_cardparam[id].Sector=0;
for(FS__SMC_cardparam[id].PhyBlock=0; FS__SMC_cardparam[id].PhyBlock<(FS__SMC_cardattrib[id].MaxBlocks-FS__SMC_cardattrib[id].MaxLogBlocks-1); FS__SMC_cardparam[id].PhyBlock++) {
if(FS__SMC_PHY_ReadRedtData(id,_FS_SMC_Redundant))
{ FS__SMC_PHY_Reset(id); return(ERROR); }
if(! _FS_SMC_Chk_FailBlock(_FS_SMC_Redundant)) {
if(_FS_SMC_Chk_CisBlock(_FS_SMC_Redundant))
{ FS__SMC_PHY_Reset(id); return(ERROR); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -