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

📄 sm.c

📁 常见卡(SD,NAND,XD,MS,ATA,CF)完整DRIVER
💻 C
📖 第 1 页 / 共 5 页
字号:
			return FAIL;
		}
	}
	mem_free(bTempBuffer);
	return PASS;
}
static BOOL CheckBlockStatus(void)
{
	if (bRedtData[0] == 0xFF)
	{
		return USABLE_BLOCK;
	}
	else
	{
		return UNUSABLE_BLOCK;
	}

	if (BitCountByte(bRedtData[5]) < 7)
	{
		return UNUSABLE_BLOCK;
	}
	return USABLE_BLOCK;
}

static BYTE BitCountByte(BYTE bByteData)
{
	BYTE bBitsCount = 0;

	while (bByteData)
	{
		bBitsCount += (bByteData & 0x01);
		bByteData >>= 1;
	}
	return bBitsCount;
}

static BOOL LoadLogBlockAddr(WORD * pwLogBlockAddr)
{
	WORD wAddr;

	if((MLC == TRUE) && (sInfo.bCurMode == INITIAL_NAND))
		wAddr = (bRedtData[0] << 8) + bRedtData[1];
	else
		wAddr = (bRedtData[6] << 8) + bRedtData[7];
	if (wAddr == 0x0)
	{
		// bad block or CIS block
		return UNUSABLE_BLOCK;
	}
	*pwLogBlockAddr = ((wAddr & 0x07ff) >> 1);
	return USABLE_BLOCK;
}

static WORD GetEmptyBlock(DWORD dwCurZone,WORD wZoneNum,WORD *pwLog2PhyTable)
{
	WORD wBlankAddr;
//	WORD *pwLog2PhyTable;
	BYTE *pReAssignTable;

	pReAssignTable = (BYTE *) sInfo.bReAssignTable[sInfo.bCurMode];
//	pwLog2PhyTable = (WORD *) sInfo.wLog2PhyTable[sInfo.bCurMode];
	if(sInfo.bCurMode == INITIAL_NAND)
	wBlankAddr = pwLog2PhyTable[wZoneNum * MAX_BLOCK + pReAssignTable[wZoneNum] + MAX_LOGBLOCK];
	else if(sInfo.bCurMode == INITIAL_XD)
		wBlankAddr = pwLog2PhyTable[dwCurZone * MAX_BLOCK + pReAssignTable[wZoneNum] + MAX_LOGBLOCK];

	return (wBlankAddr);
}

static SWORD ReadRedtData(DWORD dwSectorAddr)
{
	register MCARD *sMcard;
	SWORD swRetValue;
	WORD wNum;
	BYTE bTempMemID, *pbBuffer;
	sMcard = (MCARD *) (MCARD_BASE);
	SetControl();

	if(sInfo.bCurMode == INITIAL_NAND){
		if((MultiDieFlag & MultiDie) == MultiDie){
			if(dwSectorAddr < (MaxPhyPage/2)){
				GpioValueSetting(0,NAND1_CE);

			}else{
				dwSectorAddr = dwSectorAddr - (MaxPhyPage/2);
				GpioValueSetting(0,NAND2_CE);
			}
		
	}
		else{
				GpioValueSetting(0,NAND1_CE);
		}
	}
	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 DWORD GetSameZone(DWORD dwLogAddr, DWORD dwSectorCount)
{
	DWORD dwPage, dwCount;
	dwPage = dwLogAddr % 128;
	if (dwSectorCount > (128 - dwPage))
	{
		return (128 - 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);
              #if LCD_PANEL_480_234
		if( !Ui_CheckMsPlugIn() )			   
		SetGPIOValue(GPIO_XD_VCC, 0);
              #endif	
 #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)
{
	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;

}
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)
	{
#ifdef SHOW_NAND_ID
			sInfo.bCurID[INITIAL_NAND] = bIDBuffer[1];
#endif
			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 & 0x0000ffff) == CHIP_VER_B)||((CHIP_VER & 0x0000ffff) == CHIP_VER_C))
		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;

⌨️ 快捷键说明

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