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

📄 sd.c

📁 常见卡(SD,NAND,XD,MS,ATA,CF)完整DRIVER
💻 C
📖 第 1 页 / 共 4 页
字号:
{
	ST_MCARD_MAIL *sMcardRMail;
	register ST_MCARD_DEV *pDev = ((ST_MCARD_DEV *) pMcardDev);

	sMcardRMail = pDev->sMcardRMail;	
	McardSetClock(sInfo.dwClock);
	Select();
	switch (sMcardRMail->wCmd)
	{
	case INIT_CARD_CMD:
		pDev->Flag.Detected = Ui_CheckSdPlugIn();
		if (pDev->Flag.Detected)
		{
			MP_DEBUG("-I- SD Cardin & Detected");
			//card in
			sInfo.bInitFlag = FALSE;
			sInfo.dwCardTag = MCARD_DMA_SD;
			sInfo.dwBusWidth = DBUS_1BIT;
			sInfo.dwClock = dwINITIAL_CLOCK;
			McardSetClock(sInfo.dwClock);
			pDev->Flag.Detected = 1;	
            		MP_DEBUG("-I- SD GoTransferMode");
			if ((pDev->swStatus = GoTransferMode()))
			{
				//pDev->Flag.Detected = 0;
				pDev->Flag.Present = 0;
				pDev->dwCapacity = 0;
				pDev->wSectorSize = 0;
				McardSetCurLun(pDev->dwLunNum, NULL_DEVICE);
			}
			else
			{
			    	MP_DEBUG("-I- SD GoTransferMode out");										
				pDev->wRenewCounter++;
				pDev->Flag.ReadOnly = GetWPFlag();
				pDev->Flag.Present = 1;
				pDev->dwCapacity = sInfo.dwCapacity;
				pDev->wSectorSize = MCARD_SECTOR_SIZE;
				McardSetCurLun(pDev->dwLunNum, pDev->wMcardType);
				//EventSet(UI_EVENT, EVENT_CARD_INIT);                                
			}
		            MP_DEBUG("-I- SD init cmd pass");
		}
		else if (!(pDev->Flag.Detected))
		{
			//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);
			//EventSet(UI_EVENT, EVENT_CARD_INIT);            
		}
		break;
	case REMOVE_CARD_CMD:		//Athena 03.11.2006 seperate card in & out
	MP_DEBUG("sd remove");
		//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);
		McardIODelay(2000); // solve cf command fail when mmc plug out
		//EventSet(UI_EVENT, EVENT_CARD_INIT);
		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();
}

static void DeSelect(void)
{
	register MCARD *sMcard;

	sMcard = (MCARD *) (MCARD_BASE);
//	sMcard->McardC = 0;
	register GPIO *sGpio;
	sGpio = (GPIO *) (GPIO_BASE);

	#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600 )
		#if((CHIP_VER & 0x0000ffff) == CHIP_VER_A)
    				sGpio->Fgpcfg[0] &= ~0x02000200;
				sGpio->Fgpdat[0] |= 0x00200020;// gpio 9 clk   
		#elif(((CHIP_VER & 0x0000ffff) == CHIP_VER_B)||((CHIP_VER & 0x0000ffff) == CHIP_VER_C))
			#if((STD_BOARD_VER == MP600PQFP_8M_SDRAM)||(STD_BOARD_VER == MP600_128PQFP_CPU_8M_SDRAM))
 				sGpio->Fgpcfg[0] &= ~0x02000200;
				sGpio->Fgpdat[0] |= 0x00200020;// gpio 9 clk   
			#else
 				sGpio->Fgpcfg[1] &= ~0x00200020;
				sGpio->Fgpdat[1] |= 0x00200020;// gpio 21 clk
			#endif
		#endif
    	#else 
 		sGpio->Fgpcfg[2] &= ~0x40004000;
		sGpio->Fgpdat[2] |= 0x40004000; // gpio 46 clk 
	#endif

}
static void DeSelectData(void)//
{
	register GPIO *sGpio;
	sGpio = (GPIO *) (GPIO_BASE);
	sGpio->Fgpcfg[0] &= ~0x00ff00ff;
	sGpio->Fgpdat[0] &= ~0x00ff00ff;	
}
static void Select(void)
{
	register MCARD *sMcard;
	register GPIO *sGpio;

	sGpio = (GPIO *) (GPIO_BASE);
	sMcard = (MCARD *) (MCARD_BASE);
	#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600 )
		#if((CHIP_VER & 0x0000ffff) == CHIP_VER_A)
    			sGpio->Fgpcfg[0] |= 0x0000830f; // FGPIO[0] ~[3] : D0 ~D3, FGPIO[8],[9],[15] : CMD ,CLK,WP
			sGpio->Fgpcfg[1] |= 0x00000004; //FGPIO[18] : CD 
		#elif(((CHIP_VER & 0x0000ffff) == CHIP_VER_B)||((CHIP_VER & 0x0000ffff) == CHIP_VER_C))	
			#if((STD_BOARD_VER == MP600PQFP_8M_SDRAM)||(STD_BOARD_VER == MP600_128PQFP_CPU_8M_SDRAM))
    			sGpio->Fgpcfg[0] |= 0x0000830f; // FGPIO[0] ~[3] : D0 ~D3, FGPIO[8],[9],[15] : CMD ,CLK,WP
			sGpio->Fgpcfg[1] |= 0x00000004; //FGPIO[18] : CD 
			#else
    			sGpio->Fgpcfg[0] |= 0x0000010f; // FGPIO[0] ~[7] : D0 ~D7, FGPIO[8]: CMD 
			sGpio->Fgpcfg[1] |= 0x00000024; //FGPIO[18] : CD , FGPIO[21] : CLK
			sGpio->Agpcfg &= ~ 0x00000010; // set Agpcfg 4 fun2 as sd wp
			sGpio->Agpcfg |=  0x00100000; // set Agpcfg 4 fun2 as sd wp	
			#endif
		#endif
    #else 
	sGpio->Fgpcfg[0] |= GPIO_DEFINE_0; // FD8 ~ FD15 : D0 ~ D7
	sGpio->Fgpcfg[1] |= GPIO_DEFINE_1; // FD18 : CMD
	sGpio->Fgpcfg[2] |= GPIO_DEFINE_2; // FGPIO[46] : CLK
	sGpio->Fgpcfg[3] |= GPIO_DEFILE_3; // FGPIO[55],[56] : CD, WP
	#endif
	sMcard->McWdt = WATCHDOG_TIMER;
	sMcard->McWdt &=~ BIT21 ;
#if((STD_BOARD_VER == MP600PQFP_8M_SDRAM)||(STD_BOARD_VER == MP600_128PQFP_CPU_8M_SDRAM))
	sMcard->McardC = MCARD_ENABLE + sInfo.dwCardTag + BIT11;
#else
	sMcard->McardC = MCARD_ENABLE + sInfo.dwCardTag;
#endif
}

static BYTE GetWPFlag(void)
{
	register GPIO *sGpio;

	sGpio = (GPIO *) (GPIO_BASE);
#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600)
#if((CHIP_VER & 0x0000ffff) == CHIP_VER_A)	
	return ((sGpio->Fgpdat[0] & 0x00008000) ? 1 : 0); // M600 Fgpio15 as Sd WP#
#elif (((CHIP_VER & 0x0000ffff) == CHIP_VER_B)||((CHIP_VER & 0x0000ffff) == CHIP_VER_C))
	return ((sGpio->Agpdat & 0x00000010) ? 1 : 0); 
#endif		
#else
	return ((sGpio->Fgpdat[3] & 0x100) ? 1 : 0);
#endif
}

static void SetClockSpeed(DWORD dwSpeed)
{
	DWORD dwIndex;

	for (dwIndex = dwSD_MMC_MAX_CLOCK; dwIndex >= dwSD_MMC_MIN_CLOCK; dwIndex--)
	{
		if (sClockSpeedTable[dwIndex].dwClockValue <= dwSpeed)
		{
			break;
		}
	}
	MP_DEBUG2("setting clock: %d Hz, Value =%d", sClockSpeedTable[dwIndex].dwClockValue,sClockSpeedTable[dwIndex].bSettingValue);
	sInfo.dwClock = sClockSpeedTable[dwIndex].bSettingValue;
	McardSetClock(sInfo.dwClock);
}

static SWORD GoTransferMode(void)
{
#define MAX_RETRY_TIMES 1
	register MCARD *sMcard;
	DWORD dwResp, dwParam, dwReadBlLen, dwCSizeMult, dwCSize, dwTryCount, dwSpeed;
	SWORD swRetValue;
	BYTE bVersion, bRetryTimes,bCCS=0,bHCS=0;
	BYTE *pbBuffer1;
	BYTE bTempMemID0;
	sMcard = (MCARD *) (MCARD_BASE);
	#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600 )	
		DeSelectData();
	#endif
	if (sInfo.bInitFlag == FALSE)
	{	
		sMcard->McSdC = 0;
#if((STD_BOARD_VER == MP600PQFP_8M_SDRAM)||(STD_BOARD_VER == MP600_128PQFP_CPU_8M_SDRAM))
		sMcard->McardC = MCARD_ENABLE + sInfo.dwCardTag + BIT11;
#else
		sMcard->McardC = MCARD_ENABLE + sInfo.dwCardTag;
#endif
	}

	bRetryTimes = MAX_RETRY_TIMES;
	swRetValue = SD_PASS;
	do
	{
		if (swRetValue != SD_PASS)
		{
			bRetryTimes--;
			swRetValue = SD_PASS;
			MP_DEBUG2("-E- MMC/SD Init Failed: Trial %d out of %d", bRetryTimes, MAX_RETRY_TIMES);
		}
		// at the IDLE state, issus the APP command, if MMC inserted, it will not response
		SetCommand(CMD_GO_IDLE_STATE, 0);
		OpenDrainDelay();
		WaitHostReady();

//		if (sInfo.bInitFlag == TRUE)
//		{
			SetCommand(CMD_GO_IDLE_STATE, 0);
			OpenDrainDelay();
			WaitHostReady();

			sInfo.dwClock = dwINITIAL_CLOCK;
			McardSetClock(sInfo.dwClock);
			OpenDrainDelay();
			sInfo.dwCardTag = MCARD_DMA_SD;
#if((STD_BOARD_VER == MP600PQFP_8M_SDRAM)||(STD_BOARD_VER == MP600_128PQFP_CPU_8M_SDRAM))
			sMcard->McardC = MCARD_ENABLE + sInfo.dwCardTag + BIT11;
#else
			sMcard->McardC = MCARD_ENABLE + sInfo.dwCardTag;
#endif
			sInfo.dwBusWidth = DBUS_1BIT;
			sInfo.bInitFlag = FALSE;

			SetCommand(CMD_GO_IDLE_STATE, 0);
			OpenDrainDelay();
			WaitHostReady();
//		}


		dwTryCount = 1;
		while (dwTryCount)
		{
			WaitHostReady();
			MP_DEBUG("Send OP Cmd for MMC");
			SetCommand(CMD_SEND_OP_COND, HOST_OCR_VALUE);
			OpenDrainDelay();
			if(WaitResponse() == PASS)
				MP_DEBUG1("SD op condition = ",sMcard->McSdRspA);
			swRetValue = WaitResponse();
			dwTryCount--;
		}

		if (swRetValue)
		{
			MP_DEBUG("sd card");
			sInfo.bType = SD_TYPE;
			// send OP_COND command for getting into READY state
			dwTryCount = 1000;
			#ifdef SDHC_FLAG // SDHC
			MP_DEBUG("Send command 8 for SDHC");
                SetCommand(CMD_SEND_IF_COND,0x000001aa);
                OpenDrainDelay();
                OpenDrainDelay();
               	WaitHostReady();
				if ((swRetValue = WaitResponse()))
				{
					dwResp = sMcard->McSdRspA;
				}	           
				dwResp = sMcard->McSdRspA;
				if((sMcard->McSdRspA & 0xff) == SDHC_CHECK_PATTERN)
				{
					bHCS = 1;
				}

			#endif
          
			do
			{			    
				dwResp = 0;
				dwTryCount--;
				SetCommand(CMD_APP_COM, 0);
				OpenDrainDelay();
				OpenDrainDelay();
				WaitHostReady();
				if ((swRetValue = WaitResponse()))
				{
					continue;
				}
			#ifdef SDHC_FLAG // SDHC	
				if (bHCS == 1)
					SetCommand(ACMD_SD_APP_OP_COND, HOST_OCR_VALUE|HCS);
				else
				#endif    
					SetCommand(ACMD_SD_APP_OP_COND,HOST_OCR_VALUE);

				
				OpenDrainDelay();
				OpenDrainDelay();
				WaitHostReady();
				if ((swRetValue = WaitResponse()))
				{
					continue;
				}
				dwResp = sMcard->McSdRspA;
			}
			while (!(dwResp >> 31) && (dwTryCount > 0));
            #ifdef SDHC_FLAG
			if(dwResp & HCS)
				bCCS =1;
            #endif
			MP_DEBUG1("SD dwResp = %x", dwResp);
			// while card is still busy, keep sending OP_COND command

			if (swRetValue != SD_PASS)
			{
				MP_DEBUG("-E- ACMD_SD_APP_OP_COND FAIL");
				continue;
			}

			SetCommand(CMD_ALL_SEND_CID, 0);
			OpenDrainDelay();
			WaitHostReady();
			if ((swRetValue = WaitResponse()))
			{
				MP_DEBUG1("-E- CMD_ALL_SEND_CID FAIL (swRetValue: %d)", swRetValue);
				continue;
			}
			// send the host designating RCA to card and change to STANDBY state
			SetCommand(CMD_SEND_RELATIVE_ADDR, 0);
			OpenDrainDelay();
			if ((swRetValue = WaitHostReady()))
			{
				MP_DEBUG1("-E- CMD_SEND_RELATIVE_ADDR FAIL (swRetValue: %d)", swRetValue);
				continue;
			}			
			sInfo.dwRelativeCardAddr = sMcard->McSdRspA;
			sInfo.dwRelativeCardAddr &= 0xffff0000;
			MP_DEBUG1("dwRelativeCardAddr = %x", sInfo.dwRelativeCardAddr);
		}
		else
		{
			sInfo.bType = MMC_TYPE;
			MP_DEBUG("mmc card");
			IODelay(1000); // rick add for mmc detect fail issue

			sInfo.dwCardTag = MCARD_DMA_MMC;
#if((STD_BOARD_VER == MP600PQFP_8M_SDRAM)||(STD_BOARD_VER == MP600_128PQFP_CPU_8M_SDRAM))
			sMcard->McardC = MCARD_ENABLE + sInfo.dwCardTag + BIT11;
#else
			sMcard->McardC = MCARD_ENABLE + sInfo.dwCardTag;
#endif
			dwTryCount = 100;
			do
			{
				dwTryCount--;
				dwResp = 0;
				SetCommand(CMD_SEND_OP_COND, HOST_OCR_VALUE);
				OpenDrainDelay();
				OpenDrainDelay();
				WaitHostReady();
				if ((swRetValue = WaitResponse()))
				{
					continue;
				}
				dwResp = sMcard->McSdRspA;
			}
			while (!(dwResp >> 31) && (dwTryCount > 0));

			MP_DEBUG1("mmc op condition = %x", dwResp);

			if (swRetValue != SD_PASS)
			{
				MP_DEBUG("-E- CMD_SEND_OP_COND FAIL");
				continue;
			}

			SetCommand(CMD_ALL_SEND_CID, 0);
			OpenDrainDelay();
			WaitHostReady();
			if ((swRetValue = WaitResponse()))
			{
				MP_DEBUG1("-E- CMD_ALL_SEND_CID FAIL (swRetValue: %d)", swRetValue);
				continue;
			}

			// send the host designating RCA to card and change to STANDBY state
			sInfo.dwRelativeCardAddr = MMC_DEFAULT_ADDR;
			SetCommand(CMD_SEND_RELATIVE_ADDR, sInfo.dwRelativeCardAddr);
			OpenDrainDelay();
			WaitHostReady();
			if ((swRetValue = WaitResponse()))
			{
				MP_DEBUG1("-E- CMD_SEND_RELATIVE_ADDR FAIL (swRetValue: %d)", swRetValue);
				continue;
			}
			MP_DEBUG1("dwRelativeCardAddr = %x", sInfo.dwRelativeCardAddr);
		}
	#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600 )	
		Select();
	#endif

		// get the Card Specific Register
		SetCommand(CMD_SEND_CSD, sInfo.dwRelativeCardAddr);
		OpenDrainDelay();
		WaitHostReady();
		if ((swRetValue = WaitResponse()))
		{
			MP_DEBUG1("-E- CMD_SEND_CSD FAIL (swRetValue: %d)", swRetValue);
			continue;
		}
		if(bCCS == 0)
		{
		// calculate the card capacity
		dwResp = sMcard->McSdRspB;
		dwReadBlLen = (dwResp & 0x000f0000) >> 16;
		dwCSize = (dwResp & 0x000003ff) << 2;
		dwResp = sMcard->McSdRspC;
		dwCSize += ((dwResp >> 30) + 1);
		dwCSizeMult = ((dwResp & 0x00038000) >> 15) + 2;
		sInfo.dwCapacity =
			((1 << dwReadBlLen) * ((1 << dwCSizeMult) * dwCSize)) / MCARD_SECTOR_SIZE;
		}
		else 
		{
			sInfo.bType = SDHC_TYPE;
			bVersion = (sMcard->McSdRspA &0xc0000000)>>30;
			dwReadBlLen = (sMcard->McSdRspB & 0x000f0000)>>16;
			dwCSize = (sMcard->McSdRspC & 0xffff0000)>>16;
			dwCSize +=1;
			sInfo.dwCapacity = (dwCSize / MCARD_SECTOR_SIZE)*(1<<(dwReadBlLen+10));
			MP_DEBUG1(" SDHC Capacity = %d",sInfo.dwCapacity);

		}

		dwResp = sMcard->McSdRspA;

#ifdef ENABLE_CHACK_TACC_MECHANISM
		// if TAAC less than 1ms, not ues multiblock read
		if (((dwResp & 0x00060000) >> 17) == 3)
		{
			sInfo.bMultiReadFlag = 1;
		}
		else
		{
			sInfo.bMultiReadFlag = 0;
		}
#endif
		// if mmc card get spec version.
		if (sInfo.dwCardTag == MCARD_DMA_MMC)
		{
			bVersion = (dwResp & 0x3c000000) >> 26;
			MP_DEBUG1("MMC Version = %x", bVersion);
		}
		else
		{
			bVersion = 0;
		}

		//change frequency
		dwResp = (sMcard->McSdRspA & 0xff);
		sInfo.dwSpeed = (dwSpeedUnit[(dwResp & 0x7)] * bSpeedFactor[((dwResp & 0xf8) >> 3)]) / 10;
		MP_DEBUG1("card max speed = %d kHz", sInfo.dwSpeed);

⌨️ 快捷键说明

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