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

📄 sm.c

📁 常见卡(SD,NAND,XD,MS,ATA,CF)完整DRIVER
💻 C
📖 第 1 页 / 共 5 页
字号:
		else if((sMcard->McEcc4SState & MC_ECC4S_STATE_STATE_MASK) == DECODE_CORRECTION_IMPOSSIBLE)
		{
			//MP_DEBUG("ECC4S_Decode_Check correction impossible");
			return DECODE_CORRECT_IMPOSSIBLE;
		}
		if(dwCounter == 0)
		{
			MP_DEBUG("ECC4S_Decode_Check time out");
			return DECODE_CHECK_TIMEOUT;
		}
		dwCounter--;
	}
				//MP_DEBUG("ECC4S_Decode_Check no error");
	return NO_ERROR;


}
static SWORD ECC4S_Encode_Check(void)
{
	register MCARD * sMcard = (MCARD *)MCARD_BASE;
	SWORD dwRetValue;
	DWORD dwCounter = 0x1000;
	while((sMcard->McEcc4SState & MC_ECC4S_STATE_STATE_MASK) != ENCODE_NORMAL_COMPLETION)
	{
		if(dwCounter == 0)
		{
			MP_DEBUG("ECC4S_Encode_Check time out");		
			return -1;
		}
		dwCounter--;
	}
	return ENCODE_COMPLETION;

}
#endif
SWORD ECC_Check(void)
{
	register MCARD * sMcard = (MCARD *)MCARD_BASE;
	bECCCode[0] = ((sMcard->McSmEcc1 >> 16) & 0xff);
	bECCCode[1] = ((sMcard->McSmEcc1 >> 8) & 0xff);
	bECCCode[2] = (sMcard->McSmEcc1  & 0xff);
	if((bRedtData[13] != bECCCode[2]) ||(bRedtData[14] != bECCCode[1]) ||(bRedtData[15] != bECCCode[0]))
	{
		MP_DEBUG("ECC-Field 1 Error !!");
		return FAIL;
	}
	bECCCode[0] = ((sMcard->McSmEcc2 >> 16) & 0xff);
	bECCCode[1] = ((sMcard->McSmEcc2 >> 8) & 0xff);
	bECCCode[2] = (sMcard->McSmEcc2  & 0xff);	
	if((bRedtData[8] != bECCCode[2]) ||(bRedtData[9] != bECCCode[1]) ||(bRedtData[10] != bECCCode[0]))
	{
		MP_DEBUG("ECC-Field 2 Error !!");
		return FAIL;
	}
	return PASS;

}
void GpioValueSetting(BYTE value,BYTE num )
{
	GPIO * sGpio = (GPIO *) GPIO_BASE;
	DWORD dwCfg;
	BYTE m,n;
	dwCfg = 0;
	m = num /16;
	n = num %16;
	dwCfg =((1<<(16+n))|(1<<n));

	sGpio->Fgpcfg[m] &= ~dwCfg;
	sGpio->Fgpdat[m] |=(dwCfg & 0xffff0000);
	if(value)
		sGpio->Fgpdat[m] |=(dwCfg & 0x0000ffff);
	else
		sGpio->Fgpdat[m] &=~(dwCfg & 0x0000ffff);		
	
}
BOOL GetGpioValue(BYTE num )
{
	GPIO * sGpio = (GPIO *) GPIO_BASE;
	DWORD dwCfg;
	BYTE m,n;
	dwCfg = 0;
	m = num /16;
	n = num %16;
	dwCfg =((1<<(16+n))|(1<<n));

	sGpio->Fgpcfg[m] &= ~dwCfg;
	sGpio->Fgpdat[m] &= ~(dwCfg & 0xffff0000);
	return (sGpio->Fgpdat[m] &(dwCfg & 0x0000ffff) >> n);
	
}
void SmInit(ST_MCARD_DEV * sDev, BYTE bType)
{
	switch (bType)
	{
	case NAND:
		sDev->pbDescriptor = bDescriptor[0];
		sDev->dwLunNum = NAND_LUN_NUM;
		break;
#if SM_ENABLE
	case SM:
		sDev->pbDescriptor = bDescriptor[1];
		sDev->dwLunNum = SM_LUN_NUM;
		break;
#endif
	case XD:
		sDev->pbDescriptor = bDescriptor[1];
		sDev->dwLunNum = XD_LUN_NUM;
		break;
	}
	sDev->wMcardType = bType;
	sDev->Flag.Installed = 1;
	sDev->CommandProcess = CommandProcess;
}

/*
// Definition of local functions 
*/
//#define BYTE_MODE
static void CommandProcess(void *pMcardDev)
{
	ST_MCARD_MAIL *sMcardRMail;
	register ST_MCARD_DEV *pDev = ((ST_MCARD_DEV *) pMcardDev);
	ST_MEDIA_MEAT *sMediaMeat;
	BYTE bStartZone,bEndZone;

	McardSetClock(SM_CLOCK);
	sMcardRMail = pDev->sMcardRMail; 
		if (pDev->wMcardType == NAND)
		{
			MP_DEBUG("Nand");
//#ifndef NOR
//			Select(INITIAL_NAND);//rick1115
//#else
			sInfo.bCurMode = INITIAL_NAND;
//#endif			

		}
#if SM_ENABLE
		else if (pDev->wMcardType == SM)
		{
			Select(INITIAL_SM);

		}
#endif
		else if (pDev->wMcardType == XD)
		{
			Select(INITIAL_XD);
		}
		else
		{
			return;
		}
	switch (sMcardRMail->wCmd)
	{
	case INIT_CARD_CMD:
		if (pDev->wMcardType == SM)
			pDev->Flag.Detected = Ui_CheckSmPlugIn();
            else if (pDev->wMcardType == XD)
			pDev->Flag.Detected = Ui_CheckXdPlugIn();
		else
			pDev->Flag.Detected = 1;	//needcheck
		if (1)//(pDev->Flag.Detected)   // along
		{
			//card in
			McardIODelay(0x500);
			pDev->Flag.Detected = 1;
//#ifdef NOR
			if(sInfo.bCurMode == INITIAL_NAND)
			{
				WORD deviceCode;
				GetDeviceCode(&deviceCode);
				NewFlashRep(&flashRep, deviceCode & 0xFF);
				pDev->dwCapacity = 4096;//unit : lba
				pDev->wRenewCounter++;
				pDev->Flag.ReadOnly = 0;
				pDev->Flag.Present = 1;			
			}
			else
//#else
		   {	
			if (((pDev->swStatus = Identify(&pDev->dwCapacity))))
			{
				//pDev->Flag.Detected = 0;
				pDev->Flag.Present = 0;
				pDev->dwCapacity = 0;
				pDev->wSectorSize = 0;
				if (pDev->wMcardType != NAND)
				{
					McardSetCurLun(pDev->dwLunNum, NULL_DEVICE);
				}
			}
			else
			{
				sMediaMeat = (ST_MEDIA_MEAT *) sInfo.sMediaMeat[sInfo.bCurMode];			
				pDev->wSectorSize = MCARD_SECTOR_SIZE;
				if(sInfo.bCurMode == INITIAL_NAND)
				{
					bStartZone = 0;
					bEndZone = sMediaMeat->bMaxZone;
				}
				else if(sInfo.bCurMode == INITIAL_XD)
				{
					bStartZone = 0;
					bEndZone = XD_STA_ZONE;
					sInfo.dwXdCurZone = (DWORD)bStartZone;	
                                   #if LCD_PANEL_480_234
                                   	{
					BYTE i;
					for(i=0;i<200;i++)// roger add it to wait if MS in and it can be checked by uiTASK, the timing need check
						TaskYield();
                                   	}
					if( !Ui_CheckMsPlugIn() )
                                   	{
						mpDebugPrint("!Ui_CheckMsPlugIn() ");
				       SetGPIOValue(GPIO_XD_VCC, 0);
                                   	}
                                   #endif	
				}
				if (pDev->swStatus = Log2PhyTabInit(bStartZone,bEndZone))
				{
					MP_DEBUG("Log2PhyTabInit fail");
					pDev->Flag.Present = 0;
					pDev->dwCapacity = 0;
					pDev->wSectorSize = 0;
					if (pDev->wMcardType != NAND)
					{
						McardSetCurLun(pDev->dwLunNum, NULL_DEVICE);
					}
				}
				else
				{
					MP_DEBUG("Log2PhyTabInit pass");
					pDev->wRenewCounter++;
					pDev->Flag.ReadOnly = GetWPFlag();
					pDev->Flag.Present = 1;
					if (pDev->wMcardType != NAND)
					{
						McardSetCurLun(pDev->dwLunNum, pDev->wMcardType);
					}
					//EventSet(UI_EVENT, EVENT_CARD_INIT);                  
				}
			   }
		   	}
//#endif		
		}
		else
		{
			//card out

	 		#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600)

 			#else
				GpioValueSetting(1,XD_WP);
				GpioValueSetting(1,XD_VCC);	
				McardIODelay(10);		
				GpioValueSetting(0,XD_WP);
			#endif

			pDev->Flag.Detected = 0;
			pDev->Flag.Present = 0;
			pDev->Flag.ReadOnly = 0;
			pDev->Flag.PipeEnable = 0;
			pDev->swStatus = 0;
			pDev->dwCapacity = 0;
			pDev->wSectorSize = 0;
			McardSetCurLun(pDev->dwLunNum, NULL_DEVICE);
			//EventSet(UI_EVENT, EVENT_CARD_INIT);                  
		}
		break;
	case REMOVE_CARD_CMD:		//Athena 03.11.2006 seperate card in & out
		//card out
		pDev->Flag.Detected = 0;
		pDev->Flag.Present = 0;
		pDev->Flag.ReadOnly = 0;
		pDev->Flag.PipeEnable = 0;
		pDev->swStatus = 0;
		pDev->dwCapacity = 0;
		pDev->wSectorSize = 0;
		McardSetCurLun(pDev->dwLunNum, NULL_DEVICE);

            	if (pDev->wMcardType == XD) {		
			GpioValueSetting(0,XD_WP);
                     #if LCD_PANEL_480_234
		       SetGPIOValue(GPIO_XD_VCC, 1);
                    #endif	
            	 }
 		#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600)

		#else
			GpioValueSetting(1,XD_VCC);	
		#endif

		PreSMType = 0;

		break;
	case READ_PAGE_CMD:
		pDev->swStatus =
			FlatRead(sMcardRMail->dwBuffer, sMcardRMail->dwBlockCount, sMcardRMail->dwBlockAddr);
		break;

	case WRITE_PAGE_CMD:
		pDev->swStatus =
			FlatWrite(sMcardRMail->dwBuffer, sMcardRMail->dwBlockCount, sMcardRMail->dwBlockAddr);
		break;

	case FORMAT_CMD:
		pDev->swStatus = Format();
		break;

	default:
		MP_DEBUG("-E- INVALID CMD");
		break;
	}
	DeSelect();
//	PreSMType = pDev->wMcardType;
}

//static SWORD Log2PhyTabInit(void)
static SWORD Log2PhyTabInit(BYTE bStartZone,BYTE bEndZone)
{
	ST_MEDIA_MEAT *sMediaMeat;
	DWORD dwCurAddr;
	SWORD swRetValue;
	WORD wLogBlockAddr, wZoneNum, wReassignState, i, wCurPhyBlock, wLogBlock, wPhyBlock, wTemp;
	WORD *pwLog2PhyTable;
	BYTE *pReAssignTable;
	DWORD dwBase;
	sMediaMeat = (ST_MEDIA_MEAT *) sInfo.sMediaMeat[sInfo.bCurMode];
//	pwLog2PhyTable = (WORD *) sInfo.wLog2PhyTable[sInfo.bCurMode];
	if(sInfo.bCurMode == INITIAL_NAND)
		pwLog2PhyTable = (WORD *) sInfo.wNandLog2PhyTable;
	else if((sInfo.bCurMode == INITIAL_XD) &&(bStartZone>= XD_STA_ZONE))
		pwLog2PhyTable = (WORD *) sInfo.wXdDLog2PhyTable;
	else if((sInfo.bCurMode == INITIAL_XD) &&(bStartZone < XD_STA_ZONE))
		pwLog2PhyTable = (WORD *) sInfo.wXdSLog2PhyTable;

	pReAssignTable = (BYTE *) sInfo.bReAssignTable[sInfo.bCurMode];
	BYTE *bTempBuffer = (BYTE *)mem_malloc(0x40000);
	for (wZoneNum = bStartZone; wZoneNum < bEndZone; wZoneNum++)
	{
		if(sInfo.bCurMode == INITIAL_NAND)
			dwBase = wZoneNum*MAX_BLOCK;
		else if(sInfo.bCurMode == INITIAL_XD)
			dwBase = (wZoneNum-bStartZone)*MAX_BLOCK;
		wReassignState = 0;
		for (i = 0; i < MAX_BLOCK; i++)
		{
			pwLog2PhyTable[dwBase + i] = 0xffff;
			bTempBuffer[(i << 1)] = 0xff;
			bTempBuffer[(i << 1) + 1] = 0xff;
		}
		dwCurAddr = wZoneNum * sMediaMeat->wMaxBlock * sMediaMeat->wMaxSector;
		for (wCurPhyBlock = 0; wCurPhyBlock < sMediaMeat->wMaxBlock; wCurPhyBlock++)
		{
			if ((swRetValue = ReadRedtData(dwCurAddr)))
			{
				mem_free(bTempBuffer);
				MP_DEBUG1("-E- ReadRedtData FAIL (swRetValue: %d)", swRetValue);
				return swRetValue;
			}
			dwCurAddr += sMediaMeat->wMaxSector;
			if (CheckBlockStatus())
			{
				if (bRedtData[0] == 0x00)
				{
					bTempBuffer[wReassignState * 2] = (BYTE) (wCurPhyBlock >> 8);
					bTempBuffer[wReassignState * 2 + 1] = (BYTE) wCurPhyBlock;
					wReassignState++;
				}
				MP_DEBUG1("%d is bad block",(dwCurAddr/sMediaMeat->wMaxSector));
				continue;
			}

			if (LoadLogBlockAddr(&wLogBlockAddr))
			{
				continue;
			}

			if (wLogBlockAddr >= sMediaMeat->wMaxLogBlock)
			{
				bTempBuffer[wReassignState * 2] = (BYTE) (wCurPhyBlock >> 8);
				bTempBuffer[wReassignState * 2 + 1] = (BYTE) wCurPhyBlock;
				wReassignState++;
			}
			else
			{
//				if (pwLog2PhyTable[wZoneNum * MAX_BLOCK + wLogBlockAddr] == 0xffff)
				if (pwLog2PhyTable[dwBase + wLogBlockAddr] == 0xffff)
				{
//					pwLog2PhyTable[wZoneNum * MAX_BLOCK + wLogBlockAddr] = wCurPhyBlock;
					pwLog2PhyTable[dwBase + wLogBlockAddr] = wCurPhyBlock;
				}
				else
				{
					wLogBlock = wLogBlockAddr;
					if ((swRetValue = ReadRedtData(dwCurAddr - 1)))
					{
						mem_free(bTempBuffer);
						MP_DEBUG1("-E- ReadRedtData FAIL (swRetValue: %d)", swRetValue);
						return swRetValue;
					}
					if (!LoadLogBlockAddr(&wLogBlockAddr))
					{
						if (wLogBlockAddr == wLogBlock)
						{
//							wPhyBlock = pwLog2PhyTable[wZoneNum * MAX_BLOCK + wLogBlockAddr];
//							pwLog2PhyTable[wZoneNum * MAX_BLOCK + wLogBlockAddr] = wCurPhyBlock;
							wPhyBlock = pwLog2PhyTable[dwBase + wLogBlockAddr];
							pwLog2PhyTable[dwBase + wLogBlockAddr] = wCurPhyBlock;
							bTempBuffer[wReassignState * 2] = (BYTE) (wPhyBlock >> 8);
							bTempBuffer[wReassignState * 2 + 1] = (BYTE) wPhyBlock;
							wReassignState++;
						}
						else
						{
							bTempBuffer[wReassignState * 2] = (BYTE) (wCurPhyBlock >> 8);
							bTempBuffer[wReassignState * 2 + 1] = (BYTE) wCurPhyBlock;
							wReassignState++;
						}
					}
					else
					{
						bTempBuffer[wReassignState * 2] = (BYTE) (wCurPhyBlock >> 8);
						bTempBuffer[wReassignState * 2 + 1] = (BYTE) wCurPhyBlock;
						wReassignState++;
					}
				}
			}
		}

		for (i = 0; i < sMediaMeat->wMaxLogBlock; i++)
		{
//			if ((pwLog2PhyTable[wZoneNum * MAX_BLOCK + i] == 0xffff) && (wReassignState != 0))
			if ((pwLog2PhyTable[dwBase + i] == 0xffff) && (wReassignState != 0))
			{
				wTemp = bTempBuffer[wReassignState * 2 - 2];
				wTemp = (wTemp << 8) + bTempBuffer[wReassignState * 2 - 1];
//				pwLog2PhyTable[wZoneNum * MAX_BLOCK + i] = wTemp;
				pwLog2PhyTable[dwBase + i] = wTemp;
				wReassignState--;
			}
		}

		for (i = 0; i < 16; i++)
		{
			if (wReassignState != 0)
			{
				wTemp = bTempBuffer[wReassignState * 2 - 2];
				wTemp = (wTemp << 8) + bTempBuffer[wReassignState * 2 - 1];
//				pwLog2PhyTable[wZoneNum * MAX_BLOCK + MAX_LOGBLOCK + i] = wTemp;
				pwLog2PhyTable[dwBase + MAX_LOGBLOCK + i] = wTemp;
				wReassignState--;
			}
		}

		// Check if more than 24 bad block          
		pReAssignTable[wZoneNum] = 0;
		if (GetEmptyBlock((wZoneNum-sInfo.dwXdCurZone),wZoneNum,pwLog2PhyTable) == 0xffff)
		{
			mem_free(bTempBuffer);
			MP_DEBUG("-E- Get Empty Block Address FAIL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -