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

📄 sm_normal.c

📁 常见卡(SD,NAND,XD,MS,ATA,CF)完整DRIVER
💻 C
📖 第 1 页 / 共 5 页
字号:
		}
		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 
*/
static void CommandProcess(void *pMcardDev)
{
	ST_MCARD_MAIL *sMcardRMail;
	register ST_MCARD_DEV *pDev = ((ST_MCARD_DEV *) pMcardDev);

	McardSetClock(SM_CLOCK);
	sMcardRMail = pDev->sMcardRMail; 
		if (pDev->wMcardType == NAND)
		{
			Select(INITIAL_NAND);
		}
#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 (pDev->Flag.Detected)
		if(1)
		{
			//card in
			McardIODelay(0x500);
			pDev->Flag.Detected = 1;
			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
			{
				pDev->wSectorSize = MCARD_SECTOR_SIZE;
				if (pDev->swStatus = Log2PhyTabInit())
				{
					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);                  
				}
			}
		}
		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 ((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)
{
	ST_MEDIA_MEAT *sMediaMeat;
	DWORD dwCurAddr;
	SWORD swRetValue;
	WORD wLogBlockAddr, wZoneNum, wReassignState, i, wCurPhyBlock, wLogBlock, wPhyBlock, wTemp;
	WORD *pLog2PhyTable;
	BYTE *pReAssignTable;
	sMediaMeat = (ST_MEDIA_MEAT *) sInfo.sMediaMeat[sInfo.bCurMode];
	pLog2PhyTable = (WORD *) sInfo.wLog2PhyTable[sInfo.bCurMode];
	pReAssignTable = (BYTE *) sInfo.bReAssignTable[sInfo.bCurMode];
	BYTE *bTempBuffer = (BYTE *)mem_malloc(0x40000);
	for (wZoneNum = 0; wZoneNum < sMediaMeat->bMaxZone; wZoneNum++)
	{
		wReassignState = 0;
		for (i = 0; i < MAX_BLOCK; i++)
		{
			pLog2PhyTable[(wZoneNum * MAX_BLOCK) + 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;
			// Check block status, 
			// if LogBlockAddr == 0x0000,   bad block or CIS block
			// if 0 < LogBlockAddr < pMediaMeat->wMaxLogBlock, USED block
			// else are free blocks
			if (CheckBlockStatus())
			{
				if (bRedtData[5] == 0xf0)
				{
					bTempBuffer[wReassignState * 2] = (BYTE) (wCurPhyBlock >> 8);
					bTempBuffer[wReassignState * 2 + 1] = (BYTE) wCurPhyBlock;
					wReassignState++;
				}
				MP_DEBUG1("%d is bad block",(dwCurAddr/32));
				continue;
			}

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

			if (wLogBlockAddr >= sMediaMeat->wMaxLogBlock)
			{
				bTempBuffer[wReassignState * 2] = (BYTE) (wCurPhyBlock >> 8);
				bTempBuffer[wReassignState * 2 + 1] = (BYTE) wCurPhyBlock;
				wReassignState++;
			}
			else
			{
				// If SmXdLog2PhyTable is 0xffff, fill curphyblock
				// else compare the blockaddr to last page ,if the same fill curphyblock and access the original block as free block
				if (pLog2PhyTable[wZoneNum * MAX_BLOCK + wLogBlockAddr] == 0xffff)
				{
					pLog2PhyTable[wZoneNum * MAX_BLOCK + 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 = pLog2PhyTable[wZoneNum * MAX_BLOCK + wLogBlockAddr];
							pLog2PhyTable[wZoneNum * MAX_BLOCK + wLogBlockAddr] = wCurPhyBlock;
							bTempBuffer[wReassignState * 2] = (BYTE) (wPhyBlock >> 8);
							bTempBuffer[wReassignState * 2 + 1] = (BYTE) wPhyBlock;
							wReassignState++;
						}
						else
						{
//							bTempBuffer[wReassignState * 2] = (BYTE) (wPhyBlock >> 8);
//							bTempBuffer[wReassignState * 2 + 1] = (BYTE) wPhyBlock;
							bTempBuffer[wReassignState * 2] = (BYTE) (wCurPhyBlock >> 8);
							bTempBuffer[wReassignState * 2 + 1] = (BYTE) wCurPhyBlock;
							wReassignState++;
						}
					}
					else
					{
//						bTempBuffer[wReassignState * 2] = (BYTE) (wPhyBlock >> 8);
//						bTempBuffer[wReassignState * 2 + 1] = (BYTE) wPhyBlock;
						bTempBuffer[wReassignState * 2] = (BYTE) (wCurPhyBlock >> 8);
						bTempBuffer[wReassignState * 2 + 1] = (BYTE) wCurPhyBlock;
						wReassignState++;
					}
				}
			}
		}

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

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

		// Check if more than 24 bad block          
		pReAssignTable[wZoneNum] = 0;
		if (GetEmptyBlock(wZoneNum) == 0xffff)
		{
			mem_free(bTempBuffer);
			MP_DEBUG("-E- Get Empty Block Address FAIL");
			return FAIL;
		}
	}
	mem_free(bTempBuffer);
	return PASS;
}
static BOOL CheckBlockStatus(void)
{
	if (bRedtData[5] == 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(WORD wZoneNum)
{
	WORD wBlankAddr;
	WORD *pwLog2PhyTable;
	BYTE *pReAssignTable;

	pReAssignTable = (BYTE *) sInfo.bReAssignTable[sInfo.bCurMode];
	pwLog2PhyTable = (WORD *) sInfo.wLog2PhyTable[sInfo.bCurMode];
	wBlankAddr = pwLog2PhyTable[wZoneNum * 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);
		}

⌨️ 快捷键说明

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