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

📄 sd.c

📁 SDIO实现底层驱动文件.非常有用.经典!
💻 C
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************
*  Copyright Statement:
*  --------------------
*  This software is protected by Copyright and the information contained
*  herein is confidential. The software may not be copied and the information
*  contained herein may not be used or disclosed except with the written
*  permission of MediaTek Inc. (C) 2005
*
*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
*
*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
*
*****************************************************************************/

/*****************************************************************************
 *
 * Filename:
 * ---------
 *   sd.c
 *
 * Project:
 * --------
 *   Maui_Software
 *
 * Description:
 * ------------
 *   driver functons for SD/MMC 
 *   
 *
 * Author:
 * -------
 * -------
 *
 *============================================================================
 *             HISTORY
 * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
 *------------------------------------------------------------------------------
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 *------------------------------------------------------------------------------
 * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
 *============================================================================ 
 ****************************************************************************/
#include "kal_release.h"
#include "app_buff_alloc.h"
#include "gpt_sw.h"
#include "msdc_def.h"
#include "sd_def.h"
#include "intrCtrl.h"
#include "reg_base.h"

#if defined(__MSDC_SD_MMC__)
//global variables
T_SDC_HANDLE	gSD;

extern void GPTI_BusyWait(kal_uint16 len);
extern kal_uint8 MSDC_GetIOCtrlParam(void);
/*************************************************************************
* FUNCTION
*  SD_Acmd42
*
* DESCRIPTION
*	connect/disconnect the 50K Ohm pull-up resistor on CD/DAT3
*
* PARAMETERS
*
* RETURNS
*	SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*	gSD
*
* NOTE
*	
*
*************************************************************************/

// Get CID(CMD2)
SDC_CMD_STATUS SD_Acmd42(kal_bool connect)
{
	SDC_CMD_STATUS status;

	// send APP_CMD
	if((status = SD_Cmd55(gSD.mRCA))!=NO_ERROR)
		return status;
	// send cmd6
	if((status = SD_Send_Cmd(SDC_CMD_ACMD42,connect))!=NO_ERROR)
		return status;
	//read R1
	if((status = SD_CheckStatus())!=NO_ERROR)
		return status;	

	gSD.mCD_DAT3 = KAL_FALSE;	// pull-up resistor is disconnected for data trnasfer
	return NO_ERROR;
}

/*************************************************************************
* FUNCTION
*  SD_SetMMC40_4bit_high_speed
*
* DESCRIPTION
*	Check inserted card is SD or MMC
*
* PARAMETERS
*	
*
* RETURNS
*  SD_CARD or MMC_CARD
*
* GLOBALS AFFECTED
*	gMSDC_Handle
*
*************************************************************************/
SDC_CMD_STATUS SD_SetMMC40_bus_high_speed(void)
{
		kal_uint32 clock, hs;
		
		MSDC_WriteReg32(MSDC_IOCON,0x1B);			
		// read the EXT_CSD
		if(SD_SendEXTCSD_MMC40(MSDC_Sector) != NO_ERROR)
			goto err;;

		// set high speed
		if(gSD.mCSD.ext_csd->card_type & HS_52M)
		{
			// should be 52000
			clock = 13000;
			hs = 1;
		}
		else if(gSD.mCSD.ext_csd->card_type & HS_26M)
		{
			// should be 26000
			clock = 13000;
			hs = 1;
		}
		else
		{
			clock = 13000;
			hs = 0;
		}
		if(hs)
		{
			// select proper power class
			if(SD_Switch_MMC40(SET_BYTE,EXT_CSD_POW_CLASS_INDEX,
				(gSD.mCSD.ext_csd->pwr_52_360&0xf) ,0) != NO_ERROR)
				goto err;
			
			// enable high speed (26M or 52M)
			if(SD_Switch_MMC40(SET_BYTE,EXT_CSD_HIGH_SPPED_INDEX,
				EXT_CSD_ENABLE_HIGH_SPEED,0) != NO_ERROR)
				goto err;

			// latch data at falling edge to cover the card driving capability
			// MSDC_SET_BIT32(MSDC_CFG,MSDC_CFG_RED);			
		}
		gMSDC_Handle.msdc_clock = MSDC_CLOCK;
		MSDC_SetClock(clock);
		
		// select bus width
		#if defined(MMC40_USE_4BIT_BUS)
		// enable 4-bit bus width
		if(SD_Switch_MMC40(SET_BYTE,EXT_CSD_BUS_WIDTH_INDEX,BIT_4_MMC40,0) != NO_ERROR)
			goto err;
		MSDC_SET_BIT32(SDC_CFG,SDC_CFG_MDLEN);
		gSD.bus_width = 4;		
		#elif defined(MMC40_USE_8BIT_BUS)
		// enable 8-bit bus width
		if(SD_Switch_MMC40(SET_BYTE,EXT_CSD_BUS_WIDTH_INDEX,BIT_8_MMC40,0) != NO_ERROR)
			goto err;
		MSDC_SET_BIT32(SDC_CFG,SDC_CFG_MDLEN8);
		gSD.bus_width = 8;		
		#endif
					
		if(SD_SendEXTCSD_MMC40(MSDC_Sector) != NO_ERROR)
			goto err;;
				
		return NO_ERROR;
err:
		return ERR_MMC_BUS_HS_ERROR;
}
/*************************************************************************
* FUNCTION
*  SD_CheckSDorMMC
*
* DESCRIPTION
*	Check inserted card is SD or MMC
*
* PARAMETERS
*	
*
* RETURNS
*  SD_CARD or MMC_CARD
*
* GLOBALS AFFECTED
*	gMSDC_Handle
*
*************************************************************************/
T_MSDC_CARD SD_CheckSDorMMC()
{
	SDC_CMD_STATUS status; 

	// 1. send ACMD41
	if((status = SD_Acmd41_SD())==NO_ERROR)
		return gMSDC_Handle.mMSDC_type;	// SD_CARD
	else if((status = SD_Cmd1_MMC())==NO_ERROR)
		return gMSDC_Handle.mMSDC_type;	// MMC_CARD

	return UNKNOWN_CARD;
}
/*************************************************************************
* FUNCTION
*  SD_SetDefault
*
* DESCRIPTION
*	set default values to gSD
*
* PARAMETERS
*	
*
* RETURNS
*
* GLOBALS AFFECTED
*	gSD
*
*************************************************************************/
void SD_SetDefault(void)
{
	kal_mem_set(&gSD,0,sizeof(T_SDC_HANDLE));
	gSD.mBKLength = 512;
	gSD.mRCA = 0;
	gSD.mInactive = KAL_FALSE;
	gSD.mState = IDLE_STA;
	gSD.bus_width = 1;
	gSD.mCD_DAT3 = KAL_TRUE;
}
/*************************************************************************
* FUNCTION
*  SD_Initialize
*
* DESCRIPTION
*	Initial SD controller and card
*
* PARAMETERS
*	
*
* RETURNS
*  SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*	gSD
*
*************************************************************************/
SDC_CMD_STATUS SD_Initialize(void)
{
	kal_uint32 cid[4],csd[4],scr[4];
	kal_uint16 rca, iocon;
	SDC_CMD_STATUS status;

	if(gMSDC_Handle.mIsInitialized == KAL_TRUE)
	{
		return NO_ERROR;
	}
	// reset the events
	kal_set_eg_events(MSDC_Events, 0, KAL_AND);
	// reset msdc
	if(*(volatile kal_uint32*)MSDC_CFG & MSDC_CFG_RST)
	{
		MSDC_CLR_BIT32(MSDC_CFG, MSDC_CFG_RST);
	}
	else
	{
		RESET_MSDC();
	}
	// set rise edge data
	//MSDC_SET_BIT32(MSDC_CFG,MSDC_CFG_RED);
	// TODO: some card off, but some are on 
	//MSDC_SET_BIT32(MSDC_CFG,MSDC_CFG_CRED);
	
	// set the output driving capability from customization interface
	iocon = *(volatile kal_uint16*)MSDC_IOCON;
	iocon &= ~(0xff);
	iocon |= MSDC_GetIOCtrlParam();
	MSDC_WriteReg16(MSDC_IOCON,(kal_uint16)iocon);			
	
	// set pull up the data and cmd 
	BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)2,MSDC_CFG_PRCFG0);
	BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)2,MSDC_CFG_PRCFG1);
	BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)2,MSDC_CFG_PRCFG2);	
	// set read timeout x5ms
	BitFieldWrite32((kal_uint32*)SDC_CFG,(kal_uint32)40,SDC_CFG_DTOC);
	//set clock of serial clcok for initialization
	MSDC_CLR_BIT32(MSDC_CFG, MSDC_CFG_CLKSRC);
	gMSDC_Handle.msdc_clock = MSDC_CLOCK;
	MSDC_SetClock(MSDC_INI_CLOCK);	
	// disable 4-bit
	MSDC_CLR_BIT32(SDC_CFG,SDC_CFG_MDLEN);
	// initial global sturctures
	SD_SetDefault();
	// send the card to IDLE state
	if((status = SD_Reset())!=NO_ERROR)
	{
		goto err;
	}
	// set the IRQ MASK
	// set block length to 512
	BitFieldWrite32((kal_uint32*)SDC_CFG,(kal_uint32)512,SDC_CFG_BLKLEN);

	// and validate the OCR  (CMD0,CMD1 or ADMD41)
	if(SD_CheckSDorMMC() == UNKNOWN_CARD)
	{
		status = ERR_STATUS;
		goto err;
	}

	// get CID(CMD2)
	if((status = SD_GetCID(cid))!=NO_ERROR)
	{
		goto err;
	}
	// get or set RCA(CMD3)
	if((status = SD_ValidateRCA(&rca))!=NO_ERROR)
	{
		goto err;
	}
	// get CSD and analysis the CSD(CMD9)
	if((status = SD_GetCSD(gSD.mRCA,csd))!=NO_ERROR)
	{
		goto err;
	}		
	// Set driver stage register DSR to default value (0x0404)(CMD4)
	if(gSD.mCSD.dsr_imp)
		if((status = SD_SetDSR())!=NO_ERROR)
		{
			//dbg_print("6\r\n");
			goto err;
		}
	
	#if !defined(__MSDC_NO_WRITE_PROTECT__)
	// check write proctect switch(WP at SDC_STA)
	if((*(volatile kal_uint16*)SDC_STA & SDC_STA_WP))
		gSD.mWPEnabled = KAL_TRUE;
	#endif
	
	// select the card (CMD7) ,maybe locked 
	status = SD_SelectCard(gSD.mRCA);
	if(status == CARD_IS_LOCKED)
		gSD.mIsLocked = KAL_TRUE;

	// read the SD Configuration Register(ACMD51)
	if(gMSDC_Handle.mMSDC_type == SD_CARD)
	{
		#if defined(MSDC_USE_USB_CLK)
		MSDC_SET_BIT32(MSDC_CFG, MSDC_CFG_CLKSRC);
		gMSDC_Handle.msdc_clock = MSDC_CLOCK_USB;
		MSDC_SetClock(MSDC_SD_OP_CLOCK);
		#else
		MSDC_CLR_BIT32(MSDC_CFG, MSDC_CFG_CLKSRC);
		gMSDC_Handle.msdc_clock = MSDC_CLOCK;
		MSDC_SetClock(MSDC_OP_CLOCK);
		#endif
		if((status = SD_ReadSCR(scr))!=NO_ERROR)
		{
			goto err;

⌨️ 快捷键说明

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