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

📄 sd.c

📁 8032底层驱动部分。因为可以移植 所以单独来拿出来
💻 C
📖 第 1 页 / 共 5 页
字号:

	return NO_ERROR;
}

/*************************************************************************
* FUNCTION
*  SD_Reset
*
* DESCRIPTION
*	reset all cards to idle state
*
* PARAMETERS
*	1. cmd: the content of SDC_CMD register
*	2. arg: the argument(if the command need no argument, fill it with 0)
*
* RETURNS
*	SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*	
* NOTE
*
*************************************************************************/
SDC_CMD_STATUS SD_Reset(void)
{
	SDC_CMD_STATUS status;

	status = SD_Send_Cmd(SDC_CMD_CMD0,SDC_NO_ARG);
	gSD.mState = IDLE_STA;

	return status;
}

/*************************************************************************
* FUNCTION
*  SD_Cmd55
*
* DESCRIPTION
*	APP_CMD: inidicate to the card that the next command is an application specified command
*			rather than a standard command
*
* PARAMETERS
*	rca: relative card address
*
* RETURNS
*	SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*	
* NOTE
*
*************************************************************************/
SDC_CMD_STATUS SD_Cmd55(kal_uint16 rca)
{
	SDC_CMD_STATUS status;

	if((status = SD_Send_Cmd(SDC_CMD_CMD55,(kal_uint32)rca<<16))!=NO_ERROR)
		return status;
	//read R1
	if((status = SD_CheckStatus())!=NO_ERROR)
		return status;
	//check APP_CMD bit in status register
	MSDC_ReadReg32(SDC_RESP0,&status);
	if(!(status & R1_APP_CMD_5))
		return ERR_APPCMD_FAILED;

	return NO_ERROR;	
}
/*************************************************************************
* FUNCTION
*  SD_Cmd8
*
* DESCRIPTION
*	1. Sends SD Memory Card interface conditions for support larger than 2G cards
*	2. check if the card is compliant to SD2.0 or higher
*	3. only performed while at IDLE state.
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*	gSD.mIsCMD8
*
*************************************************************************/
void SD_Cmd8(void)
{
	kal_uint32 resp;

	if(SD_Send_Cmd(SDC_CMD_CMD8,SDC_CMD8_ARG)!=NO_ERROR)
	{
		dbg_print("SD_Cmd8 fail \r\n");
		SD_Reset();
		gSD.mCMD8Resp = SD_CMD8_RESP_NORESP;
		return;
	}
	MSDC_ReadReg32(SDC_RESP0,&resp);
	if(resp == SDC_CMD8_ARG)
		gSD.mCMD8Resp = SD_CMD8_RESP_VALID;
	else
		gSD.mCMD8Resp = SD_CMD8_RESP_INVALID;
}

/*************************************************************************
* FUNCTION
*  SD_Cmd1_MMC
*
* DESCRIPTION
*	 asks all cards in idle state to send their OCR in the response on the CMD line
*
* PARAMETERS
*
* RETURNS
*	SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*	gSD
*
* NOTE
*	only works for MMC
*
*************************************************************************/
SDC_CMD_STATUS SD_Cmd1_MMC(void)
{
	SDC_CMD_STATUS status;
	kal_uint32 _ocr, ocr_i, t1, t2;

	#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
	if(gSD.mCMD8Resp == SD_CMD8_RESP_INVALID)
		return ERR_CMD8_INVALID;
	ocr_i = (SDC_OCR_DEFAULT|MMC_HIGH_DESITY_CHECK_BIT);
	#else
	ocr_i = SDC_OCR_DEFAULT;
	#endif

	if(gMSDC_Handle.is_init_timeout == KAL_TRUE)
		return ERR_R3_OCR_BUSY;
	t2 = drv_get_current_time();
	do{
		t1 = drv_get_current_time();
		MSDC_START_TIMER(MSDC_TIMEOUT_PERIOD_DAT);
		while((MSDC_IS_BUSY)
			&& MSDC_Check_Card_Present() && !gMSDC_Handle.is_timeout)
		{
			if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
				gMSDC_Handle.is_timeout = KAL_TRUE;
		};
		MSDC_STOP_TIMER();		
		if(gMSDC_Handle.is_timeout)
			return MSDC_GPT_TIMEOUT_ERR;		
		MSDC_WriteReg32(SDC_ARG,ocr_i);
		MSDC_WriteReg32(SDC_CMD,SDC_CMD_CMD1);
		if((status = SD_WaitCmdRdyOrTo())  != NO_ERROR)
		{
			return status;
		}		
		MSDC_ReadReg32(SDC_RESP0, &_ocr);
		if((_ocr & SDC_OCR_DEFAULT) == 0)
			return ERR_OCR_NOT_SUPPORT;
		if(!gMSDC_Handle.mIsPresent)
			return MSDC_CARD_NOT_PRESENT;
		
		if(!(_ocr&SDC_OCR_BUSY))		
		{
			if(drv_get_duration_ms(t2) > MSDC_TIMEOUT_PERIOD_INI)
			{
				gMSDC_Handle.is_init_timeout = KAL_TRUE;			
				break;
			}					
			if(kal_query_systemInit() == KAL_TRUE)
				GPTI_BusyWait(30);
			else
				kal_sleep_task(7);
				
		}
		else
			break;		
	}while(1);

	if(gMSDC_Handle.is_init_timeout)
		return ERR_CMD_TIMEOUT;

	#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
	if((_ocr & MMC_HIGH_DESITY_CHECK_MSK) == MMC_HIGH_DESITY_CHECK_BIT)
	{
		gSD.flags |= SD_FLAG_HCS_SUPPORT;
		gMSDC_Handle.mMSDC_type = MMC42_CARD;
	}
	else
	#endif
	gMSDC_Handle.mMSDC_type = MMC_CARD;
	gSD.mInactive = KAL_FALSE;
	gSD.mSDC_ocr = _ocr;
	gSD.mState = READY_STA;
	
	return NO_ERROR;
}

/*************************************************************************
* FUNCTION
*  SD_Acmd41_SD
*
* DESCRIPTION
*	asks all cards in idle state to send their OCR in the response on the CMD line
*	OCR: Operation Condition Register
*
* PARAMETERS
*
* RETURNS
*	SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*	gSD
*
* NOTE
*	only works for SD
*
*************************************************************************/
SDC_CMD_STATUS SD_Acmd41_SD(void)
{

	SDC_CMD_STATUS		status;
	kal_uint32			_ocr = 0, ocr_i, t1, t2;
	
#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)	
	if(gSD.mCMD8Resp == SD_CMD8_RESP_NORESP)
		ocr_i = SDC_OCR_DEFAULT;
	else if(gSD.mCMD8Resp == SD_CMD8_RESP_VALID)
		ocr_i = (SDC_OCR_DEFAULT|SD_ACMD41_HCS);
	else if(gSD.mCMD8Resp == SD_CMD8_RESP_INVALID)
		return ERR_CMD8_INVALID;	
#else	
	ocr_i = SDC_OCR_DEFAULT;
#endif	

	gMSDC_Handle.is_init_timeout = KAL_FALSE;
	t2 = drv_get_current_time();
	do{
		t1 = drv_get_current_time();		
		MSDC_START_TIMER(MSDC_TIMEOUT_PERIOD_CMD);
		while((MSDC_IS_BUSY)
			&& MSDC_Check_Card_Present() && !gMSDC_Handle.is_timeout)
		{
			if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_CMD*11)
				gMSDC_Handle.is_timeout = KAL_TRUE;			
		};
		MSDC_STOP_TIMER();
		if(gMSDC_Handle.is_timeout)
			return MSDC_GPT_TIMEOUT_ERR;		
		status=SD_Cmd55(SDC_RCA_DEFAULT);
		if(status != NO_ERROR)
		{
			return status;
		}
		MSDC_START_TIMER(MSDC_TIMEOUT_PERIOD_CMD);
		t1 = drv_get_current_time();
		while((MSDC_IS_BUSY)
			&& MSDC_Check_Card_Present() && !gMSDC_Handle.is_timeout)
		{
			if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_CMD*11)
				gMSDC_Handle.is_timeout = KAL_TRUE;			
		};
		MSDC_STOP_TIMER();
		if(gMSDC_Handle.is_timeout)
			return MSDC_GPT_TIMEOUT_ERR;		
		MSDC_WriteReg32(SDC_ARG,ocr_i);
		MSDC_WriteReg32(SDC_CMD,SDC_CMD_CMD41_SD);
		if((status = SD_WaitCmdRdyOrTo())  != NO_ERROR)
		{
			return status;
		}		
		MSDC_ReadReg32(SDC_RESP0, &_ocr);
		if((_ocr & SDC_OCR_DEFAULT) == 0)
			return ERR_OCR_NOT_SUPPORT;
		if(!gMSDC_Handle.mIsPresent)
			return ERR_CARD_NOT_PRESENT;	
		if(!(_ocr&SDC_OCR_BUSY))		
		{
			if(drv_get_duration_ms(t2) > MSDC_TIMEOUT_PERIOD_INI)
			{
				gMSDC_Handle.is_init_timeout = KAL_TRUE;			
				break;
			}					
			if(kal_query_systemInit() == KAL_TRUE)
				GPTI_BusyWait(30);
			else
				kal_sleep_task(7);
		}
		else
			break;		
	}
	while(1);

	if(gMSDC_Handle.is_init_timeout)
		return ERR_R3_OCR_BUSY;

	gSD.mInactive = KAL_FALSE;
	gSD.mSDC_ocr = _ocr;
	#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
	gSD.flags |= SD_FLAG_SD_TYPE_CARD;	
	if(_ocr & SD_ACMD41_HCS)
	{
		gSD.flags |= SD_FLAG_HCS_SUPPORT;
		gMSDC_Handle.mMSDC_type = SD20_HCS_CARD;
	}
	else if(gSD.mCMD8Resp == SD_CMD8_RESP_VALID)
		gMSDC_Handle.mMSDC_type = SD20_LCS_CARD;
	else
	#endif
		gMSDC_Handle.mMSDC_type = SD_CARD;
	gSD.mState = READY_STA;

	return NO_ERROR;
}

/*************************************************************************
* FUNCTION
*  SD_GetCID
*
* DESCRIPTION
*	Read Card Identification.
*
* PARAMETERS
*
* RETURNS
*	SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*	gSD
*
* NOTE
*	
*
*************************************************************************/

// Get CID(CMD2)
SDC_CMD_STATUS SD_GetCID(kal_uint32 Cid[4])
{
	int i;
	SDC_CMD_STATUS status;

	if((status = SD_Send_Cmd(SDC_CMD_CMD2,SDC_NO_ARG))!=NO_ERROR)
		return status;
	//read R2
	for(i=0;i<4;i++)
		MSDC_ReadReg32((SDC_RESP0+i*sizeof(kal_uint32)), &Cid[i]);
	SD_AnalysisCID(Cid);
	gSD.mState = IDENT_STA;
	
	return NO_ERROR;
}

/*************************************************************************
* FUNCTION
*  SD_ValidateRCA
*
* DESCRIPTION
*	assing or read RCA
*
* PARAMETERS
*	pRca: used for input or output RCA
*
* RETURNS
*	SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*	gSD
*
* NOTE
*	RCA is assinged to MMC card fixed to SDC_RCA_MMC(1)
*
*************************************************************************/

// assign or read RCA
SDC_CMD_STATUS SD_ValidateRCA(kal_uint16* pRca)
{
	SDC_CMD_STATUS status;
	kal_uint32 resp;
	kal_uint8  state;

	#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
	if(gSD.flags & SD_FLAG_SD_TYPE_CARD )
	#else
	if(gMSDC_Handle.mMSDC_type == SD_CARD)
	#endif
	{
		//read RCA form card
		if((status = SD_Send_Cmd(SDC_CMD_CMD3_SD,SDC_NO_ARG))!=NO_ERROR)
			return status;
		//read R6
		MSDC_ReadReg32(SDC_RESP0, &resp);
		*pRca = resp >>  16;
		gSD.mRCA =*pRca;
		
	}
	else
	{
		//assign RCA to card
		if((status = SD_Send_Cmd(SDC_CMD_CMD3_MMC,(kal_uint32)SDC_RCA_MMC<<16))!=NO_ERROR)
			return status;

		//read R1
		MSDC_ReadReg32(SDC_RESP0, &resp);
		SD_GetStatus(SDC_RCA_MMC,&resp);
		state = 0;
		GetBitFieldN((kal_uint8*)&state,(kal_uint8*)&resp,9,4);
		if(STBY_STA != state)
			return ERR_RCA_FAIL;		
		*pRca = gSD.mRCA = SDC_RCA_MMC;			
	}

	gSD.mState = STBY_STA;
	return NO_ERROR;
}

/*************************************************************************
* FUNCTION
*  SD_SetDSR
*
* DESCRIPTION
*	set default value to the DSR
*
* PARAMETERS
*
* RETURNS
*	SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*
* NOTE
*	SDC_DSR_DEFAULT(0x404)
*
*************************************************************************/
SDC_CMD_STATUS SD_SetDSR(void)
{
	return SD_Send_Cmd(SDC_CMD_CMD4,(kal_uint32)SDC_DSR_DEFAULT<<16);
}

/*************************************************************************
* FUNCTION
*  SD_SelectCard
*
* DESCRIPTION
*	select/deselect card
*
* PARAMETERS
*	rca: relative card address
*
* RETURNS
*	SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*
* NOTE
*
*************************************************************************/
SDC_CMD_STATUS SD_SelectCard(kal_uint16 rca)
{
	SDC_CMD_STATUS status;

	if((status = SD_Send_Cmd(SDC_CMD_CMD7,(kal_uint32)rca<<16))!=NO_ERROR)
		return status;
		
	//read R1b
	if((status = SD_WaitCardNotBusy())!=NO_ERROR)	
		return status;
	if((status = SD_CheckStatus())!=NO_ERROR)
		return status;

	return NO_ERROR;
}

/*************************************************************************
* FUNCTION
*  SD_GetCSD
*
* DESCRIPTION
*	Get CSD from addressed card
*
* PARAMETERS
*	rca: relative card address
*	Csd: used for containing read CSD
*
* RETURNS
*	SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*	
* NOTE
*
*************************************************************************/
SDC_CMD_STATUS SD_GetCSD(kal_uint16 rca, kal_uint32 Csd[4])
{
	SDC_CMD_STATUS status;
	kal_uint32 i;

	if((status = SD_Send_Cmd(SDC_CMD_CMD9,(kal_uint32)rca<<16))!=NO_ERROR)
		return status;
	// read R2
	for(i=0;i<4;i++)
		MSDC_ReadReg32((volatile kal_uint32 *)(SDC_RESP0+i*4), &Csd[i]);
	// analysis CSD...
	SD_AnalysisCSD(Csd);

	return NO_ERROR;
}

// addressed send CID
SDC_CMD_STATUS SD_GetAddressedCID(kal_uint16 rca, kal_uint32 Cid[4])
{
	SDC_CMD_STATUS status;
	kal_uint32 i;

	if((status = SD_Send_Cmd(SDC_CMD_CMD10,(kal_uint32)rca<<16))!=NO_ERROR)
		return status;

	// read R2
	for(i=0;i<4;i++)
		MSDC_ReadReg32((volatile kal_uint32 *)(SDC_RESP0+i*4), &Cid[i]);

	return NO_ERROR;
}


/*************************************************************************
* FUNCTION
*  SD_StopTrans
*
* DESCRIPTION
*	Stop Muli-Block operation
*
* PARAMETERS
*
* RETURNS
*	SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*	
* NOTE
*	definition of SD_STOP_SLOW is used for some erroneous card
*************************************************************************/
SDC_CMD_STATUS SD_StopTrans(kal_bool isTx)
{
	SDC_CMD_STATUS status;
	
	if((status = SD_Send_Cmd(SDC_CMD_CMD12,SDC_NO_ARG))!=NO_ERROR)
		return status;

⌨️ 快捷键说明

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