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

📄 sm_normal.c

📁 常见卡(SD,NAND,XD,MS,ATA,CF)完整DRIVER
💻 C
📖 第 1 页 / 共 5 页
字号:


//==========================================================================
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 + -