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

📄 sm_normal.c

📁 常见卡(SD,NAND,XD,MS,ATA,CF)完整DRIVER
💻 C
📖 第 1 页 / 共 5 页
字号:
	}
	else if(sInfo.bCurMode == INITIAL_XD){
				GpioValueSetting(0,XD_CE);
	}
	WaitReady();
//	McardIODelay(5);

	if (((sInfo.bCurMode == INITIAL_NAND) && (sInfo.sMediaMeat[sInfo.bCurMode]->wMaxSector == 0x100)) ||
		(sInfo.bCurMode == INITIAL_NAND) && (sInfo.sMediaMeat[sInfo.bCurMode]->wMaxSector == 0x200))
	{
		bTempMemID = OsTempMemAllocate();
		pbBuffer = (BYTE *) GetOsTempMemory(bTempMemID);
		for (wNum = 0; wNum < 512; wNum++)
		{
			*(pbBuffer + wNum) = 0;
		}		
		
		SetCommand(READ_PAGE1_CMD);
		SetAddress(dwSectorAddr, 0);
		SetCommand(READ_PAGE1_CMD_2CYC);
		if ((swRetValue = WaitReady()))
		{
			MP_DEBUG1("-E- Read Command FAIL (swRetValue: %d)", swRetValue);
			OsTempMemRelease(bTempMemID);
			return swRetValue;
		}
		if ((swRetValue = ReadSector((DWORD) pbBuffer, MCARD_SECTOR_SIZE)))
		{
			MP_DEBUG1("-E- DMA Read FAIL (swRetValue: %d)", swRetValue);
			OsTempMemRelease(bTempMemID);
			return swRetValue;
		}
		OsTempMemRelease(bTempMemID);

		for (wNum = 0; wNum < 16; wNum++)
		{
			bRedtData[wNum] = sMcard->McSmDat;
		}
	}
	else
	{
		SetCommand(READ_REDUNDANT_CMD);
		SetAddress(dwSectorAddr, 0);
		if ((swRetValue = WaitReady()))
		{
			return swRetValue;
		}

		for (wNum = 0; wNum < 16; wNum++)
		{
			bRedtData[wNum] = sMcard->McSmDat;
		}
	}
	sMcard->McSmC = 0x0;
	GpioValueSetting(1,NAND1_CE);
	GpioValueSetting(1,NAND2_CE);
	GpioValueSetting(1,XD_CE);
	return PASS;

}

static DWORD GetSameBlock(DWORD dwLogAddr, DWORD dwSectorCount)
{
	DWORD dwPage, dwCount;
	ST_MEDIA_MEAT *sMediaMeat;

	sMediaMeat = (ST_MEDIA_MEAT *) sInfo.sMediaMeat[sInfo.bCurMode];

	dwPage = dwLogAddr % sMediaMeat->wMaxSector;
	if (dwSectorCount > (sMediaMeat->wMaxSector - dwPage))
	{
		return (sMediaMeat->wMaxSector - dwPage);
	}
	return dwSectorCount;
}

static void Select(BYTE bMode)
{
	register GPIO *sGpio;

	sGpio = (GPIO *) (GPIO_BASE);
	sInfo.bCurMode = bMode;
	switch (bMode)
	{
#if SM_ENABLE
	case INITIAL_SM:
		sGpio->Fgpcfg[0] &= ~(GPIO_DEFINE_0_SM|(GPIO_DEFINE_0_SM<<16));		
		sGpio->Fgpcfg[0] |= GPIO_DEFINE_0_SM;
		sGpio->Fgpcfg[1] &= ~(GPIO_DEFINE_1_SM|(GPIO_DEFINE_1_SM<<16));		
		sGpio->Fgpcfg[1] |= GPIO_DEFINE_1_SM;
		sGpio->Fgpcfg[2] &= ~(GPIO_DEFINE_2_SM|(GPIO_DEFINE_2_SM<<16));		
		sGpio->Fgpcfg[2] |= GPIO_DEFINE_2_SM;
		sGpio->Fgpcfg[3] &= ~(GPIO_DEFINE_3_SM|(GPIO_DEFINE_3_SM<<16));		
		sGpio->Fgpcfg[3] |= GPIO_DEFINE_3_SM;
		sInfo.dwCurModeSetting = SETTING_SM;
		sInfo.dwReadTiming = READ_TIMING_SM;
		sInfo.dwWriteTiming = WRITE_TIMING_SM;
//		MP_DEBUG("-I- initial SM");
		break;
#endif
	case INITIAL_NAND:
		sGpio->Fgpcfg[0] &= ~(GPIO_DEFINE_0_NAND|(GPIO_DEFINE_0_NAND<<16));		
		sGpio->Fgpcfg[0] |= GPIO_DEFINE_0_SM;
		sGpio->Fgpcfg[1] &= ~(GPIO_DEFINE_1_NAND|(GPIO_DEFINE_1_NAND<<16));		
		sGpio->Fgpcfg[1] |= GPIO_DEFINE_1_NAND;
		sGpio->Fgpcfg[2] &= ~(GPIO_DEFINE_2_NAND|(GPIO_DEFINE_2_NAND<<16));		
		sGpio->Fgpcfg[2] |= GPIO_DEFINE_2_NAND;
		sGpio->Fgpcfg[3] &= ~(GPIO_DEFINE_3_NAND|(GPIO_DEFINE_3_NAND<<16));		
		sGpio->Fgpcfg[3] |= GPIO_DEFINE_3_NAND;
//		sGpio->Fgpcfg[1] &= ~0x00010001;		
		GpioValueSetting(1,XD_CE);
		GpioValueSetting(1,NAND1_CE);
		GpioValueSetting(1,NAND2_CE);
		
		GpioValueSetting(1,NAND_WP);//SetNandWPHigh();
		sInfo.dwCurModeSetting = SETTING_NAND;
		sInfo.dwReadTiming = READ_TIMING_NAND;
		sInfo.dwWriteTiming = WRITE_TIMING_NAND;
//		MP_DEBUG("-I- initial NAND");
		break;

	case INITIAL_XD:

		sGpio->Fgpcfg[0] &= ~(GPIO_DEFINE_0_XD|(GPIO_DEFINE_0_XD<<16));		
		sGpio->Fgpcfg[0] |= GPIO_DEFINE_0_XD;
		sGpio->Fgpcfg[1] &= ~(GPIO_DEFINE_1_XD|(GPIO_DEFINE_1_XD<<16));		
		sGpio->Fgpcfg[1] |= GPIO_DEFINE_1_XD;
		sGpio->Fgpcfg[2] &= ~(GPIO_DEFINE_2_XD|(GPIO_DEFINE_2_XD<<16));		
		sGpio->Fgpcfg[2] |= GPIO_DEFINE_2_XD;
		sGpio->Fgpcfg[3] &= ~(GPIO_DEFINE_3_XD|(GPIO_DEFINE_3_XD<<16));		
		sGpio->Fgpcfg[3] |= GPIO_DEFINE_3_XD;

		
		sGpio->Fgpcfg[1] &= ~0x00010001;		
		sGpio->Fgpdat[1] &= ~0x00010000;				
		GpioValueSetting(1,XD_CE);
		GpioValueSetting(1,NAND1_CE);
		GpioValueSetting(1,NAND2_CE);

 #if ((CHIP_VER & 0xffff0000) == CHIP_VER_600)
		GpioValueSetting(1,XD_WP);
 #else
		GpioValueSetting(0,XD_WP);
		GpioValueSetting(0,XD_VCC);	
		McardIODelay(10);		
		GpioValueSetting(1,XD_WP);
#endif
		sInfo.dwCurModeSetting = SETTING_XD;
		sInfo.dwReadTiming = READ_TIMING_XD;
		sInfo.dwWriteTiming = WRITE_TIMING_XD;
//		MP_DEBUG("-I- initial XD");
		break;
	}
}

static void DeSelect(void)
{
#if 1
	register GPIO *sGpio;
	register MCARD *sMcard;

	sMcard = (MCARD *) (MCARD_BASE);
	sGpio = (GPIO *) (GPIO_BASE);
	switch (sInfo.bCurMode)
	{
	case INITIAL_SM:
		sGpio->Fgpcfg[0] &= ~GPIO_DEFINE_0_SM;
		sGpio->Fgpcfg[1] &= ~GPIO_DEFINE_1_SM;
		sGpio->Fgpcfg[2] &= ~GPIO_DEFINE_2_SM;
		sGpio->Fgpcfg[3] &= ~GPIO_DEFINE_3_SM;
		break;

	case INITIAL_NAND:
		sGpio->Fgpcfg[0] &= ~GPIO_DEFINE_0_NAND;
		sGpio->Fgpcfg[0] &= ~(GPIO_DEFINE_0_NAND<<16);		
		sGpio->Fgpdat[0] &= ~(GPIO_DEFINE_0_NAND);
		sGpio->Fgpdat[0] &= ~(GPIO_DEFINE_0_NAND<<16);
		sGpio->Fgpcfg[1] &= ~GPIO_DEFINE_1_NAND;
		sGpio->Fgpcfg[0] &= ~(GPIO_DEFINE_1_NAND <<16);		
		sGpio->Fgpdat[1] &= ~(GPIO_DEFINE_1_NAND<<16);
		sGpio->Fgpcfg[2] &= ~GPIO_DEFINE_2_NAND;
		sGpio->Fgpcfg[2] &= ~(GPIO_DEFINE_2_NAND <<16);		
		sGpio->Fgpdat[2] &= ~(GPIO_DEFINE_2_NAND<<16);		
		sGpio->Fgpcfg[3] &= ~GPIO_DEFINE_3_NAND;
		sGpio->Fgpcfg[3] &= ~(GPIO_DEFINE_3_NAND <<16);		
		sGpio->Fgpdat[3] &= ~(GPIO_DEFINE_3_NAND<<16);		
		GpioValueSetting(0,NAND_CLE);
		break;

	case INITIAL_XD:
//		sGpio->Gpdat1 &= ~0x01000100;	//simulate XD writeable pin           
		sGpio->Fgpcfg[0] &= ~GPIO_DEFINE_0_XD;
		sGpio->Fgpcfg[1] &= ~GPIO_DEFINE_1_XD;
		sGpio->Fgpcfg[2] &= ~GPIO_DEFINE_2_XD;
		sGpio->Fgpcfg[3] &= ~GPIO_DEFINE_3_XD;
		break;

	}
	sMcard->McardC &= ~MCARD_ENABLE;
#endif
}
static BYTE GetWPFlag(void)
{
	register GPIO *sGpio;
	sGpio = (GPIO *) (GPIO_BASE);
	if (sInfo.bCurMode == INITIAL_SM)
	{
		#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600)	
			return ((sGpio->Fgpdat[0] & 0x00008000) ? 0 : 1);// 600 nand wp gpio 15
		#else
		return ((sGpio->Fgpdat[3] & 0x00000040) ? 0 : 1);// nand wp gpio 54
		#endif	
	}
	else if (sInfo.bCurMode == INITIAL_XD)
	{
		#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600)
			return ((sGpio->Fgpdat[0] & 0x00008000) ? 0 : 1);// 600 xd wp gpio 15
	 	#else
			return ((sGpio->Fgpdat[3] & 0x00000400) ? 0 : 1); // xd wp gpio 58
        #endif
	}
	return 0;
}

static void SetCommand(BYTE bCommand)
{
	register MCARD *sMcard;

	sMcard = (MCARD *) (MCARD_BASE);
	if(sInfo.bCurMode == INITIAL_NAND){
		GpioValueSetting(1,NAND_CLE);
		}
	else if(sInfo.bCurMode == INITIAL_XD){
		GpioValueSetting(1,XD_CLE);
	}	

	*((BYTE *) (&sMcard->McSmDat)) = bCommand;
	if(sInfo.bCurMode == INITIAL_NAND){
		GpioValueSetting(0,NAND_CLE);
		}
	else if(sInfo.bCurMode == INITIAL_XD){
		GpioValueSetting(0,XD_CLE);
	}		

}

static SWORD Identify(DWORD * pdwTotalSector)
{
	register MCARD *sMcard;
	ST_MEDIA_MEAT_TABLE *sMediaMeatTable;
	SWORD swRetValue;
	BYTE bIDBuffer[4],DieNum,i;
	DWORD TotalSector;
	TotalSector = *pdwTotalSector;
	sMcard = (MCARD *) (MCARD_BASE);
	SetControl();
	WaitReady();

	if(sInfo.bCurMode == INITIAL_NAND)
	{
		GpioValueSetting(0,NAND1_CE);
	}
	if(sInfo.bCurMode == INITIAL_XD)
	{
		GpioValueSetting(0,XD_CE);
	}	
	SetCommand(READ_ID_CMD);

	if(sInfo.bCurMode == INITIAL_NAND){
		GpioValueSetting(1,NAND_ALE);	
		}
	else if(sInfo.bCurMode == INITIAL_XD){
		GpioValueSetting(1,XD_ALE);	
	}
	sMcard->McSmDat = 0x00;
	if(sInfo.bCurMode == INITIAL_NAND){
		GpioValueSetting(0,NAND_ALE);
		}
	else if(sInfo.bCurMode == INITIAL_XD){
		GpioValueSetting(0,XD_ALE);
	}	
	WaitReady();
	bIDBuffer[0] = sMcard->McSmDat;
	bIDBuffer[1] = sMcard->McSmDat;
	bIDBuffer[2] = sMcard->McSmDat;
	bIDBuffer[3] = sMcard->McSmDat;
	if(sInfo.bCurMode == INITIAL_NAND)
	{
			DieNum = bIDBuffer[2] & 0x03;
			if(DieNum > 0)
				MultiDieFlag |= MultiDie;
			if((bIDBuffer[2] & 0x0c) == 0x04){
				MLC =TRUE;
				MP_DEBUG("MLC type nand");
			}
	}
	sMcard->McSmC = 0x0;
	GpioValueSetting(1,XD_CE);
	GpioValueSetting(1,NAND1_CE);	
	GpioValueSetting(1,NAND2_CE);		
	MP_DEBUG4("-I- identify SM card Maker %x and Device code %x,3RD code %x , 4TH code %x", bIDBuffer[0], bIDBuffer[1],bIDBuffer[2],bIDBuffer[3]);

	swRetValue = TYPE_NOT_SUPPORT;
	for (sMediaMeatTable = (ST_MEDIA_MEAT_TABLE *) sMediaMeatTable_S; sMediaMeatTable->bID != 0;
		 sMediaMeatTable++)
	{
		if (sMediaMeatTable->bID == bIDBuffer[1])
		{
			sInfo.sMediaMeat[sInfo.bCurMode] = &sMediaMeatTable->sMediaMeat;
			SetAddrInfo(0);
			swRetValue = PASS;
			break;
		}
	}

	if (sInfo.bCurMode != INITIAL_XD)
	{
		// swRetValue = TYPE_NOT_SUPPORT;  // for NAND      
		for (sMediaMeatTable = (ST_MEDIA_MEAT_TABLE *) sMediaMeatTable_B; sMediaMeatTable->bID != 0;
			 sMediaMeatTable++)
		{
			if (sMediaMeatTable->bID == bIDBuffer[1])
			{
				sInfo.sMediaMeat[sInfo.bCurMode] = &sMediaMeatTable->sMediaMeat;
				SetAddrInfo(1);
				swRetValue = PASS;
				break;
			}
		}
	}
	
	// 20070601 abel add, if size <= 64MB, no MLC or MultiDie 
	if(sInfo.bCurMode == INITIAL_NAND)
	{
		if((sInfo.sMediaMeat[INITIAL_NAND]->bMaxZone <= 4)
			&& (sInfo.sMediaMeat[INITIAL_NAND]->wMaxSector <= 0x20))
		{
			MLC = FALSE;
			MultiDieFlag &= ~MultiDie;
		}
	}	
	
	if ((MLC == TRUE)	&& (sInfo.bCurMode == INITIAL_NAND))
	{
		 swRetValue = TYPE_NOT_SUPPORT;  // for NAND      
		#if (CHIP_VER  == (CHIP_VER_600 | CHIP_VER_B))
		for (sMediaMeatTable = (ST_MEDIA_MEAT_TABLE *) sMediaMeatTable_MLC; sMediaMeatTable->bID != 0;
			 sMediaMeatTable++)
		{
			if (sMediaMeatTable->bID == bIDBuffer[1])
			{
				sInfo.sMediaMeat[sInfo.bCurMode] = &sMediaMeatTable->sMediaMeat;
				SetAddrInfo(1);
				swRetValue = PASS;
				break;
			}
		}
		#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;	
}

⌨️ 快捷键说明

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