📄 sm.c
字号:
}
}
#endif
}
if(swRetValue != PASS){
MP_DEBUG("TYPE - NOT - SUPPORT");
return swRetValue;
}
*pdwTotalSector =
(sInfo.sMediaMeat[sInfo.bCurMode]->bMaxZone *
sInfo.sMediaMeat[sInfo.bCurMode]->wMaxLogBlock *
sInfo.sMediaMeat[sInfo.bCurMode]->wMaxSector);
if(sInfo.bCurMode == INITIAL_NAND){
if((MultiDieFlag & MultiDie) == MultiDie){
MP_DEBUG(" ***** This Nand is Multi-Die ***** ");
*pdwTotalSector = (*pdwTotalSector) * 2;
sMediaMeatTable++;
sInfo.sMediaMeat[sInfo.bCurMode] = &sMediaMeatTable->sMediaMeat;
}
MaxLogPage = (sInfo.sMediaMeat[sInfo.bCurMode]->bMaxZone *
sInfo.sMediaMeat[sInfo.bCurMode]->wMaxLogBlock*
sInfo.sMediaMeat[sInfo.bCurMode]->wMaxSector);
MaxPhyPage = (sInfo.sMediaMeat[sInfo.bCurMode]->bMaxZone *
sInfo.sMediaMeat[sInfo.bCurMode]->wMaxBlock *
sInfo.sMediaMeat[sInfo.bCurMode]->wMaxSector);
}
MP_DEBUG3("-I- Total %d(%x) sectors, %d KB", *pdwTotalSector, *pdwTotalSector,
(*pdwTotalSector >> 1));
return swRetValue;
}
static void SetAddrInfo(BYTE bType)
{
DWORD dwSize;
BYTE bTimes;
if (bType == 0)
{
dwSize =
(sInfo.sMediaMeat[sInfo.bCurMode]->bMaxZone *
sInfo.sMediaMeat[sInfo.bCurMode]->wMaxBlock *
sInfo.sMediaMeat[sInfo.bCurMode]->wMaxSector) - 1;
}
else
{
dwSize =
((sInfo.sMediaMeat[sInfo.bCurMode]->bMaxZone *
sInfo.sMediaMeat[sInfo.bCurMode]->wMaxBlock *
sInfo.sMediaMeat[sInfo.bCurMode]->wMaxSector) >> 2) - 1;
}
bTimes = 0;
while (dwSize)
{
dwSize = dwSize >> 8;
bTimes += 1;
}
sInfo.bAddrInfo[sInfo.bCurMode][0] = bTimes;
sInfo.bAddrInfo[sInfo.bCurMode][2] = ADR_LENGTH_3;
if (bTimes == 4)
{
sInfo.bAddrInfo[sInfo.bCurMode][2] = ADR_LENGTH_4;
}
else if (bTimes >= 5)
{
sInfo.bAddrInfo[sInfo.bCurMode][2] = ADR_LENGTH_5;
}
if (bType == 0)
{
bTimes += 1;
}
else
{
bTimes += 2;
}
sInfo.bAddrInfo[sInfo.bCurMode][1] = ADR_LENGTH_3;
if (bTimes == 4)
{
sInfo.bAddrInfo[sInfo.bCurMode][1] = ADR_LENGTH_4;
}
else if (bTimes >= 5)
{
sInfo.bAddrInfo[sInfo.bCurMode][1] = ADR_LENGTH_5;
}
}
static void SetControl(void)
{
register MCARD *sMcard;
sMcard = (MCARD *) (MCARD_BASE);
sMcard->McardC = 0; // abel test
sMcard->McardC = (MCARD_ENABLE | MCARD_DMA_SM);
sMcard->McRtm = sInfo.dwReadTiming;
sMcard->McWtm = sInfo.dwWriteTiming;
sMcard->McSmIc = IM_ALL;
sMcard->McSmC = sInfo.dwCurModeSetting;
}
//==========================================================================
static inline BOOL Polling_SM_Status(void)
{
/*
if (sInfo.dwCurModeSetting == SETTING_SM)
return !Ui_CheckSmPlugIn();
else if (sInfo.dwCurModeSetting == SETTING_XD)
return !Ui_CheckXdPlugIn();
else
*/
return 0;
}
static SWORD WaitReady(void)
{
register MCARD *sMcard;
DWORD dwTimeCount;
sMcard = (MCARD *) (MCARD_BASE);
dwTimeCount = (g_bAniFlag & ANI_VIDEO)? (TIMEOUT_COUNT>>3):TIMEOUT_COUNT;
while (dwTimeCount)
{
if (Polling_SM_Status())
return FAIL;
if (!(sMcard->McSmIc & IC_SRB))
{
return PASS;
}
dwTimeCount--;
// McardIODelay(5);
TASK_YIELD();
}
return TIMEOUT;
}
static void SetAddress(DWORD dwPhyAddr, BYTE bMode)
{
register MCARD *sMcard;
DWORD dwTemp, i;
sMcard = (MCARD *) (MCARD_BASE);
sMcard->McSmC &= 0xffffff9f;
if(sInfo.bCurMode == INITIAL_NAND){
GpioValueSetting(1,NAND_ALE);
}
else if(sInfo.bCurMode == INITIAL_XD){
GpioValueSetting(1,XD_ALE);
}
switch (bMode)
{
case 1:
dwTemp = dwPhyAddr;
sMcard->McSmC |= sInfo.bAddrInfo[sInfo.bCurMode][2];
if (((sInfo.bCurMode == INITIAL_NAND) && (sInfo.sMediaMeat[sInfo.bCurMode]->wMaxSector == 0x100)) ||
((sInfo.bCurMode == INITIAL_NAND) && (sInfo.sMediaMeat[sInfo.bCurMode]->wMaxSector == 0x200)))
{
dwTemp = dwTemp >> 2;
}
break;
case 0:
default:
sMcard->McSmC |= sInfo.bAddrInfo[sInfo.bCurMode][1];
if (((sInfo.bCurMode == INITIAL_NAND) && (sInfo.sMediaMeat[sInfo.bCurMode]->wMaxSector == 0x100)) ||
((sInfo.bCurMode == INITIAL_NAND) && (sInfo.sMediaMeat[sInfo.bCurMode]->wMaxSector == 0x200)))
{
dwTemp = (dwPhyAddr % 4) * 528;
sMcard->McSmDat = (BYTE) (dwTemp & 0xff);
dwTemp = dwTemp >> 8;
sMcard->McSmDat = (BYTE) (dwTemp & 0xff);
dwTemp = dwPhyAddr >> 2;
}
else
{
dwTemp = dwPhyAddr;
sMcard->McSmDat = 0x00;
}
break;
}
for (i = 0; i < sInfo.bAddrInfo[sInfo.bCurMode][0]; i++)
{
sMcard->McSmDat = (BYTE)(dwTemp & 0xff);
dwTemp = dwTemp >> 8;
//McardIODelay(5);
}
if(sInfo.bCurMode == INITIAL_NAND){
GpioValueSetting(0,NAND_ALE);
}
else if(sInfo.bCurMode == INITIAL_XD){
GpioValueSetting(0,XD_ALE);
McardIODelay(20); // abel 20070706 for UNI-V KinSton CF + XD issue
}
}
static void TimeoutHandle(void)
{
register CHANNEL *sChannel;
sChannel = (CHANNEL *) (DMA_MC_BASE);
sChannel->Control = 0;
DmaIntDis(IM_MCRDDM);
blTimeOutFlag = 1;
TaskWakeup(MCARD_TASK);
}
static SWORD FlatRead(DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr)
{
//#ifdef NOR
if(sInfo.bCurMode == INITIAL_NAND)
{
MP_DEBUG2("-I- Nand FlatRead ,dwLogAddr %d,dwSectorCount %d",dwLogAddr,dwSectorCount);
DWORD dwCount;
SWORD swRetValue;
BYTE bRetry;
// MP_DEBUG2("-I- SM FlatRead ,dwLogAddr %d,dwSectorCount %d",dwLogAddr,dwSectorCount);
while (dwSectorCount)
{
bRetry = MCARD_RETRY_TIME;
dwCount = GetSameBlock(dwLogAddr, dwSectorCount);
while (bRetry)
{
if (!(swRetValue = LogicalRead(dwLogAddr, dwCount, dwBufferAddress)))
{
break;
}
bRetry--;
MP_DEBUG1("-I- remain retry times %d", bRetry);
}
if (swRetValue)
{
return swRetValue;
}
dwSectorCount -= dwCount;
dwLogAddr += dwCount;
dwBufferAddress += (dwCount << MCARD_SECTOR_BIT_OFFSET);
}
//DeSelect();
MP_DEBUG("pass");
return PASS;
}
else
//#else
{
DWORD dwCount;
SWORD swRetValue;
BYTE bRetry;
MP_DEBUG2("-I- XD FlatRead ,dwLogAddr %d,dwSectorCount %d",dwLogAddr,dwSectorCount);
while (dwSectorCount)
{
bRetry = MCARD_RETRY_TIME;
dwCount = GetSameBlock(dwLogAddr, dwSectorCount);
while (bRetry)
{
if (Polling_SM_Status())
return FAIL;
if (!(swRetValue = LogicalRead(dwLogAddr, dwCount, dwBufferAddress)))
{
break;
}
bRetry--;
MP_DEBUG1("-I- remain retry times %d", bRetry);
}
if (swRetValue)
{
return swRetValue;
}
dwSectorCount -= dwCount;
dwLogAddr += dwCount;
dwBufferAddress += (dwCount << MCARD_SECTOR_BIT_OFFSET);
}
//DeSelect();
return PASS;
}
//#endif
}
static SWORD LogicalRead(DWORD dwLogAddr, DWORD dwSectorCount, DWORD dwBufferAddress)
{
//#ifdef NOR
if(sInfo.bCurMode == INITIAL_NAND)
{
SWORD swRetValue;
if ((swRetValue = PhysicalRead(dwLogAddr, dwSectorCount, dwBufferAddress)))
{
MP_DEBUG1("-E- SmPhysicalRead FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
return PASS;
}
else
//#else
{
ST_MEDIA_MEAT *sMediaMeat;
DWORD dwPhyBlock, dwLogBlock, dwZone, dwPhyAddr, dwPhyPage;
SWORD swRetValue;
WORD *pwLog2PhyTable;
DWORD dwEZone;
if (!dwSectorCount)
{
MP_DEBUG1("-E- dwSectorCount %d", dwSectorCount);
return FAIL;
}
sMediaMeat = (ST_MEDIA_MEAT *) sInfo.sMediaMeat[sInfo.bCurMode];
// pwLog2PhyTable = (WORD *) sInfo.wLog2PhyTable[sInfo.bCurMode];
dwPhyPage = dwLogAddr % sMediaMeat->wMaxSector;
dwPhyBlock = dwLogAddr / sMediaMeat->wMaxSector;
dwZone = dwPhyBlock / sMediaMeat->wMaxLogBlock;
dwLogBlock = dwPhyBlock % sMediaMeat->wMaxLogBlock;
if(sInfo.bCurMode == INITIAL_NAND)
{
pwLog2PhyTable = (WORD *) sInfo.wNandLog2PhyTable;
dwPhyAddr = pwLog2PhyTable[(dwZone * MAX_BLOCK) + dwLogBlock];
dwPhyAddr = dwPhyAddr + (dwZone * MAX_BLOCK); //get physical block address
}
else if(sInfo.bCurMode == INITIAL_XD)
{
if(dwZone >= XD_STA_ZONE)
{
if((sInfo.dwXdCurZone > dwZone) ||((sInfo.dwXdCurZone+XD_DNY_ZONE-1) < dwZone) \
||(sInfo.dwXdCurZone ==0))
{
sInfo.dwXdCurZone = (BYTE)dwZone;
dwEZone = dwZone+XD_DNY_ZONE;
if(dwEZone > sMediaMeat->bMaxZone)
dwEZone = sMediaMeat->bMaxZone;
MP_DEBUG2("Read Dny table from zone %d to zone %d ",dwZone,dwEZone);
Log2PhyTabInit(dwZone, dwEZone);
}
pwLog2PhyTable = (WORD *) sInfo.wXdDLog2PhyTable;
dwPhyAddr = (((dwZone-XD_STA_ZONE) / XD_DNY_ZONE)*XD_DNY_ZONE*MAX_BLOCK);
dwPhyAddr += (((dwZone-XD_STA_ZONE) % XD_DNY_ZONE)*MAX_BLOCK);
dwPhyAddr += XD_STA_ZONE*MAX_BLOCK;
// dwPhyAddr = dwZone*MAX_BLOCK;
dwPhyAddr+=pwLog2PhyTable[((dwZone-sInfo.dwXdCurZone)%XD_DNY_ZONE) * MAX_BLOCK + dwLogBlock];
}
else
{
pwLog2PhyTable = (WORD *) sInfo.wXdSLog2PhyTable;
dwPhyAddr = (dwZone *MAX_BLOCK);
dwPhyAddr+=pwLog2PhyTable[dwZone * MAX_BLOCK + dwLogBlock];
}
}
dwPhyAddr = (dwPhyAddr * sMediaMeat->wMaxSector) + dwPhyPage; // get physical sector address;
if ((swRetValue = PhysicalRead(dwPhyAddr, dwSectorCount, dwBufferAddress)))
{
MP_DEBUG1("-E- SmPhysicalRead FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
return PASS;
}
//#endif
}
//#define 1M 0x00100000
#define CODE_FLASH_BASE 0xbfc00000
#if USE_512K_SIZE
#define FLASH_DATA_BASE 0x00180000// 512kB
#else
#define FLASH_DA_BASE 0x00100000// 1MB
#endif
static SWORD PhysicalRead(DWORD dwPhyAddr, DWORD dwSectorCount, DWORD dwBufferAddress)
{
//#ifdef NOR
if(sInfo.bCurMode == INITIAL_NAND)
{
DWORD *pdwMem;
DWORD dwNorRAddr;
DWORD dwCount;
DWORD *pdwSBuffer,*pdwTBuffer;
dwNorRAddr = CODE_FLASH_BASE +FLASH_DATA_BASE;
pdwMem = 0x80418848;
dwNorRAddr += dwPhyAddr << 9;
dwCount = dwSectorCount << (9-2);
pdwTBuffer = dwBufferAddress;
pdwSBuffer = dwNorRAddr;
while(dwCount != 0)
{
*pdwTBuffer++ = *pdwSBuffer++;
dwCount--;
};
return PASS;
}
else
//#else
{
register MCARD *sMcard;
SWORD swRetValue;
DWORD i, dwTempAddr;
BYTE *pbBuffer;
BYTE bp=0;
pbBuffer = (BYTE *) dwBufferAddress;
sMcard = (MCARD *) (MCARD_BASE);
if(sInfo.bCurMode == INITIAL_NAND){
if((MultiDieFlag & MultiDie) == MultiDie){
if(dwPhyAddr < (MaxPhyPage/2)){
GpioValueSetting(0,NAND1_CE);
// MP_DEBUG("read nand 1");
}else{
dwPhyAddr = dwPhyAddr - (MaxPhyPage/2);
GpioValueSetting(0,NAND2_CE);
MP_DEBUG("read nand 2");
}
}
else{
// MP_DEBUG("read nand 1");
GpioValueSetting(0,NAND1_CE);
}
}
else if(sInfo.bCurMode == INITIAL_XD){
GpioValueSetting(0,XD_CE);
}
if (((sInfo.bCurMode == INITIAL_NAND) && (sInfo.sMediaMeat[sInfo.bCurMode]->wMaxSector == 0x100)) ||
((sInfo.bCurMode == INITIAL_NAND) && (sInfo.sMediaMeat[sInfo.bCurMode]->wMaxSector == 0x200)))
{
//big block
SetControl();
if ((swRetValue = WaitReady()))
{
MP_DEBUG1("-E- Read Command FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
//McardIODelay(5);
dwTempAddr = dwPhyAddr;
SetCommand(READ_PAGE1_CMD);
SetAddress(dwTempAddr, 0);
SetCommand(READ_PAGE1_CMD_2CYC);
while (dwSectorCount)
{
if ((swRetValue = WaitReady()))
{
MP_DEBUG1("-E- Read Command FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -