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

📄 sm.c

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

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