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

📄 sm.c

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