📄 ms.c
字号:
return PASS;
}
}
//Memory Stick Read TPC Bus State (page mode)
static SWORD ReadTpcBsPage(void)
{
register MCARD *sMcard;
register SWORD swRetValue;
register DWORD dwTemp, dwTimeout;
sMcard = (MCARD *) (MCARD_BASE);
sMcard->McardC = 0;
sMcard->McardC = MCARD_DMA_DIR_CM + sInfo.bBusWidth + (MCARD_FIFO_EMPTY | MCARD_ENABLE);
sMcard->McDmarl = MCARD_DMA_LIMIT_ENABLE + (MCARD_SECTOR_SIZE >> 2);
#if ((STD_BOARD_VER == MP600PQFP_8M_SDRAM)||(STD_BOARD_VER == MP600_128PQFP_CPU_8M_SDRAM))
sMcard->McardC |= (MCARD_FIFO_ENABLE+BIT11);
#else
sMcard->McardC |= (MCARD_FIFO_ENABLE);
#endif
// Wait fifo idle
dwTimeout = 0x100000;
#if 1//rick ms pro fast , 7/25
while (!(sMcard->McMsStatus & STATUS_FIFOIDLE))
{
if (Polling_MS_Status()) return FAIL;
if (dwTimeout == 0)
{
return TPC_RB_TIMEOUT;
}
dwTimeout--;
}
#endif
// Set int mask
sMcard->McMsIc = 0;
#ifdef MS_IRQ
sMcard->McMsIc = (PL_ALL_HIGH | IM_CMDEND | IM_TIMEOUT1 | IM_INVALIDCMD); // tpc cmd end, INT time out, invalid tpc cmd
SystemIntEna(IC_MCARD);
#else
SystemIntDis(IC_MCARD);
#endif
sMcard->McMsCmd = TPC_READ_LONG_DATA + DATA_PATH_BY_DMA + PAGE_MOD_512_BYTE;
// Wait dma done
if ((swRetValue = WaitDMAEnd())) // can not remove or will affect MS read to wrong data
{
return swRetValue;
}
// Wait cmd end
dwTemp = WaitCmdEnd();// this procedure can not remove
if (dwTemp & STATUS_TIMEOUT0)
{
return TPC_RB_TIMEOUT;
}
else if (dwTemp & STATUS_TIMEOUT1)
{
return TPC_INT_TIMEOUT;
}
else if (dwTemp & STATUS_CRCERROR)
{
return READ_DATA_CRC_ERROR;
}
else
{
return PASS;
}
}
//Memory Stick Write TPC Bus State (page mode)
static SWORD WriteTpcBsPage(void)
{
register MCARD *sMcard;
register SWORD swRetValue;
register DWORD dwTimeout;
sMcard = (MCARD *) (MCARD_BASE);
//sMcard->McardC = 0x00000400;
sMcard->McardC = 0;
sMcard->McardC = MCARD_DMA_DIR_MC + sInfo.bBusWidth + (MCARD_FIFO_EMPTY | MCARD_ENABLE);
sMcard->McDmarl = MCARD_DMA_LIMIT_ENABLE + (MCARD_SECTOR_SIZE >> 2);
#if ((STD_BOARD_VER == MP600PQFP_8M_SDRAM)||(STD_BOARD_VER == MP600_128PQFP_CPU_8M_SDRAM))
sMcard->McardC |= (MCARD_FIFO_ENABLE+BIT11);
#else
sMcard->McardC |= (MCARD_FIFO_ENABLE);
#endif
// Set int mask
sMcard->McMsIc = 0;
sMcard->McMsIc = (PL_ALL_HIGH | IM_HWRREQ);
sMcard->McMsCmd = TPC_WRITE_LONG_DATA + DATA_PATH_BY_DMA + PAGE_MOD_512_BYTE;
// Wait cmd end
dwTimeout = 0x100000;
#if 1//rick ms pro fast , 7/25
while (!(sMcard->McMsStatus & (STATUS_TIMEOUT1 | STATUS_TIMEOUT0 | STATUS_CMDEND)))
{
if (Polling_MS_Status()) return FAIL;
if (dwTimeout == 0)
{
return TPC_RB_TIMEOUT;
}
dwTimeout--;
}
#endif
if (sMcard->McMsStatus & STATUS_TIMEOUT0)
{
return TPC_RB_TIMEOUT;
}
else if (sMcard->McMsStatus & STATUS_TIMEOUT1)
{
return TPC_INT_TIMEOUT;
}
else
{
if ((swRetValue = WaitDMAEnd()))
{
MP_DEBUG1("-E- WaitDMAEnd FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
return PASS;
}
}
//Make Mapping Table Init Size 16(seg)*512(block)
//
// 0 ~ 495 | 496 ~ 511
// Log2Phy mapping | Free block table
//
//ps: frist seg only use 494 blocks , reserved 2 block for boot block
static SWORD InitLog2PhyTable(void)
{
register DWORD dwSegNum, dwPhyBlockAddr, dwLogBlockaddr, i;
SWORD swRetValue;
WORD wReAssignState, *wTempLogBufer, wTemp;
register WORD *pwLog2PhyTable;
WORD *pwReAssignTable;
BYTE bDisableBlock[MCARD_SECTOR_SIZE], bExtraBuffer[4], bTempBuffer[4];
BYTE *pbDisableBlock, *pbBuffer1, *pbBuffer2, bTempMemID0;
bTempMemID0 = OsTempMemAllocate();
pbBuffer1 = (BYTE *) GetOsTempMemory(bTempMemID0);
wTempLogBufer = (WORD *) ((DWORD) pbBuffer1);
pwLog2PhyTable = sInfo.wLog2PhyTable;
pwReAssignTable = sInfo.wReAssignTable;
pbDisableBlock = (BYTE *) (((DWORD) (&bDisableBlock) | 0xa0000000));
if ((swRetValue = PhysicalRead(sInfo.bBootBlock, 1, 1, (DWORD) pbDisableBlock)))
{
OsTempMemRelease(bTempMemID0);
MP_DEBUG1("-E- PhysicalRead FAIL (swRetValue: %d)", swRetValue);
return swRetValue;
}
// segment count
register DWORD dwSegBlockAddr = 0;
register WORD *pwCurLog2PhyTable;
for (dwSegNum = 0; dwSegNum < sInfo.dwSegment; dwSegNum++, dwSegBlockAddr += MAXPHYBLOCK)
{
DWORD dwLogAddrCheckValue = (dwSegNum * 496 + 494);
//ver.1.00 spec A.8 Logical/physical corresponding information creation process
//Init all Log2PhyTable(LPTable) and tmpLogBufer(FreeTable) to 0xffff
pwCurLog2PhyTable = &pwLog2PhyTable[dwSegBlockAddr];
for (dwPhyBlockAddr = 0; dwPhyBlockAddr < MAXPHYBLOCK; dwPhyBlockAddr++)
{
*pwCurLog2PhyTable = 0xffff;
pwCurLog2PhyTable++;
wTempLogBufer[dwPhyBlockAddr] = 0xffff;
}
//set 0 to wReAssignState(:Number of alternative[free] blocks)
wReAssignState = 0;
// Get all logical addr of one segment
// If segment 0, start at block 2 (first 2 block are reserved for boot block
for (dwPhyBlockAddr = (!dwSegNum) ? (sInfo.bBootBlock + 1) : 0;
dwPhyBlockAddr < MAXPHYBLOCK; dwPhyBlockAddr++)
{
// Check if disabled block
if (CheckDisableBlock((dwPhyBlockAddr + dwSegBlockAddr), pbDisableBlock))
{
continue;
}
// read extra data area on page 0 in block x
// uncorrectable error occured
if ((swRetValue =
ReadExtraData((dwSegBlockAddr + dwPhyBlockAddr), 0, (DWORD) bExtraBuffer)))
{
MP_DEBUG1("-E- ReadExtraData FAIL (swRetValue: %d)", swRetValue);
continue;
}
//last segment
//transformation table bit of block is 0
if ((dwSegNum == (sInfo.dwSegment - 1)) && (!(bExtraBuffer[1] & 0x8)))
{
PhysicalErase((dwSegBlockAddr + dwPhyBlockAddr));
}
// BS of block x is 0(: NG)
if (!(bExtraBuffer[0] & 0x80))
{
continue;
}
//PS of page 0 in block x is 3 or 6 ?? (: OK)
if (!(bExtraBuffer[0] & 0x60))
{
continue;
}
//set dwLogBlockaddr to Logical Address read
dwLogBlockaddr = (bExtraBuffer[2] << 8) + bExtraBuffer[3];
//dwLogBlockaddr is 0xffff
if (dwLogBlockaddr == 0xffff)
{
//erase block and register block on wTmpLogBufer(FreeTable)
PhysicalErase((dwSegBlockAddr + dwPhyBlockAddr));
wTempLogBufer[wReAssignState] = (WORD) dwPhyBlockAddr;
wReAssignState++;
continue;
}
//logical address is out of predefined segment range
//note: segment number 0 is different to others
if (dwSegNum)
{
//if ((dwLogBlockaddr < ((dwSegNum - 1) * 496 + 494)) || (dwLogBlockaddr > (dwSegNum * 496 + 494)))
if ((dwLogBlockaddr < (dwLogAddrCheckValue - 496))
|| (dwLogBlockaddr > dwLogAddrCheckValue))
{
//erase block and register block on wTmpLogBufer(FreeTable)
if (sInfo.bWriteProtected != 1)
{
PhysicalErase((dwSegBlockAddr + dwPhyBlockAddr));
wTempLogBufer[wReAssignState] = (WORD) dwPhyBlockAddr;
wReAssignState++;
}
continue;
}
dwLogBlockaddr = (dwLogBlockaddr - 494) % 496;
}
else
{
if (dwLogBlockaddr > 493)
{
//erase block and register block on wTmpLogBufer(FreeTable)
if (sInfo.bWriteProtected != 1)
{
PhysicalErase((dwSegBlockAddr + dwPhyBlockAddr));
wTempLogBufer[wReAssignState] = (WORD) dwPhyBlockAddr;
wReAssignState++;
}
continue;
}
}
//Log2PhyTable(LPTable) is 0xffff
//Check if the same logical addr with others
pwCurLog2PhyTable = &pwLog2PhyTable[dwSegBlockAddr + dwLogBlockaddr];
if (*pwCurLog2PhyTable == 0xffff)
{
*pwCurLog2PhyTable = (WORD) dwPhyBlockAddr;
}
else
{
MP_DEBUG("compare update status of Log2PhyTable");
//compare update status of Log2PhyTable(LPTable) and dwPhyBlockAddr
ReadExtraData(*pwCurLog2PhyTable, 0, (DWORD) bTempBuffer);
// update status is different
if ((bTempBuffer[0] & 0x10) == (bExtraBuffer[0] & 0x10))
{
//Log2PhyTable(LPTable) > dwPhyBlockAddr
if (*pwCurLog2PhyTable > (WORD) dwPhyBlockAddr)
{
//erase block and register block on wTmpLogBufer(FreeTable)
PhysicalErase((dwSegBlockAddr + dwPhyBlockAddr));
wTempLogBufer[wReAssignState] = (WORD) dwPhyBlockAddr;
wReAssignState++;
}
else
{
//erase block and register block on wTmpLogBufer(FreeTable)
PhysicalErase(*pwCurLog2PhyTable);
wTempLogBufer[wReAssignState] = *pwCurLog2PhyTable;
wReAssignState++;
*pwCurLog2PhyTable = (WORD) dwPhyBlockAddr;
}
}
else
{
//update staus of block dwPhyBlockAddr is 0
if ((bExtraBuffer[0] & 0x10))
{
//erase block and register block on wTmpLogBufer(FreeTable)
if (sInfo.bWriteProtected != 1)
{
PhysicalErase((dwSegBlockAddr + dwPhyBlockAddr));
wTempLogBufer[wReAssignState] = (WORD) dwPhyBlockAddr;
wReAssignState++;
}
}
else
{
//erase block and register block on wTmpLogBufer(FreeTable)
PhysicalErase(*pwCurLog2PhyTable);
wTempLogBufer[wReAssignState] = *pwCurLog2PhyTable;
wReAssignState++;
*pwCurLog2PhyTable = (WORD) dwPhyBlockAddr;
}
}
}
}
//ver.1.00 spec A.9 Logical Address confirmation process
if (dwSegNum == (sInfo.dwSegment - 1))
{
if (wReAssignState < 2)
{
OsTempMemRelease(bTempMemID0);
sInfo.bWriteProtected = 1;
MP_DEBUG("write protect");
return PASS;
}
}
else
{
if (wReAssignState < 1)
{
OsTempMemRelease(bTempMemID0);
sInfo.bWriteProtected = 1;
MP_DEBUG("write protect");
return PASS;
}
}
//Insert free blaock address into Log2PhyTable
for (i = 0; i < MAXPHYBLOCK; i++)
{
if ((pwLog2PhyTable[dwSegBlockAddr + i] == 0xffff) && (wReAssignState != 0))
{
if (dwSegNum == 0)
{
if ((i == 494) || (i == 495))
{
continue;
}
}
if ((i < 496) && (!sInfo.bWriteProtected))
{
MP_DEBUG("Insert free blaock address into Log2PhyTable");
WriteExtraData((wTempLogBufer[wReAssignState - 1] + (dwSegBlockAddr)), 0,
(DWORD) (dwSegBlockAddr + i));
}
pwLog2PhyTable[dwSegBlockAddr + i] = wTempLogBufer[wReAssignState - 1];
wReAssignState--;
}
}
pwReAssignTable[dwSegNum] = 0;
MP_DEBUG1(" (dwSegNum: %d)", dwSegNum);
}
if ((sInfo.bWriteProtected == 1) && (sInfo.bProtectBlockCount != 0))
{
register WORD *pwTable = &sInfo.wProtectBlockTable[0];
for (i = 0; i < sInfo.bProtectBlockCount; i++)
{
pwLog2PhyTable[*pwTable] = i;
pwTable++;
}
}
OsTempMemRelease(bTempMemID0);
return PASS;
}
static SWORD CheckDisableBlock(register DWORD dwPhyAddr, register BYTE * pbDisableAddr)
{
register WORD wDisableCount, wDisableBlock;
wDisableCount = 0;
do
{
if (Polling_MS_Status())
return FAIL;
wDisableBlock =
(WORD) ((pbDisableAddr[wDisableCount] << 8) + pbDisableAddr[wDisableCount + 1]);
if (dwPhyAddr == wDisableBlock)
{
return FAIL;
}
wDisableCount += 2;
}
while (wDisableBlock != 0xffff);
return PASS;
}
static WORD GetEmptyBlock(DWORD dwSegNum)
{
WORD wBlankAddr;
WORD *pwLog2PhyTable, *pwReAssignTable;
pwLog2PhyTable = sInfo.wLog2PhyTable;
pwReAssignTable = sInfo.wReAssignTable;
wBlankAddr = pwLog2PhyTable[dwSegNum * MAXPHYBLOCK + pwReAssignTable[dwSegNum] + 496];
return wBlankAddr;
}
static WORD GetSameBlockPages(register DWORD dwLogAddr, register DWORD dwSectorCount)
{
register WORD wPage;
register DWORD dwPagePerBlock = sInfo.dwPagePerBlock;
wPage = dwLogAddr % dwPagePerBlock;
if (dwSectorCount > (dwPagePerBlock - wPage))
{
return (dwPagePerBlock - wPage);
}
else
{
return dwSectorCount;
}
}
static SWORD IdentifyType(void)
{
register SWORD swRetValue;
BYTE abTempBuf[6];
SetRWRegTpcAddr(0x02, 0x06, 0x10, 0x01); //Set R/W Register TPC Addr
if ((swRetValue = WriteTpcBs(TPC_SET_RW_REG_ADR, (BYTE *) & sRWRegTpcAddr, 4))) // SET_RW_REG_ADRS
{
return swRetValue;
}
// READ_REG
if ((swRetValue = ReadTpcBs(TPC_READ_REG, abTempBuf, 6)))
{
return swRetValue;
}
if (abTempBuf[2] == 0x00)
{
if (abTempBuf[4] >= 0x80)
{
MP_DEBUG("-E- ms type FAIL");
return FAIL;
}
else if ((abTempBuf[4] >= 0x01) && (abTempBuf[4] <= 0x7F))
{
MP_DEBUG("-I- ms i/o expanded m
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -