⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ms.c

📁 常见卡(SD,NAND,XD,MS,ATA,CF)完整DRIVER
💻 C
📖 第 1 页 / 共 5 页
字号:
		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 + -