📄 sm_normal.c
字号:
//==========================================================================
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)
{
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 (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;
}
static SWORD LogicalRead(DWORD dwLogAddr, DWORD dwSectorCount, DWORD dwBufferAddress)
{
ST_MEDIA_MEAT *sMediaMeat;
DWORD dwPhyBlock, dwLogBlock, dwZone, dwPhyAddr, dwPhyPage;
SWORD swRetValue;
WORD *pwLog2PhyTable;
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;
dwPhyAddr = pwLog2PhyTable[(dwZone * MAX_BLOCK) + dwLogBlock];
dwPhyAddr = dwPhyAddr + (dwZone * MAX_BLOCK); //get physical block address
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;
}
static SWORD PhysicalRead(DWORD dwPhyAddr, DWORD dwSectorCount, DWORD dwBufferAddress)
{
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;
}
if ((swRetValue = ReadSector((DWORD) pbBuffer, MCARD_SECTOR_SIZE)))
{
MP_DEBUG1("-E- DMA Read FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
// Read spare area out
if (dwSectorCount != 0)
{
for (i = 0; i < 0x10; i++)
{
bRedtData[i] = sMcard->McSmDat;
}
}
if ((MLC != TRUE) && (sInfo.bCurMode == INITIAL_NAND))
{
//ECC_Check();
}
#if ECC4S_ENABLE
if ((MLC == TRUE) && (sInfo.bCurMode == INITIAL_NAND))
{
if(ECC4S_Decode_Check((DWORD)pbBuffer) == CORRECT_COMPLETE)
MP_DEBUG2("Physical Read dwPhyAddr = %x,dwSectorCount = %x",dwPhyAddr,dwSectorCount);
}
#endif
pbBuffer += MCARD_SECTOR_SIZE;
dwSectorCount--;
dwTempAddr++;
if ((dwTempAddr % 4) == 0)
{
SetCommand(READ_PAGE1_CMD);
SetAddress(dwTempAddr, 0);
SetCommand(READ_PAGE1_CMD_2CYC);
}
}
}
else
{
//small block
SetControl();
WaitReady();
//McardIODelay(5);
if(sInfo.bCurMode == INITIAL_XD)
{
SetCommand(READ_PAGE1_CMD);
SetAddress(dwPhyAddr, 0);
}
while (dwSectorCount)
{
if ((sInfo.bCurMode == INITIAL_NAND) && (sInfo.sMediaMeat[sInfo.bCurMode]->wMaxSector == 0x20))
{
SetCommand(READ_PAGE1_CMD);
SetAddress(dwPhyAddr, 0);
}
if(sInfo.bCurMode == INITIAL_XD)
McardIODelay(20); // abel 20070706 for UNI-V KinSton CF + XD issue
if ((swRetValue = WaitReady()))
{
MP_DEBUG1("-E- Read Command FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
if ((swRetValue = ReadSector((DWORD) pbBuffer, MCARD_SECTOR_SIZE)))
{
MP_DEBUG1("-E- DMA Read FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
// Read spare area out
if (dwSectorCount != 0)
{
for (i = 0; i < 0x10; i++)
{
bRedtData[i] = sMcard->McSmDat;
}
}
//ECC_Check();
pbBuffer += MCARD_SECTOR_SIZE;
dwSectorCount--;
if ((sInfo.bCurMode == INITIAL_NAND) && (sInfo.sMediaMeat[sInfo.bCurMode]->wMaxSector == 0x20))
{
dwPhyAddr++;
}
}
}
sMcard->McSmC = 0x0;
GpioValueSetting(1,NAND1_CE);
GpioValueSetting(1,NAND2_CE);
GpioValueSetting(1,XD_CE);
return PASS;
}
static SWORD ReadSector(DWORD dwBufferAddress, WORD wSize)
{
register CHANNEL *sChannel;
register MCARD *sMcard;
DWORD dwTimeOutCount;
#if ECC4S_ENABLE
if ((MLC == TRUE) && (sInfo.bCurMode == INITIAL_NAND))
ECC4S_Decode();
#endif
if (dwBufferAddress & 0x3)
{
MP_DEBUG("-E- target buffer must align to 4 bytes boundary !");
return FAIL;
}
sChannel = (CHANNEL *) (DMA_MC_BASE);
sMcard = (MCARD *) (MCARD_BASE);
sMcard->McSmC &=~ ECC_ENABLE;
sMcard->McSmC |= ECC_ENABLE;
#ifdef SM_TIMEOUT_HANDLE
DmaIntEna(IM_MCRDDM);
blTimeOutFlag = 0;
AddTimerProc(2000, TimeoutHandle);
sChannel->Control = 0x0;
sChannel->StartA = dwBufferAddress;
sChannel->EndA = dwBufferAddress + wSize - 1;
sMcard->McDmarl = MCARD_DMA_LIMIT_ENABLE + (wSize >> 2);
sMcard->McardC = ((sMcard->McardC & 0xffffffef) | MCARD_DMA_DIR_CM | MCARD_FIFO_ENABLE);
sChannel->Control = (MCARD_DMA_ENABLE | MCARD_INT_DBFEND_ENABLE);
TaskSleep();
if (blTimeOutFlag == 1)
{
MP_DEBUG1("-E- DMA end FAIL (status: %x)", sChannel->Control);
return DMA_TIMEOUT;
}
RemoveTimerProc(TimeoutHandle);
return PASS;
#else
sChannel->Control = 0x0;
sChannel->StartA = dwBufferAddress;
sChannel->EndA = dwBufferAddress + wSize - 1;
sMcard->McDmarl = MCARD_DMA_LIMIT_ENABLE + (wSize >> 2);
sMcard->McardC = ((sMcard->McardC & 0xffffffef) | MCARD_DMA_DIR_CM | MCARD_FIFO_ENABLE);
//sChannel->Control = MCARD_DMA_ENABLE;
dwTimeOutCount = (g_bAniFlag & ANI_VIDEO)? (TIMEOUT_COUNT>>3):TIMEOUT_COUNT;
/*
while (!(sMcard->McSmIc & IC_SFTCE))
{
if (Polling_SM_Status())
return FAIL;
if (dwTimeOutCount == 0)
{
MP_DEBUG1("-E- FIFO transaction count FAIL (status: %x)", sMcard->McSmIc);
return IC_SFTCE_TIMEOUT;
}
dwTimeOutCount--;
TASK_YIELD();
}
sMcard->McSmIc &= ~IC_SFTCE;
*/
#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600)
dwTimeOutCount = 0x4000000; //TIMEOUT_COUNT;
volatile register IPU *ipu;
ipu = (IPU *)IPU_BASE;
if (g_bAniFlag & ANI_VIDEO)
{
while (dwTimeOutCount )
{
if (ipu->IpIc & 0x1)
break;
dwTimeOutCount--;
}
}
sChannel->Control = MCARD_DMA_ENABLE;
#endif
dwTimeOutCount = (g_bAniFlag & ANI_VIDEO)? (TIMEOUT_COUNT>>3):TIMEOUT_COUNT;
while ((sChannel->Control & MCARD_DMA_ENABLE))
{
if (Polling_SM_Status())
return FAIL;
if (dwTimeOutCount == 0)
{
MP_DEBUG2("-E- DMA end FAIL sChannel->Control: 0x%x , sChannel->Current = 0x%x", sChannel->Control,sChannel->Current);
MP_DEBUG2("-E- sChannel->StartA: 0x%x , sChannel->EndA = 0x%x", sChannel->StartA,sChannel->EndA);
MP_DEBUG1("sMcard->McSmC = 0x%x",sMcard->McSmC);
return DMA_TIMEOUT;
}
dwTimeOutCount--;
TASK_YIELD();
}
return PASS;
#endif
}
static SWORD FlatWrite(DWORD dwBufferAddress, DWORD dwSectorCount, DWORD dwLogAddr)
{
DWORD dwCount;
DWORD i,dwVeryCount,dwVeryLogAddr;
SWORD swRetValue;
BYTE bRetry;
/// MP_DEBUG2("-I- SM FlatWrite ,dwLogAddr %d,dwSectorCount %d",dwLogAddr,dwSectorCount);
#if WRITE_VERIFY
BYTE TempBuffer[512*dwSectorCount];
BYTE * pbTempBuffer1,*pbTempBuffer2;
pbTempBuffer1 = ImageAllocSourceBuffer(512*dwSectorCount + 32);
pbTempBuffer2 = (BYTE *)(DWORD)dwBufferAddress;
dwVeryCount = dwSectorCount;
dwVeryLogAddr = dwLogAddr;
#endif
while (dwSectorCount)
{
bRetry = MCARD_RETRY_TIME;
dwCount = GetSameBlock(dwLogAddr, dwSectorCount);
while (bRetry)
{
if (Polling_SM_Status())
return FAIL;
if (!(swRetValue = LogicalWrite(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);
}
#if WRITE_VERIFY
FlatRead(pbTempBuffer1,dwVeryCount,dwVeryLogAddr);
for(i=0;i<512*dwVeryCount;i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -