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

📄 msdc.c

📁 一个复杂控制SD卡的例子,可以参考应用到手机上.
💻 C
📖 第 1 页 / 共 4 页
字号:
sd_select_enum current_card; // active card
#if !defined(__CUST_NEW__)
extern kal_char MSDC_GetLDO_GPIO(void);
extern kal_char MSDC_GetSwitch_GPIO(void);
kal_char gpio_simplug_ldo_switch;
kal_char gpio_ext_sd_ldo_switch;
kal_char gpio_sim_msdc_switch;	
#endif
#endif

// system control blocks

// function predeclaration
void MSDC_DMAInit(void);
void MSDC_INT_Init(void);
void MSDC_DMA_Callback(void);
void MSDC_EINT_Handler(void);

extern void GPIO_ModeSetup(kal_uint16 pin, kal_uint16 conf_dada);
extern boot_mode_type stack_query_boot_mode(void); 
extern kal_bool INT_USBBoot(void);
/*************************************************************************
* FUNCTION
*  MSDC_SetClock
*
* DESCRIPTION
*
* PARAMETERS
*	clock: the desired operating clock rate in the unit of kHz
*
* RETURNS
*
* GLOBALS AFFECTED
*
*************************************************************************/
void MSDC_SetClock(kal_uint32 clock)
{
	kal_uint32 cfg;

	if(clock == 0)
		return;
	MSDC_CLR_BIT32(SDC_CFG,SDC_CFG_SIEN);
	cfg = ((gMSDC_Handle->msdc_clock+clock-1)/clock);
	if(cfg <=2 )
	{		
		cfg = 0;
		gMSDC_Handle->op_clock = gMSDC_Handle->msdc_clock/2;
	}
	else
	{
		cfg = (cfg >> 2) + (cfg&3 != 0);	
		gMSDC_Handle->op_clock = gMSDC_Handle->msdc_clock/(4*cfg);
	}
	BitFieldWrite32((kal_uint32*)MSDC_CFG,(kal_uint32)cfg,MSDC_CFG_SCLKF);
	MSDC_SET_BIT32(SDC_CFG,SDC_CFG_SIEN);
	
}
/*************************************************************************
* FUNCTION
*  MSDC_Check_Card_Present
*
* DESCRIPTION
*	c
*
* PARAMETERS
*	ON: turn on power saving or not
*
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
kal_bool MSDC_Check_Card_Present(void)
{
#if !defined(__MSDC_NOT_SUPPORT_HOT_PLUG__)
	return gMSDC_Handle->mIsPresent;
#else
	return KAL_TRUE;
#endif
}
/*************************************************************************
* FUNCTION
*  MSDC_PDNControl
*
* DESCRIPTION
*	Enable power saving or not.
*
* PARAMETERS
*	ON: turn on power saving or not
*
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
void MSDC_PDNControl(kal_bool ON)
{
	gMSDC_Handle->mIsPWDown = ON;
#ifndef DRV_LSD
	if(ON)
	{	// OFF		
		// clear all pending IRQ
		MSDC_CLR_INT();
		MSDC_CLR_INT();
		#if 0 //!defined(MSDC_USE_INT)
/* under construction !*/
		#endif
		#if defined(MSDC_USE_USB_CLK) && defined(__MSDC_SD_MMC__)
#ifndef __SDC_SPI_INTERFACE__		
		if(gSD->flags & SD_FLAG_USE_USB_CLK)
			UPLL_Disable(UPLL_OWNER_MSDC);
#endif		
		#endif
#ifndef __SDC_SPI_INTERFACE__		
		DRVPDN_Enable(DRVPDN_CON1,DRVPDN_CON1_MSDC,PDN_MSDC);	
#else
		//DRVPDN_Enable(DRVPDN_CON1,DRVPDN_CON1_UART3,PDN_UART3);	
#endif
	}
	else
	{	// ON
		#if 0 // !defined(MSDC_USE_INT)
/* under construction !*/
		#endif		
#ifndef __SDC_SPI_INTERFACE__		
		DRVPDN_Enable(DRVPDN_CON1,DRVPDN_CON1_MSDC,PDN_MSDC);	
#else
		//DRVPDN_Enable(DRVPDN_CON1,DRVPDN_CON1_UART3,PDN_UART3);	
#endif
		#if defined(MSDC_USE_USB_CLK) && defined(__MSDC_SD_MMC__)
#ifndef __SDC_SPI_INTERFACE__				
		if(gSD->flags & SD_FLAG_USE_USB_CLK)
			UPLL_Enable(UPLL_OWNER_MSDC);		
#endif		
		#endif
	}
	// turn on MSDC_PDN bit always recently to cover sleep mode card detection
	#if 0 // !defined(USE_INT26_CARD_DETECTION)
/* under construction !*/
	#endif	
#else
	LSD_PDNControl(ON);
#endif

}
/*************************************************************************
* FUNCTION
*  MSDC_TimeOutHandler
*
* DESCRIPTION
*	Callback function of gpt timer, and launched while MSDC busy for a while

*
* PARAMETERS
*	
*
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
void MSDC_TimeOutHandler(void *parameter)
{
	kal_print("MSDC_TimeOutHandler");
	gMSDC_Handle->is_timeout = KAL_TRUE;	
	#if defined(__MSDC_MS__)||defined(__MSDC_MSPRO__)
	kal_set_eg_events(MSDC_Events,
				(EVENT_MSIFIRQ|EVENT_DMAIRQ|EVENT_MSRDYIRQ),
				KAL_OR);	
	#else
	kal_set_eg_events(MSDC_Events,
				(EVENT_SDCMDIRQ|EVENT_SDDATIRQ|EVENT_SDMCIRQ|EVENT_SDR1BIRQ|EVENT_DMAIRQ),
				KAL_OR);	
	#endif	
}

/*************************************************************************
* FUNCTION
*  MSDC_GetCardStatus
*
* DESCRIPTION
*	Check currently card is present or not.
*
* PARAMETERS
*	
*
* RETURNS
*
* GLOBALS AFFECTED
*	msdc_eint_state
*
*
*************************************************************************/
int MSDC_GetCardStatus(void * DriveData, int AckType)
{
    if(kal_query_systemInit() == KAL_FALSE)
    {
        kal_sleep_task(100);        
    }    
	ENTER_CRITICAL();
	send_ilm = KAL_TRUE;
	EXIT_CRITICAL();
	
	#if defined(__SIM_PLUS__)
	gMSDC_Handle = (MSDC_HANDLE *)DriveData;	
	if(!gMSDC_Handle->mIsPresent && current_card == SD_EXT)
		MSDC_PDNControl(KAL_TRUE);	
	#else
	if(!gMSDC_Handle->mIsPresent)
		MSDC_PDNControl(KAL_TRUE);
	#endif
	return 0;
}
/*************************************************************************
* FUNCTION
*  MSDC_SendCardInd
*
* DESCRIPTION
*	Send card indication to the specified module.
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
void MSDC_SendCardInd(module_type dest_id,sd_select_enum sel )
{
#if !defined(__MSDC_SD_SDIO__)
   ilm_struct *msdc_ilm;

   	#if defined(__SIM_PLUS__)
	if(send_ilm || sel == SD_SIM)
	#else
	if(send_ilm)
	#endif
	{
		msdc_card_detect_ind_struct *local;

		local = (msdc_card_detect_ind_struct*)
				   construct_local_para(sizeof(msdc_card_detect_ind_struct), TD_CTRL);	   
		local->media_size = 1;
		#if defined(__SIM_PLUS__)
		local->media_array = &MSDC_Blk[sel];
		#else
		local->media_array = &gMSDC_Handle;
		#endif	   
	   	msdc_ilm = allocate_ilm(MOD_DRV_HISR);
	   	msdc_ilm->src_mod_id = MOD_DRV_HISR;
		
		#if defined(__SIM_PLUS__)
		if(sel == SD_EXT)
		{
			msdc_ilm->msg_id = MSG_ID_MSDC_CARD_DETECT_IND;
			send_ilm = KAL_FALSE;
		}
		else
		{
			msdc_ilm->msg_id = MSG_ID_SIM_PLUS_DETECT_IND;
		}
		#else
		msdc_ilm->msg_id = MSG_ID_MSDC_CARD_DETECT_IND;
		send_ilm = KAL_FALSE;
		#endif
		
		msdc_ilm->sap_id = DRIVER_PS_SAP;
		msdc_ilm->local_para_ptr = (local_para_struct *)local;
		msdc_ilm->peer_buff_ptr = NULL;
		msdc_ilm->dest_mod_id = dest_id;
		msg_send_ext_queue(msdc_ilm);
	}
#endif
}
/*************************************************************************
* FUNCTION
*  MSDC_GetMediaChanged
*
* DESCRIPTION
*	Check if the media is changed, and clear the status after function call
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
kal_bool MSDC_GetMediaChanged(void* id)
{	
	kal_bool ret;

	ENTER_CRITICAL();
	gMSDC_Handle = (MSDC_HANDLE *)id;		
	ret = (gMSDC_Handle->mIsChanged )?(KAL_TRUE):(KAL_FALSE);
	gMSDC_Handle->mIsChanged = KAL_FALSE;	
	EXIT_CRITICAL();
		
	return ret; 
}
/*************************************************************************
* FUNCTION
*  MSDC_InvertN
*
* DESCRIPTION
* 	Invert the order of bytes eg,
* 	src: 0x01 0x02, len: 2 => dest: 0x02 0x01 
*
* PARAMETERS
*	1. dest: used for store inverted result
*	2. src: source for inverting
*	3. len: bytes for inverting
*
* RETURNS
*
* GLOBALS AFFECTED
*
* NOTE
*	1. make sure dest has the same size with src.
*************************************************************************/
void MSDC_InvertN(kal_uint8 *dest, kal_uint8 *src, kal_uint8 len)
{
	int i;
	for(i=0; i<len; i++)
		*(dest+len-1-i) = *(src+i);
	
}
/*************************************************************************
* FUNCTION
*  MSDC_Config_INS_WP
*
* DESCRIPTION
* 	Configure the pull up or pull down status for INS and WP pin
*
* PARAMETERS
*	1. ins: MSDC_IOCTRL_PULL_DOWN, MSDC_IOCTRL_PULL_UP
*	2. wp: MSDC_IOCTRL_PULL_DOWN, MSDC_IOCTRL_PULL_UP
*
* RETURNS
*
* GLOBALS AFFECTED
*
* NOTE
*	1. MT6219 can not be configured to PULL up or down. They are all pulled up by IO.
*	2. MT6218B and MT6217, WP is configured with data lines.
*************************************************************************/
void MSDC_Config_INS_WP(msdc_ioctrl_enum ins, msdc_ioctrl_enum wp)
{
	kal_uint32 msdc_cfg,iocon;
		
	gMSDC_Handle->ins_level = ins;
	//#if defined(MT6218B) || defined(MT6217)
	#if defined(DRV_MSDC_INSWP_MT6218B_SERIES)
	// INS use PRCFG0, WP use PRCFG2 together with data line (must pull high)
	msdc_cfg = *(volatile kal_uint32 *)MSDC_CFG;
	msdc_cfg &= ~(MSDC_CFG_PRCFG0);	
	msdc_cfg |= (ins << 22); 
	*(volatile kal_uint32 *)MSDC_CFG = msdc_cfg;	
	//#elif defined(MT6219)||defined(MT6227)||defined(MT6226)||defined(MT6226M) || defined(MT6225)
	#elif defined(DRV_MSDC_INSWP_MT6219_SERIES)
   #ifndef __CUST_NEW__
	GPIO_ModeSetup(MSDC_GPIO_MCINS,1); // enable card insertion signal
	GPIO_ModeSetup(MSDC_GPIO_WP,1); // enable write protection signal		
   #endif /* __CUST_NEW__ */
	if(ins == MSDC_IOCTRL_PULL_DOWN)
		GPIO_PullenSetup(MSDC_GPIO_MCINS, KAL_FALSE);	
	//#elif defined(MT6228)||defined(MT6229)||defined(MT6227)||defined(MT6226)||defined(MT6226M)
	#else
	msdc_cfg = *(volatile kal_uint32 *)MSDC_CFG;
	// INS use PRCFG3, WP use PRCFG0
	msdc_cfg &= ~(MSDC_CFG_PRCFG0);	
	msdc_cfg |= (wp << 22); 
	*(volatile kal_uint32 *)MSDC_CFG = msdc_cfg;
	iocon = *(volatile kal_uint16*)MSDC_IOCON;
	iocon &= ~(MSDC_IOCON_PRCFG3);
	iocon |= (ins<<8);	
	*(volatile kal_uint32 *)MSDC_IOCON = iocon;
	#endif	
}
/*************************************************************************
* FUNCTION
*  MSDC_Initialize
*
* DESCRIPTION
*	Initialize the MS/SD host controller, called only once at drv_init
*
* PARAMETERS*	
*
* RETURNS
*  1: initailized failed 
*  0: successful
*
* GLOBALS AFFECTED
*	gMSDC_Handle
*
*************************************************************************/
void MSDC_Initialize(void)
{	
	// turn on the power of controler
	#ifndef DRV_LSD
#ifndef __SDC_SPI_INTERFACE__
	DRVPDN_Disable(DRVPDN_CON1,DRVPDN_CON1_MSDC,PDN_MSDC);
#else
	//DRVPDN_Disable(DRVPDN_CON1,DRVPDN_CON1_UART3,PDN_UART3);
#endif

	#else
	ASSERT(LSD_Support());
	LSD_Reset();
	LSD_PDNControl(KAL_FALSE);
	#endif
#if defined(__MSDC_MS__)
	MSDC_CLR_BIT32(MSDC_CFG, MSDC_CFG_MSDC);
	gMSDC_Handle->mMSDC_type = MS_CARD;
#elif defined(__MSDC_MSPRO__)
	MSDC_CLR_BIT32(MSDC_CFG, MSDC_CFG_MSDC);
	gMSDC_Handle->mMSDC_type = MSPRO_CARD;	
	FS_MspDrvAll = FS_MspDrv;
#elif defined(__MSDC_SD_MMC__)
	MSDC_SET_BIT32(MSDC_CFG, MSDC_CFG_MSDC)	;
	gMSDC_Handle->mMSDC_type = SD_CARD;
#endif		
	gMSDC_Handle->msdc_clock = MSDC_CLOCK;

	if(gMSDC_Handle->gpt_handle == 0)
		GPTI_GetHandle(&gMSDC_Handle->gpt_handle);
#ifndef DRV_LSD
	#if !defined(__MSDC_TFLASH_DAT3_1BIT_HOT_PLUG__)
	MSDC_Config_INS_WP(MSDC_IOCTRL_PULL_UP,MSDC_IOCTRL_PULL_UP);
	#else
	MSDC_Config_INS_WP(MSDC_IOCTRL_PULL_DOWN,MSDC_IOCTRL_PULL_UP);
	// first time if card is present, no card insertion interrupt generated
	gMSDC_Handle->mIsPresent = KAL_TRUE; 
	#endif
#endif
	// turn on the power of memory card
	MSDC_SET_BIT32(MSDC_CFG,MSDC_CFG_VDDPD);
#ifndef DRV_LSD
	MSDC_SET_FIFO(1);
#endif
	
	#if defined(__SIM_PLUS__)
	#if !defined(__CUST_NEW__)
	GPIO_LDO_SWITCH = MSDC_GetLDO_GPIO();
	GPIO_EXT_SD_LDO_SWITCH = MSDC_GetEXTLDO_GPIO();
	GPIO_SIM_MSDC_SWITCH = MSDC_GetSwitch_GPIO();
	#endif
	GPIO_ModeSetup(GPIO_SIM_MSDC_SWITCH, 0); // gpio mode
	GPIO_InitIO(OUTPUT, GPIO_SIM_MSDC_SWITCH);
	/*bewlow comes after JRD SIM+ issue on 2007_03_08, use custom setting instead of fix value*/
	GPIO_WriteIO(MSDC_GetSwitchDirection(), GPIO_SIM_MSDC_SWITCH);
	/*end of changes of JRD SIM+ issue on 2007_03_08*/
	if(INT_USBBoot() == KAL_TRUE)
	{
		kal_uint32 i = 20;
		DRVPDN_Disable(DRVPDN_CON1,DRVPDN_CON1_SIM,PDN_SIM);
		DRV_Reg(SIM_CONF) |= SIM_CONF_SIMSEL;
		DRV_Reg(SIM_CTRL) |= SIM_CTRL_SIMON;
		DRVPDN_Enable(DRVPDN_CON1,DRVPDN_CON1_SIM,PDN_SIM);
		GPIO_ModeSetup(GPIO_LDO_SWITCH, 0); // gpio mode
		GPIO_InitIO(OUTPUT, GPIO_LDO_SWITCH);
		MSDC_Blk[SD_SIM].mIsPresent = KAL_TRUE;
		MSDC_Blk[SD_SIM].mIsChanged = KAL_TRUE;		
	}
	#endif
	

⌨️ 快捷键说明

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