📄 sm.c
字号:
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
//mark the delay will increase read speed about 800KB in XD 2G H Type
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;
}
//#endif
}
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)
{
MP_DEBUG2("-I- SM FlatWrite ,dwLogAddr %d,dwSectorCount %d",dwLogAddr,dwSectorCount);
//#ifdef NOR
if(sInfo.bCurMode == INITIAL_NAND)
{
DWORD dwCount;
DWORD i,dwVeryCount,dwVeryLogAddr;
SWORD swRetValue;
BYTE bRetry;
while (dwSectorCount)
{
bRetry = MCARD_RETRY_TIME;
dwCount = GetSameZone(dwLogAddr, dwSectorCount);
while (bRetry)
{
if (!(swRetValue = LogicalWrite(dwLogAddr, dwCount, dwBufferAddress)))
{
break;
}
bRetry--;
}
if (swRetValue)
{
return swRetValue;
}
dwSectorCount -= dwCount;
dwLogAddr += dwCount;
dwBufferAddress += (dwCount << MCARD_SECTOR_BIT_OFFSET);
}
return PASS;
}
else
//#else
{
DWORD dwCount;
DWORD i,dwVeryCount,dwVeryLogAddr;
SWORD swRetValue;
BYTE bRetry;
// MP_DEBUG2("-I- SM FlatWrite ,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 = 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);
}
return PASS;
}
//#endif
}
static SWORD LogicalWrite(DWORD dwLogAddr, DWORD dwSectorCount, DWORD dwBufferAddress)
{
//#ifdef NOR
if(sInfo.bCurMode == INITIAL_NAND)
{
ST_MEDIA_MEAT *sMediaMeat;
DWORD dwNewPhyAddr, dwBlock, dwLogBlock, dwZone, dwPhyBlockAddr, dwPhyAddr, dwPage, dwTail, i;
SWORD swRetValue;
WORD *pwLog2PhyTable;
BYTE *pbTempBuffer, *pbBuffer, *pReAssignTable,*pbTempBuffer1;
DWORD dwEZone,dwSZone;
DWORD dwEmptyBlockOffset;
pbBuffer = (BYTE *) dwBufferAddress;
dwPage = dwLogAddr % 128;
dwTail = 128 - dwPage - dwSectorCount;
if ((dwPage == 0) && (dwTail == 0))
{
pbTempBuffer = (BYTE *) dwBufferAddress;
}
else
{
pbTempBuffer1 =(BYTE *)mem_malloc(128<<9);
// pbTempBuffer1 =&bTempBuffer[0];
pbTempBuffer = pbTempBuffer1;
if (dwPage)
{
if ((swRetValue = PhysicalRead((dwLogAddr - dwPage), dwPage, (DWORD) pbTempBuffer)))
{
mem_free(pbTempBuffer1);
MP_DEBUG1("-E- PhysicalRead FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
pbTempBuffer += (dwPage << MCARD_SECTOR_BIT_OFFSET);
}
for (i = 0; i < (dwSectorCount << MCARD_SECTOR_BIT_OFFSET); i++)
{
*pbTempBuffer++ = *pbBuffer++;
}
if (dwTail)
{
if ((swRetValue =PhysicalRead((dwLogAddr + dwSectorCount), dwTail, (DWORD) pbTempBuffer)))
{
mem_free(pbTempBuffer1);
MP_DEBUG1("-E- PhysicalRead FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
}
// pbTempBuffer = bTempBuffer;
pbTempBuffer = pbTempBuffer1;
}
if ((PhysicalWrite((dwLogAddr-(dwLogAddr%128)), 128,(DWORD) pbTempBuffer, dwBlock) == 0))
{
mem_free(pbTempBuffer1);
MP_DEBUG1("-E- SmPhysicalWrite FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
mem_free(pbTempBuffer1);
return PASS;
}
else
//#else
{
ST_MEDIA_MEAT *sMediaMeat;
DWORD dwNewPhyAddr, dwBlock, dwLogBlock, dwZone, dwPhyBlockAddr, dwPhyAddr, dwPage, dwTail, i;
SWORD swRetValue;
WORD *pwLog2PhyTable;
BYTE *pbTempBuffer, *pbBuffer, *pReAssignTable,*pbTempBuffer1;
DWORD dwEZone,dwSZone;
DWORD dwEmptyBlockOffset;
if (!dwSectorCount)
{
MP_DEBUG1("-E- dwSectorCount %d", dwSectorCount);
return FAIL;
}
pbBuffer = (BYTE *) dwBufferAddress;
sMediaMeat = (ST_MEDIA_MEAT *) sInfo.sMediaMeat[sInfo.bCurMode];
pReAssignTable = (BYTE *) sInfo.bReAssignTable[sInfo.bCurMode];
dwPage = dwLogAddr % sMediaMeat->wMaxSector;
dwBlock = dwLogAddr / sMediaMeat->wMaxSector;
dwZone = dwBlock / sMediaMeat->wMaxLogBlock;
dwLogBlock = dwBlock % sMediaMeat->wMaxLogBlock;
if(sInfo.bCurMode == INITIAL_NAND)
{
pwLog2PhyTable = (WORD *) sInfo.wNandLog2PhyTable;
dwPhyBlockAddr = pwLog2PhyTable[(dwZone * MAX_BLOCK) + dwLogBlock];
dwPhyBlockAddr = dwPhyBlockAddr + (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("Write Dny table from zone %d to zone %d ",dwZone,dwEZone);
Log2PhyTabInit(dwZone, dwEZone);
}
pwLog2PhyTable = (WORD *) sInfo.wXdDLog2PhyTable;
dwPhyBlockAddr = (((dwZone-XD_STA_ZONE) / XD_DNY_ZONE)*XD_DNY_ZONE*MAX_BLOCK);
dwPhyBlockAddr += (((dwZone-XD_STA_ZONE) % XD_DNY_ZONE)*MAX_BLOCK);
dwPhyBlockAddr += XD_STA_ZONE*MAX_BLOCK;
// dwPhyBlockAddr = dwZone*MAX_BLOCK;
dwEmptyBlockOffset = dwPhyBlockAddr;
dwSZone = dwZone-sInfo.dwXdCurZone;
dwPhyBlockAddr+=pwLog2PhyTable[(dwSZone%XD_DNY_ZONE) * MAX_BLOCK + dwLogBlock];
}
else
{
pwLog2PhyTable = (WORD *) sInfo.wXdSLog2PhyTable;
dwPhyBlockAddr = (dwZone *MAX_BLOCK);
dwEmptyBlockOffset = dwPhyBlockAddr;
dwSZone = dwZone;
dwPhyBlockAddr+=pwLog2PhyTable[dwZone * MAX_BLOCK + dwLogBlock];
}
}
dwPhyAddr = (dwPhyBlockAddr * sMediaMeat->wMaxSector) + dwPage; // get physical sector address;
dwTail = sMediaMeat->wMaxSector - dwPage - dwSectorCount;
if ((dwPage == 0) && (dwTail == 0))
{
pbTempBuffer = (BYTE *) dwBufferAddress;
}
else
{
pbTempBuffer1 = (BYTE *)mem_malloc(0x40000);
pbTempBuffer = pbTempBuffer1;
if (dwPage)
{
if ((swRetValue = PhysicalRead((dwPhyAddr - dwPage), dwPage, (DWORD) pbTempBuffer)))
{
MP_DEBUG1("-E- PhysicalRead FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
pbTempBuffer += (dwPage << MCARD_SECTOR_BIT_OFFSET);
}
for (i = 0; i < (dwSectorCount << MCARD_SECTOR_BIT_OFFSET); i++)
{
*pbTempBuffer++ = *pbBuffer++;
}
if (dwTail)
{
if ((swRetValue =PhysicalRead((dwPhyAddr + dwSectorCount), dwTail, (DWORD) pbTempBuffer)))
{
mem_free(pbTempBuffer1);
MP_DEBUG1("-E- PhysicalRead FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
}
// pbTempBuffer = bTempBuffer;
pbTempBuffer = pbTempBuffer1;
}
dwNewPhyAddr = GetEmptyBlock(dwSZone,dwZone,pwLog2PhyTable);
if (dwNewPhyAddr == 0xffff)
{
pReAssignTable[dwZone] = 0;
dwNewPhyAddr = GetEmptyBlock(dwSZone,dwZone,pwLog2PhyTable);
if (dwNewPhyAddr == 0xffff)
{
mem_free(pbTempBuffer1);
MP_DEBUG("-E- no free block");
return FAIL;
}
}
if(sInfo.bCurMode == INITIAL_NAND)
dwNewPhyAddr += (dwZone * MAX_BLOCK);
else if(sInfo.bCurMode == INITIAL_XD)
dwNewPhyAddr += dwEmptyBlockOffset;
if ((swRetValue = PhysicalErase((dwNewPhyAddr * sMediaMeat->wMaxSector))))
{
mem_free(pbTempBuffer1);
MP_DEBUG1("-E- SmPhysicalErase FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
if ((swRetValue =PhysicalWrite((dwNewPhyAddr * sMediaMeat->wMaxSector), sMediaMeat->wMaxSector,(DWORD) pbTempBuffer, dwBlock)))
{
mem_free(pbTempBuffer1);
MP_DEBUG1("-E- SmPhysicalWrite FAIL (swRetValue
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -