📄 sm.c
字号:
return FAIL;
}
}
mem_free(bTempBuffer);
return PASS;
}
static BOOL CheckBlockStatus(void)
{
if (bRedtData[0] == 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(DWORD dwCurZone,WORD wZoneNum,WORD *pwLog2PhyTable)
{
WORD wBlankAddr;
// WORD *pwLog2PhyTable;
BYTE *pReAssignTable;
pReAssignTable = (BYTE *) sInfo.bReAssignTable[sInfo.bCurMode];
// pwLog2PhyTable = (WORD *) sInfo.wLog2PhyTable[sInfo.bCurMode];
if(sInfo.bCurMode == INITIAL_NAND)
wBlankAddr = pwLog2PhyTable[wZoneNum * MAX_BLOCK + pReAssignTable[wZoneNum] + MAX_LOGBLOCK];
else if(sInfo.bCurMode == INITIAL_XD)
wBlankAddr = pwLog2PhyTable[dwCurZone * 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);
}
}
else if(sInfo.bCurMode == INITIAL_XD){
GpioValueSetting(0,XD_CE);
}
WaitReady();
// McardIODelay(5);
if (((sInfo.bCurMode == INITIAL_NAND) && (sInfo.sMediaMeat[sInfo.bCurMode]->wMaxSector == 0x100)) ||
(sInfo.bCurMode == INITIAL_NAND) && (sInfo.sMediaMeat[sInfo.bCurMode]->wMaxSector == 0x200))
{
bTempMemID = OsTempMemAllocate();
pbBuffer = (BYTE *) GetOsTempMemory(bTempMemID);
for (wNum = 0; wNum < 512; wNum++)
{
*(pbBuffer + wNum) = 0;
}
SetCommand(READ_PAGE1_CMD);
SetAddress(dwSectorAddr, 0);
SetCommand(READ_PAGE1_CMD_2CYC);
if ((swRetValue = WaitReady()))
{
MP_DEBUG1("-E- Read Command FAIL (swRetValue: %d)", swRetValue);
OsTempMemRelease(bTempMemID);
return swRetValue;
}
if ((swRetValue = ReadSector((DWORD) pbBuffer, MCARD_SECTOR_SIZE)))
{
MP_DEBUG1("-E- DMA Read FAIL (swRetValue: %d)", swRetValue);
OsTempMemRelease(bTempMemID);
return swRetValue;
}
OsTempMemRelease(bTempMemID);
for (wNum = 0; wNum < 16; wNum++)
{
bRedtData[wNum] = sMcard->McSmDat;
}
}
else
{
SetCommand(READ_REDUNDANT_CMD);
SetAddress(dwSectorAddr, 0);
if ((swRetValue = WaitReady()))
{
return swRetValue;
}
for (wNum = 0; wNum < 16; wNum++)
{
bRedtData[wNum] = sMcard->McSmDat;
}
}
sMcard->McSmC = 0x0;
GpioValueSetting(1,NAND1_CE);
GpioValueSetting(1,NAND2_CE);
GpioValueSetting(1,XD_CE);
return PASS;
}
static DWORD GetSameBlock(DWORD dwLogAddr, DWORD dwSectorCount)
{
DWORD dwPage, dwCount;
ST_MEDIA_MEAT *sMediaMeat;
sMediaMeat = (ST_MEDIA_MEAT *) sInfo.sMediaMeat[sInfo.bCurMode];
dwPage = dwLogAddr % sMediaMeat->wMaxSector;
if (dwSectorCount > (sMediaMeat->wMaxSector - dwPage))
{
return (sMediaMeat->wMaxSector - dwPage);
}
return dwSectorCount;
}
static DWORD GetSameZone(DWORD dwLogAddr, DWORD dwSectorCount)
{
DWORD dwPage, dwCount;
dwPage = dwLogAddr % 128;
if (dwSectorCount > (128 - dwPage))
{
return (128 - dwPage);
}
return dwSectorCount;
}
static void Select(BYTE bMode)
{
register GPIO *sGpio;
sGpio = (GPIO *) (GPIO_BASE);
sInfo.bCurMode = bMode;
switch (bMode)
{
#if SM_ENABLE
case INITIAL_SM:
sGpio->Fgpcfg[0] &= ~(GPIO_DEFINE_0_SM|(GPIO_DEFINE_0_SM<<16));
sGpio->Fgpcfg[0] |= GPIO_DEFINE_0_SM;
sGpio->Fgpcfg[1] &= ~(GPIO_DEFINE_1_SM|(GPIO_DEFINE_1_SM<<16));
sGpio->Fgpcfg[1] |= GPIO_DEFINE_1_SM;
sGpio->Fgpcfg[2] &= ~(GPIO_DEFINE_2_SM|(GPIO_DEFINE_2_SM<<16));
sGpio->Fgpcfg[2] |= GPIO_DEFINE_2_SM;
sGpio->Fgpcfg[3] &= ~(GPIO_DEFINE_3_SM|(GPIO_DEFINE_3_SM<<16));
sGpio->Fgpcfg[3] |= GPIO_DEFINE_3_SM;
sInfo.dwCurModeSetting = SETTING_SM;
sInfo.dwReadTiming = READ_TIMING_SM;
sInfo.dwWriteTiming = WRITE_TIMING_SM;
// MP_DEBUG("-I- initial SM");
break;
#endif
case INITIAL_NAND:
sGpio->Fgpcfg[0] &= ~(GPIO_DEFINE_0_NAND|(GPIO_DEFINE_0_NAND<<16));
sGpio->Fgpcfg[0] |= GPIO_DEFINE_0_SM;
sGpio->Fgpcfg[1] &= ~(GPIO_DEFINE_1_NAND|(GPIO_DEFINE_1_NAND<<16));
sGpio->Fgpcfg[1] |= GPIO_DEFINE_1_NAND;
sGpio->Fgpcfg[2] &= ~(GPIO_DEFINE_2_NAND|(GPIO_DEFINE_2_NAND<<16));
sGpio->Fgpcfg[2] |= GPIO_DEFINE_2_NAND;
sGpio->Fgpcfg[3] &= ~(GPIO_DEFINE_3_NAND|(GPIO_DEFINE_3_NAND<<16));
sGpio->Fgpcfg[3] |= GPIO_DEFINE_3_NAND;
// sGpio->Fgpcfg[1] &= ~0x00010001;
GpioValueSetting(1,XD_CE);
GpioValueSetting(1,NAND1_CE);
GpioValueSetting(1,NAND2_CE);
GpioValueSetting(1,NAND_WP);//SetNandWPHigh();
sInfo.dwCurModeSetting = SETTING_NAND;
sInfo.dwReadTiming = READ_TIMING_NAND;
sInfo.dwWriteTiming = WRITE_TIMING_NAND;
// MP_DEBUG("-I- initial NAND");
break;
case INITIAL_XD:
sGpio->Fgpcfg[0] &= ~(GPIO_DEFINE_0_XD|(GPIO_DEFINE_0_XD<<16));
sGpio->Fgpcfg[0] |= GPIO_DEFINE_0_XD;
sGpio->Fgpcfg[1] &= ~(GPIO_DEFINE_1_XD|(GPIO_DEFINE_1_XD<<16));
sGpio->Fgpcfg[1] |= GPIO_DEFINE_1_XD;
sGpio->Fgpcfg[2] &= ~(GPIO_DEFINE_2_XD|(GPIO_DEFINE_2_XD<<16));
sGpio->Fgpcfg[2] |= GPIO_DEFINE_2_XD;
sGpio->Fgpcfg[3] &= ~(GPIO_DEFINE_3_XD|(GPIO_DEFINE_3_XD<<16));
sGpio->Fgpcfg[3] |= GPIO_DEFINE_3_XD;
/*
sGpio->Fgpcfg[1] &= ~0x00010001;
sGpio->Fgpdat[1] &= ~0x00010000;
*/
GpioValueSetting(1,XD_CE);
GpioValueSetting(1,NAND1_CE);
GpioValueSetting(1,NAND2_CE);
#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600)
GpioValueSetting(1,XD_WP);
#if LCD_PANEL_480_234
if( !Ui_CheckMsPlugIn() )
SetGPIOValue(GPIO_XD_VCC, 0);
#endif
#else
GpioValueSetting(0,XD_WP);
GpioValueSetting(0,XD_VCC);
McardIODelay(10);
GpioValueSetting(1,XD_WP);
#endif
sInfo.dwCurModeSetting = SETTING_XD;
sInfo.dwReadTiming = READ_TIMING_XD;
sInfo.dwWriteTiming = WRITE_TIMING_XD;
// MP_DEBUG("-I- initial XD");
break;
}
}
static void DeSelect(void)
{
register GPIO *sGpio;
register MCARD *sMcard;
sMcard = (MCARD *) (MCARD_BASE);
sGpio = (GPIO *) (GPIO_BASE);
switch (sInfo.bCurMode)
{
case INITIAL_SM:
sGpio->Fgpcfg[0] &= ~GPIO_DEFINE_0_SM;
sGpio->Fgpcfg[1] &= ~GPIO_DEFINE_1_SM;
sGpio->Fgpcfg[2] &= ~GPIO_DEFINE_2_SM;
sGpio->Fgpcfg[3] &= ~GPIO_DEFINE_3_SM;
break;
case INITIAL_NAND:
sGpio->Fgpcfg[0] &= ~GPIO_DEFINE_0_NAND;
sGpio->Fgpcfg[0] &= ~(GPIO_DEFINE_0_NAND<<16);
// sGpio->Fgpdat[0] &= ~(GPIO_DEFINE_0_NAND);
// sGpio->Fgpdat[0] &= ~(GPIO_DEFINE_0_NAND<<16);
sGpio->Fgpcfg[1] &= ~GPIO_DEFINE_1_NAND;
sGpio->Fgpcfg[0] &= ~(GPIO_DEFINE_1_NAND <<16);
// sGpio->Fgpdat[1] &= ~(GPIO_DEFINE_1_NAND<<16);
sGpio->Fgpcfg[2] &= ~GPIO_DEFINE_2_NAND;
sGpio->Fgpcfg[2] &= ~(GPIO_DEFINE_2_NAND <<16);
// sGpio->Fgpdat[2] &= ~(GPIO_DEFINE_2_NAND<<16);
sGpio->Fgpcfg[3] &= ~GPIO_DEFINE_3_NAND;
sGpio->Fgpcfg[3] &= ~(GPIO_DEFINE_3_NAND <<16);
// sGpio->Fgpdat[3] &= ~(GPIO_DEFINE_3_NAND<<16);
GpioValueSetting(0,NAND_CLE);
break;
case INITIAL_XD:
// sGpio->Gpdat1 &= ~0x01000100; //simulate XD writeable pin
sGpio->Fgpcfg[0] &= ~GPIO_DEFINE_0_XD;
sGpio->Fgpcfg[1] &= ~GPIO_DEFINE_1_XD;
sGpio->Fgpcfg[2] &= ~GPIO_DEFINE_2_XD;
sGpio->Fgpcfg[3] &= ~GPIO_DEFINE_3_XD;
break;
}
sMcard->McardC &= ~MCARD_ENABLE;
}
static BYTE GetWPFlag(void)
{
register GPIO *sGpio;
sGpio = (GPIO *) (GPIO_BASE);
if (sInfo.bCurMode == INITIAL_SM)
{
#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600)
return ((sGpio->Fgpdat[0] & 0x00008000) ? 0 : 1);// 600 nand wp gpio 15
#else
return ((sGpio->Fgpdat[3] & 0x00000040) ? 0 : 1);// nand wp gpio 54
#endif
}
else if (sInfo.bCurMode == INITIAL_XD)
{
#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600)
return ((sGpio->Fgpdat[0] & 0x00008000) ? 0 : 1);// 600 xd wp gpio 15
#else
return ((sGpio->Fgpdat[3] & 0x00000400) ? 0 : 1); // xd wp gpio 58
#endif
}
return 0;
}
static void SetCommand(BYTE bCommand)
{
register MCARD *sMcard;
sMcard = (MCARD *) (MCARD_BASE);
if(sInfo.bCurMode == INITIAL_NAND){
GpioValueSetting(1,NAND_CLE);
}
else if(sInfo.bCurMode == INITIAL_XD){
GpioValueSetting(1,XD_CLE);
}
*((BYTE *) (&sMcard->McSmDat)) = bCommand;
if(sInfo.bCurMode == INITIAL_NAND){
GpioValueSetting(0,NAND_CLE);
}
else if(sInfo.bCurMode == INITIAL_XD){
GpioValueSetting(0,XD_CLE);
}
}
static SWORD Identify(DWORD * pdwTotalSector)
{
register MCARD *sMcard;
ST_MEDIA_MEAT_TABLE *sMediaMeatTable;
SWORD swRetValue;
BYTE bIDBuffer[4],DieNum,i;
DWORD TotalSector;
TotalSector = *pdwTotalSector;
sMcard = (MCARD *) (MCARD_BASE);
SetControl();
WaitReady();
if(sInfo.bCurMode == INITIAL_NAND)
{
GpioValueSetting(0,NAND1_CE);
}
if(sInfo.bCurMode == INITIAL_XD)
{
GpioValueSetting(0,XD_CE);
}
SetCommand(READ_ID_CMD);
if(sInfo.bCurMode == INITIAL_NAND){
GpioValueSetting(1,NAND_ALE);
}
else if(sInfo.bCurMode == INITIAL_XD){
GpioValueSetting(1,XD_ALE);
}
sMcard->McSmDat = 0x00;
if(sInfo.bCurMode == INITIAL_NAND){
GpioValueSetting(0,NAND_ALE);
}
else if(sInfo.bCurMode == INITIAL_XD){
GpioValueSetting(0,XD_ALE);
}
WaitReady();
bIDBuffer[0] = sMcard->McSmDat;
bIDBuffer[1] = sMcard->McSmDat;
bIDBuffer[2] = sMcard->McSmDat;
bIDBuffer[3] = sMcard->McSmDat;
if(sInfo.bCurMode == INITIAL_NAND)
{
#ifdef SHOW_NAND_ID
sInfo.bCurID[INITIAL_NAND] = bIDBuffer[1];
#endif
DieNum = bIDBuffer[2] & 0x03;
if(DieNum > 0)
MultiDieFlag |= MultiDie;
if((bIDBuffer[2] & 0x0c) == 0x04){
MLC =TRUE;
MP_DEBUG("MLC type nand");
}
}
sMcard->McSmC = 0x0;
GpioValueSetting(1,XD_CE);
GpioValueSetting(1,NAND1_CE);
GpioValueSetting(1,NAND2_CE);
MP_DEBUG4("-I- identify SM card Maker %x and Device code %x,3RD code %x , 4TH code %x", bIDBuffer[0], bIDBuffer[1],bIDBuffer[2],bIDBuffer[3]);
swRetValue = TYPE_NOT_SUPPORT;
for (sMediaMeatTable = (ST_MEDIA_MEAT_TABLE *) sMediaMeatTable_S; sMediaMeatTable->bID != 0;
sMediaMeatTable++)
{
if (sMediaMeatTable->bID == bIDBuffer[1])
{
sInfo.sMediaMeat[sInfo.bCurMode] = &sMediaMeatTable->sMediaMeat;
SetAddrInfo(0);
swRetValue = PASS;
break;
}
}
if (sInfo.bCurMode != INITIAL_XD)
{
// swRetValue = TYPE_NOT_SUPPORT; // for NAND
for (sMediaMeatTable = (ST_MEDIA_MEAT_TABLE *) sMediaMeatTable_B; sMediaMeatTable->bID != 0;
sMediaMeatTable++)
{
if (sMediaMeatTable->bID == bIDBuffer[1])
{
sInfo.sMediaMeat[sInfo.bCurMode] = &sMediaMeatTable->sMediaMeat;
SetAddrInfo(1);
swRetValue = PASS;
break;
}
}
}
// 20070601 abel add, if size <= 64MB, no MLC or MultiDie
if(sInfo.bCurMode == INITIAL_NAND)
{
if((sInfo.sMediaMeat[INITIAL_NAND]->bMaxZone <= 4)
&& (sInfo.sMediaMeat[INITIAL_NAND]->wMaxSector <= 0x20))
{
MLC = FALSE;
MultiDieFlag &= ~MultiDie;
}
}
if ((MLC == TRUE) && (sInfo.bCurMode == INITIAL_NAND))
{
swRetValue = TYPE_NOT_SUPPORT; // for NAND
#if (((CHIP_VER & 0x0000ffff) == CHIP_VER_B)||((CHIP_VER & 0x0000ffff) == CHIP_VER_C))
for (sMediaMeatTable = (ST_MEDIA_MEAT_TABLE *) sMediaMeatTable_MLC; sMediaMeatTable->bID != 0;
sMediaMeatTable++)
{
if (sMediaMeatTable->bID == bIDBuffer[1])
{
sInfo.sMediaMeat[sInfo.bCurMode] = &sMediaMeatTable->sMediaMeat;
SetAddrInfo(1);
swRetValue = PASS;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -