📄 sm_normal.c
字号:
}
dwCounter--;
}
return ENCODE_COMPLETION;
}
#endif
SWORD ECC_Check(void)
{
register MCARD * sMcard = (MCARD *)MCARD_BASE;
bECCCode[0] = ((sMcard->McSmEcc1 >> 16) & 0xff);
bECCCode[1] = ((sMcard->McSmEcc1 >> 8) & 0xff);
bECCCode[2] = (sMcard->McSmEcc1 & 0xff);
if((bRedtData[13] != bECCCode[2]) ||(bRedtData[14] != bECCCode[1]) ||(bRedtData[15] != bECCCode[0]))
{
MP_DEBUG("ECC-Field 1 Error !!");
return FAIL;
}
bECCCode[0] = ((sMcard->McSmEcc2 >> 16) & 0xff);
bECCCode[1] = ((sMcard->McSmEcc2 >> 8) & 0xff);
bECCCode[2] = (sMcard->McSmEcc2 & 0xff);
if((bRedtData[8] != bECCCode[2]) ||(bRedtData[9] != bECCCode[1]) ||(bRedtData[10] != bECCCode[0]))
{
MP_DEBUG("ECC-Field 2 Error !!");
return FAIL;
}
return PASS;
}
void GpioValueSetting(BYTE value,BYTE num )
{
GPIO * sGpio = (GPIO *) GPIO_BASE;
DWORD dwCfg;
BYTE m,n;
dwCfg = 0;
m = num /16;
n = num %16;
dwCfg =((1<<(16+n))|(1<<n));
sGpio->Fgpcfg[m] &= ~dwCfg;
sGpio->Fgpdat[m] |=(dwCfg & 0xffff0000);
if(value)
sGpio->Fgpdat[m] |=(dwCfg & 0x0000ffff);
else
sGpio->Fgpdat[m] &=~(dwCfg & 0x0000ffff);
}
BOOL GetGpioValue(BYTE num )
{
GPIO * sGpio = (GPIO *) GPIO_BASE;
DWORD dwCfg;
BYTE m,n;
dwCfg = 0;
m = num /16;
n = num %16;
dwCfg =((1<<(16+n))|(1<<n));
sGpio->Fgpcfg[m] &= ~dwCfg;
sGpio->Fgpdat[m] &= ~(dwCfg & 0xffff0000);
return (sGpio->Fgpdat[m] &(dwCfg & 0x0000ffff) >> n);
}
void SmInit(ST_MCARD_DEV * sDev, BYTE bType)
{
switch (bType)
{
case NAND:
sDev->pbDescriptor = bDescriptor[0];
sDev->dwLunNum = NAND_LUN_NUM;
break;
#if SM_ENABLE
case SM:
sDev->pbDescriptor = bDescriptor[1];
sDev->dwLunNum = SM_LUN_NUM;
break;
#endif
case XD:
sDev->pbDescriptor = bDescriptor[1];
sDev->dwLunNum = XD_LUN_NUM;
break;
}
sDev->wMcardType = bType;
sDev->Flag.Installed = 1;
sDev->CommandProcess = CommandProcess;
}
/*
// Definition of local functions
*/
static void CommandProcess(void *pMcardDev)
{
ST_MCARD_MAIL *sMcardRMail;
register ST_MCARD_DEV *pDev = ((ST_MCARD_DEV *) pMcardDev);
McardSetClock(SM_CLOCK);
sMcardRMail = pDev->sMcardRMail;
if (pDev->wMcardType == NAND)
{
Select(INITIAL_NAND);
}
#if SM_ENABLE
else if (pDev->wMcardType == SM)
{
Select(INITIAL_SM);
}
#endif
else if (pDev->wMcardType == XD)
{
Select(INITIAL_XD);
}
else
{
return;
}
switch (sMcardRMail->wCmd)
{
case INIT_CARD_CMD:
if (pDev->wMcardType == SM)
pDev->Flag.Detected = Ui_CheckSmPlugIn();
else if (pDev->wMcardType == XD)
pDev->Flag.Detected = Ui_CheckXdPlugIn();
else
pDev->Flag.Detected = 1; //needcheck
//if (pDev->Flag.Detected)
if(1)
{
//card in
McardIODelay(0x500);
pDev->Flag.Detected = 1;
if (((pDev->swStatus = Identify(&pDev->dwCapacity))))
{
//pDev->Flag.Detected = 0;
pDev->Flag.Present = 0;
pDev->dwCapacity = 0;
pDev->wSectorSize = 0;
if (pDev->wMcardType != NAND)
{
McardSetCurLun(pDev->dwLunNum, NULL_DEVICE);
}
}
else
{
pDev->wSectorSize = MCARD_SECTOR_SIZE;
if (pDev->swStatus = Log2PhyTabInit())
{
MP_DEBUG("Log2PhyTabInit fail");
pDev->Flag.Present = 0;
pDev->dwCapacity = 0;
pDev->wSectorSize = 0;
if (pDev->wMcardType != NAND)
{
McardSetCurLun(pDev->dwLunNum, NULL_DEVICE);
}
}
else
{
MP_DEBUG("Log2PhyTabInit pass");
pDev->wRenewCounter++;
pDev->Flag.ReadOnly = GetWPFlag();
pDev->Flag.Present = 1;
if (pDev->wMcardType != NAND)
{
McardSetCurLun(pDev->dwLunNum, pDev->wMcardType);
}
//EventSet(UI_EVENT, EVENT_CARD_INIT);
}
}
}
else
{
//card out
#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600)
#else
GpioValueSetting(1,XD_WP);
GpioValueSetting(1,XD_VCC);
McardIODelay(10);
GpioValueSetting(0,XD_WP);
#endif
pDev->Flag.Detected = 0;
pDev->Flag.Present = 0;
pDev->Flag.ReadOnly = 0;
pDev->Flag.PipeEnable = 0;
pDev->swStatus = 0;
pDev->dwCapacity = 0;
pDev->wSectorSize = 0;
McardSetCurLun(pDev->dwLunNum, NULL_DEVICE);
//EventSet(UI_EVENT, EVENT_CARD_INIT);
}
break;
case REMOVE_CARD_CMD: //Athena 03.11.2006 seperate card in & out
//card out
pDev->Flag.Detected = 0;
pDev->Flag.Present = 0;
pDev->Flag.ReadOnly = 0;
pDev->Flag.PipeEnable = 0;
pDev->swStatus = 0;
pDev->dwCapacity = 0;
pDev->wSectorSize = 0;
McardSetCurLun(pDev->dwLunNum, NULL_DEVICE);
if (pDev->wMcardType == XD)
GpioValueSetting(0,XD_WP);
#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600)
#else
GpioValueSetting(1,XD_VCC);
#endif
PreSMType = 0;
break;
case READ_PAGE_CMD:
pDev->swStatus =
FlatRead(sMcardRMail->dwBuffer, sMcardRMail->dwBlockCount, sMcardRMail->dwBlockAddr);
break;
case WRITE_PAGE_CMD:
pDev->swStatus =
FlatWrite(sMcardRMail->dwBuffer, sMcardRMail->dwBlockCount, sMcardRMail->dwBlockAddr);
break;
case FORMAT_CMD:
pDev->swStatus = Format();
break;
default:
MP_DEBUG("-E- INVALID CMD");
break;
}
DeSelect();
// PreSMType = pDev->wMcardType;
}
static SWORD Log2PhyTabInit(void)
{
ST_MEDIA_MEAT *sMediaMeat;
DWORD dwCurAddr;
SWORD swRetValue;
WORD wLogBlockAddr, wZoneNum, wReassignState, i, wCurPhyBlock, wLogBlock, wPhyBlock, wTemp;
WORD *pLog2PhyTable;
BYTE *pReAssignTable;
sMediaMeat = (ST_MEDIA_MEAT *) sInfo.sMediaMeat[sInfo.bCurMode];
pLog2PhyTable = (WORD *) sInfo.wLog2PhyTable[sInfo.bCurMode];
pReAssignTable = (BYTE *) sInfo.bReAssignTable[sInfo.bCurMode];
BYTE *bTempBuffer = (BYTE *)mem_malloc(0x40000);
for (wZoneNum = 0; wZoneNum < sMediaMeat->bMaxZone; wZoneNum++)
{
wReassignState = 0;
for (i = 0; i < MAX_BLOCK; i++)
{
pLog2PhyTable[(wZoneNum * MAX_BLOCK) + i] = 0xffff;
bTempBuffer[(i << 1)] = 0xff;
bTempBuffer[(i << 1) + 1] = 0xff;
}
dwCurAddr = wZoneNum * sMediaMeat->wMaxBlock * sMediaMeat->wMaxSector;
for (wCurPhyBlock = 0; wCurPhyBlock < sMediaMeat->wMaxBlock; wCurPhyBlock++)
{
if ((swRetValue = ReadRedtData(dwCurAddr)))
{
mem_free(bTempBuffer);
MP_DEBUG1("-E- ReadRedtData FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
dwCurAddr += sMediaMeat->wMaxSector;
// Check block status,
// if LogBlockAddr == 0x0000, bad block or CIS block
// if 0 < LogBlockAddr < pMediaMeat->wMaxLogBlock, USED block
// else are free blocks
if (CheckBlockStatus())
{
if (bRedtData[5] == 0xf0)
{
bTempBuffer[wReassignState * 2] = (BYTE) (wCurPhyBlock >> 8);
bTempBuffer[wReassignState * 2 + 1] = (BYTE) wCurPhyBlock;
wReassignState++;
}
MP_DEBUG1("%d is bad block",(dwCurAddr/32));
continue;
}
if (LoadLogBlockAddr(&wLogBlockAddr))
{
continue;
}
if (wLogBlockAddr >= sMediaMeat->wMaxLogBlock)
{
bTempBuffer[wReassignState * 2] = (BYTE) (wCurPhyBlock >> 8);
bTempBuffer[wReassignState * 2 + 1] = (BYTE) wCurPhyBlock;
wReassignState++;
}
else
{
// If SmXdLog2PhyTable is 0xffff, fill curphyblock
// else compare the blockaddr to last page ,if the same fill curphyblock and access the original block as free block
if (pLog2PhyTable[wZoneNum * MAX_BLOCK + wLogBlockAddr] == 0xffff)
{
pLog2PhyTable[wZoneNum * MAX_BLOCK + wLogBlockAddr] = wCurPhyBlock;
}
else
{
wLogBlock = wLogBlockAddr;
if ((swRetValue = ReadRedtData(dwCurAddr - 1)))
{
mem_free(bTempBuffer);
MP_DEBUG1("-E- ReadRedtData FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
if (!LoadLogBlockAddr(&wLogBlockAddr))
{
if (wLogBlockAddr == wLogBlock)
{
wPhyBlock = pLog2PhyTable[wZoneNum * MAX_BLOCK + wLogBlockAddr];
pLog2PhyTable[wZoneNum * MAX_BLOCK + wLogBlockAddr] = wCurPhyBlock;
bTempBuffer[wReassignState * 2] = (BYTE) (wPhyBlock >> 8);
bTempBuffer[wReassignState * 2 + 1] = (BYTE) wPhyBlock;
wReassignState++;
}
else
{
// bTempBuffer[wReassignState * 2] = (BYTE) (wPhyBlock >> 8);
// bTempBuffer[wReassignState * 2 + 1] = (BYTE) wPhyBlock;
bTempBuffer[wReassignState * 2] = (BYTE) (wCurPhyBlock >> 8);
bTempBuffer[wReassignState * 2 + 1] = (BYTE) wCurPhyBlock;
wReassignState++;
}
}
else
{
// bTempBuffer[wReassignState * 2] = (BYTE) (wPhyBlock >> 8);
// bTempBuffer[wReassignState * 2 + 1] = (BYTE) wPhyBlock;
bTempBuffer[wReassignState * 2] = (BYTE) (wCurPhyBlock >> 8);
bTempBuffer[wReassignState * 2 + 1] = (BYTE) wCurPhyBlock;
wReassignState++;
}
}
}
}
for (i = 0; i < sMediaMeat->wMaxLogBlock; i++)
{
if ((pLog2PhyTable[wZoneNum * MAX_BLOCK + i] == 0xffff) && (wReassignState != 0))
{
wTemp = bTempBuffer[wReassignState * 2 - 2];
wTemp = (wTemp << 8) + bTempBuffer[wReassignState * 2 - 1];
pLog2PhyTable[wZoneNum * MAX_BLOCK + i] = wTemp;
wReassignState--;
}
}
for (i = 0; i < 16; i++)
{
if (wReassignState != 0)
{
wTemp = bTempBuffer[wReassignState * 2 - 2];
wTemp = (wTemp << 8) + bTempBuffer[wReassignState * 2 - 1];
pLog2PhyTable[wZoneNum * MAX_BLOCK + MAX_LOGBLOCK + i] = wTemp;
wReassignState--;
}
}
// Check if more than 24 bad block
pReAssignTable[wZoneNum] = 0;
if (GetEmptyBlock(wZoneNum) == 0xffff)
{
mem_free(bTempBuffer);
MP_DEBUG("-E- Get Empty Block Address FAIL");
return FAIL;
}
}
mem_free(bTempBuffer);
return PASS;
}
static BOOL CheckBlockStatus(void)
{
if (bRedtData[5] == 0xFF)
{
return USABLE_BLOCK;
}
else
{
return UNUSABLE_BLOCK;
}
if (BitCountByte(bRedtData[5]) < 7)
{
return UNUSABLE_BLOCK;
}
return USABLE_BLOCK;
}
static BYTE BitCountByte(BYTE bByteData)
{
BYTE bBitsCount = 0;
while (bByteData)
{
bBitsCount += (bByteData & 0x01);
bByteData >>= 1;
}
return bBitsCount;
}
static BOOL LoadLogBlockAddr(WORD * pwLogBlockAddr)
{
WORD wAddr;
if((MLC == TRUE) && (sInfo.bCurMode == INITIAL_NAND))
wAddr = (bRedtData[0] << 8) + bRedtData[1];
else
wAddr = (bRedtData[6] << 8) + bRedtData[7];
if (wAddr == 0x0)
{
// bad block or CIS block
return UNUSABLE_BLOCK;
}
*pwLogBlockAddr = ((wAddr & 0x07ff) >> 1);
return USABLE_BLOCK;
}
static WORD GetEmptyBlock(WORD wZoneNum)
{
WORD wBlankAddr;
WORD *pwLog2PhyTable;
BYTE *pReAssignTable;
pReAssignTable = (BYTE *) sInfo.bReAssignTable[sInfo.bCurMode];
pwLog2PhyTable = (WORD *) sInfo.wLog2PhyTable[sInfo.bCurMode];
wBlankAddr = pwLog2PhyTable[wZoneNum * MAX_BLOCK + pReAssignTable[wZoneNum] + MAX_LOGBLOCK];
return (wBlankAddr);
}
static SWORD ReadRedtData(DWORD dwSectorAddr)
{
register MCARD *sMcard;
SWORD swRetValue;
WORD wNum;
BYTE bTempMemID, *pbBuffer;
sMcard = (MCARD *) (MCARD_BASE);
SetControl();
if(sInfo.bCurMode == INITIAL_NAND){
if((MultiDieFlag & MultiDie) == MultiDie){
if(dwSectorAddr < (MaxPhyPage/2)){
GpioValueSetting(0,NAND1_CE);
}else{
dwSectorAddr = dwSectorAddr - (MaxPhyPage/2);
GpioValueSetting(0,NAND2_CE);
}
}
else{
GpioValueSetting(0,NAND1_CE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -