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

📄 msdc.c

📁 一个复杂控制SD卡的例子,可以参考应用到手机上.
💻 C
📖 第 1 页 / 共 4 页
字号:
		MSDC_CLR_FIFO();
		MSDC_CLR_INT();
		MSDC_CLR_INT();
		//TurnOffMSDC();
		DMA_Stop(msdc_dmaport);		
	}
	#if !defined(FMT_NOT_PRESENT)
		MSDC_SendCardInd(MOD_FMT, SD_EXT);		
	#endif
	/*
	if(LSD_cardInsertion == LSD_cardDetection()){
		MSDC_CARD_INSERT_COUNTER ++;
	}
	else if(LSD_cardRemoval == LSD_cardDetection()){
		MSDC_CARD_REMOVE_COUNTER++;
	}
	else
		ASSERT(0);
	*/
}
#endif

/*************************************************************************
* FUNCTION
*  MSDC_INT_Init
*
* DESCRIPTION
*	Initialize MSDC's interrupt
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*	
*
*************************************************************************/
void MSDC_INT_Init(void)
{
#ifndef __SDC_SPI_INTERFACE__
#ifdef  __TST_WRITE_TO_FILE_ONLY__
   /*error recording: it mens this functions is called twice, just return*/
   if(KAL_TRUE == INT_QueryExceptionStatus())
   	return;
#endif
   MSDC_Events = kal_create_event_group("MSDC Events");
#ifndef DRV_LSD
   DRV_Register_HISR(DRV_MSDC_HISR_ID, MSDC_HISR_Entry);
   IRQ_Register_LISR(IRQ_MSDC_CODE, MSDC_LISR,"MSDC ISR");
   IRQSensitivity(IRQ_MSDC_CODE,LEVEL_SENSITIVE);
   IRQUnmask(IRQ_MSDC_CODE);
   
	// enable MSDC interrupt
	MSDC_CLR_INT();	
	#if !defined(MSDC_USE_INT)
	MSDC_DISABLE_INT();// (active)turn off other interrupt event except pin interrupt		
	#else
	MSDC_ENABLE_INT();// (deactive)
	#endif
	
	#ifdef USE_INT26_CARD_DETECTION
   // for card detection
   IRQ_Register_LISR(IRQ_MSDC_CD_CODE, MSDC_CardDetect_LISR,"MSDC CD ISR");
   IRQSensitivity(IRQ_MSDC_CD_CODE,EDGE_SENSITIVE);
   IRQUnmask(IRQ_MSDC_CD_CODE);
	#if !defined(MSDC_USE_INT)
	IRQMask(IRQ_MSDC_CODE);
	#endif
   #endif //USE_INT26_CARD_DETECTION
#else
    LSD_HISR_Registration();
#endif   
#endif   

}
void MSDC_LISR(void)
{
#ifndef DRV_LSD
#ifndef __SDC_SPI_INTERFACE__
	IRQMask(IRQ_MSDC_CODE);
#endif
	drv_active_hisr(DRV_MSDC_HISR_ID);
#endif
}
/*************************************************************************
* FUNCTION
*  MSDC_HISR_Entry
*
* DESCRIPTION
*	Set corresponding enevt and wake up waiting task.
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*	
*
*************************************************************************/
void MSDC_HISR_Entry(void)
{
	register kal_uint16 msdc_int = 0;

#if defined(__MSDC_MS__)||defined(__MSDC_MSPRO__)
	kal_uint16 msc_sta;

	FS_MspDrvAll = FS_MspDrv;
	#if defined (USE_INT26_CARD_DETECTION)
	if(gMSDC_Handle->mIsChanged == KAL_TRUE)
	{
		static kal_bool pre_IsPresent = KAL_TRUE; // it works only at first time
		
		if(pre_IsPresent)
			pre_IsPresent = gMSDC_Handle->mIsPresent;
		#if defined(MSDC_USE_INT)
		kal_set_eg_events(MSDC_Events,
				(EVENT_SDCMDIRQ|EVENT_SDDATIRQ|EVENT_SDMCIRQ|EVENT_SDR1BIRQ|EVENT_DMAIRQ),
				KAL_OR);		
		#endif	
		TurnOnMSDC();
		if(*(volatile kal_uint16*)MSDC_PS & MSDC_PS_PIN0)
		{
			if(gMSDC_Handle->ins_level == MSDC_IOCTRL_PULL_UP)
				gMSDC_Handle->mIsPresent = KAL_FALSE;	
			else
				gMSDC_Handle->mIsPresent = KAL_TRUE;	
		}
		else
		{
			if(gMSDC_Handle->ins_level == MSDC_IOCTRL_PULL_UP)
				gMSDC_Handle->mIsPresent = KAL_TRUE;
			else
				gMSDC_Handle->mIsPresent = KAL_FALSE;	
		}
		// use INT26 as the card detection, if the card is present during power on, then the 
		// card detection interrup of INT26 will always generated. This interrupt should be ignored.		
		if(pre_IsPresent && gMSDC_Handle->mIsPresent && gMSDC_Handle->mIsInitialized )
		{			
			pre_IsPresent = KAL_FALSE;
			gMSDC_Handle->mIsInitialized = KAL_TRUE;
			IRQUnmask(IRQ_MSDC_CD_CODE); 			
			return;			
		}
		else
			gMSDC_Handle->mIsInitialized = KAL_FALSE;					
		if(gMSDC_Handle->mIsPresent == KAL_FALSE)
		{
			MSDC_CLR_FIFO();
			MSDC_CLR_INT();
			MSDC_CLR_INT();
			//TurnOffMSDC();
			DMA_Stop(msdc_dmaport);		
		}
		#if !defined(FMT_NOT_PRESENT)
			MSDC_SendCardInd(MOD_FMT, SD_EXT);			
		#endif
		IRQUnmask(IRQ_MSDC_CD_CODE); 
		return;
	}
	#endif //USE_INT26_CARD_DETECTION	
	TurnOnMSDC();
	msc_sta = *(volatile kal_uint16*)MSC_STA;
	if(msc_sta & MSC_STA_SIF)
		kal_set_eg_events(MSDC_Events,EVENT_MSIFIRQ,KAL_OR);
	else
		kal_set_eg_events(MSDC_Events,EVENT_MSRDYIRQ,KAL_OR);

	msdc_int = *(volatile kal_uint16*)MSDC_INTR;
	#if !defined(USE_INT26_CARD_DETECTION)
	if(msdc_int & MSDC_INT_PINIRQ)
	{
		gMSDC_Handle->mIsInitialized = KAL_FALSE;	
		gMSDC_Handle->mIsChanged = KAL_TRUE;		
		kal_set_eg_events(MSDC_Events,
			(EVENT_MSIFIRQ|EVENT_DMAIRQ|EVENT_MSRDYIRQ),
			KAL_OR);								
		if(*(volatile kal_uint16*)MSDC_PS & MSDC_PS_PIN0)
		{
			if(gMSDC_Handle->ins_level == MSDC_IOCTRL_PULL_UP)
				gMSDC_Handle->mIsPresent = KAL_FALSE;	
			else
				gMSDC_Handle->mIsPresent = KAL_TRUE;	
		}
		else
		{
			if(gMSDC_Handle->ins_level == MSDC_IOCTRL_PULL_UP)
				gMSDC_Handle->mIsPresent = KAL_TRUE;
			else
				gMSDC_Handle->mIsPresent = KAL_FALSE;	
		}
		if(gMSDC_Handle->mIsPresent == KAL_FALSE)
		{			
			MSDC_CLR_FIFO();
			MSDC_CLR_INT();
			MSDC_CLR_INT();
			//TurnOffMSDC();
			DMA_Stop(msdc_dmaport);		
		}		//dbg_print("MSDC_HISR present %d \r\n",gMSDC_Handle->mIsPresent);					
		#if !defined(FMT_NOT_PRESENT)
			MSDC_SendCardInd(MOD_FMT, SD_EXT);		
		#endif		
		//MSDC_PDNControl(KAL_TRUE);	
	}
	#endif //USE_INT26_CARD_DETECTION
#else // sd/mmc
	#if defined (USE_INT26_CARD_DETECTION)
	#if defined(__SIM_PLUS__)
	{
		
		MSDC_Blk[SD_EXT].mIsInitialized = KAL_FALSE;				
		MSDC_Blk[SD_EXT].mIsChanged = KAL_TRUE;				
		if(*(volatile kal_uint16*)MSDC_PS & MSDC_PS_PIN0)
		{
			if(MSDC_Blk[SD_EXT].ins_level == MSDC_IOCTRL_PULL_UP)
				MSDC_Blk[SD_EXT].mIsPresent = KAL_FALSE;	
			else
				MSDC_Blk[SD_EXT].mIsPresent = KAL_TRUE;	
		}
		else
		{
			if(MSDC_Blk[SD_EXT].ins_level == MSDC_IOCTRL_PULL_UP)
				MSDC_Blk[SD_EXT].mIsPresent = KAL_TRUE;
			else
				MSDC_Blk[SD_EXT].mIsPresent = KAL_FALSE;	
		}
		/*bewlow comes after JRD SIM+ issue on 2007_03_08, give power, this should be temperary solution for jrd*/
		if(MSDC_NO_EXT_LDO != GPIO_EXT_SD_LDO_SWITCH){
			if(KAL_TRUE == gMSDC_Handle->mIsPresent)
				GPIO_WriteIO(1, GPIO_EXT_SD_LDO_SWITCH);
			else if(KAL_FALSE == gMSDC_Handle->mIsPresent)
				GPIO_WriteIO(0, GPIO_EXT_SD_LDO_SWITCH);
		}
		/*end of changes of JRD SIM+ issue on 2007_03_08*/
		if(MSDC_Blk[SD_EXT].mIsPresent == KAL_FALSE && current_card == SD_EXT)
		{
			MSDC_CLR_FIFO();
			MSDC_CLR_INT();
			MSDC_CLR_INT();
			DMA_Stop(msdc_dmaport);		
		}	
	#if !defined(FMT_NOT_PRESENT)
			MSDC_SendCardInd(MOD_FMT, SD_EXT);		
	#endif	
	#else // __SIM_PLUS__
	if(gMSDC_Handle->mIsChanged == KAL_TRUE)
	{	
		static kal_bool pre_IsPresent = KAL_TRUE; // it works only at first time
		
		if(pre_IsPresent)
			pre_IsPresent = gMSDC_Handle->mIsPresent;
		#if defined(MSDC_USE_INT)
		kal_set_eg_events(MSDC_Events,
				(EVENT_SDCMDIRQ|EVENT_SDDATIRQ|EVENT_SDMCIRQ|EVENT_SDR1BIRQ|EVENT_DMAIRQ),
				KAL_OR);		
		#endif	
		TurnOnMSDC();
		if(*(volatile kal_uint16*)MSDC_PS & MSDC_PS_PIN0)
		{
			if(gMSDC_Handle->ins_level == MSDC_IOCTRL_PULL_UP)
				gMSDC_Handle->mIsPresent = KAL_FALSE;	
			else
				gMSDC_Handle->mIsPresent = KAL_TRUE;	
		}
		else
		{
			if(gMSDC_Handle->ins_level == MSDC_IOCTRL_PULL_UP)
				gMSDC_Handle->mIsPresent = KAL_TRUE;
			else
				gMSDC_Handle->mIsPresent = KAL_FALSE;	
		}
		// use INT26 as the card detection, if the card is present during power on, then the 
		// card detection interrup of INT26 will always generated. This interrupt should be ignored.		
		if(pre_IsPresent && gMSDC_Handle->mIsPresent && gMSDC_Handle->mIsInitialized )
		{			
			pre_IsPresent = KAL_FALSE;
			gMSDC_Handle->mIsInitialized = KAL_TRUE;
			IRQUnmask(IRQ_MSDC_CD_CODE); 			
			return;			
		}
		else
			gMSDC_Handle->mIsInitialized = KAL_FALSE;					
		if(gMSDC_Handle->mIsPresent == KAL_FALSE)
		{
			MSDC_CLR_FIFO();
			MSDC_CLR_INT();
			MSDC_CLR_INT();
			//TurnOffMSDC();
			DMA_Stop(msdc_dmaport);		
		}
		#if !defined(FMT_NOT_PRESENT)
			MSDC_SendCardInd(MOD_FMT, SD_EXT);		
		#endif
		#endif // __SIM_PLUS__
		IRQUnmask(IRQ_MSDC_CD_CODE); 
		return;
	}
	#endif //USE_INT26_CARD_DETECTION
	TurnOnMSDC();		
	msdc_int = *(volatile kal_uint16*)MSDC_INTR;	
	#if defined(MSDC_USE_INT)
	if(msdc_int & MSDC_INT_SDCMDIRQ)
	{	
		kal_set_eg_events(MSDC_Events,EVENT_SDCMDIRQ,KAL_OR);
	}
	if(msdc_int & MSDC_INT_SDDATIRQ)
	{
		kal_set_eg_events(MSDC_Events,EVENT_SDDATIRQ,KAL_OR);
		
	}
	if(msdc_int & MSDC_INT_SDMCIRQ)
	{
		kal_set_eg_events(MSDC_Events,EVENT_SDMCIRQ,KAL_OR);
		
	}
	if(msdc_int & MSDC_INT_SDR1BIRQ)
	{
		kal_set_eg_events(MSDC_Events,EVENT_SDR1BIRQ,KAL_OR);		
	}
	#endif // MSDC_USE_INT
        	#if defined(__MSDC_SD_MMC__)&&defined(__MSDC_SD_SDIO__)
	/*SDIO*/
	if(msdc_int & MSDC_INT_SDIOIRQ)
	{	    
      SDIO_HISR_Entry();		   		 
	} 
	#endif 	
	#if !defined(USE_INT26_CARD_DETECTION)
	#if defined(__SIM_PLUS__)
	if(msdc_int & MSDC_INT_PINIRQ)
	{
		MSDC_Blk[SD_EXT].mIsInitialized = KAL_FALSE;				
		MSDC_Blk[SD_EXT].mIsChanged = KAL_TRUE;				
		if(*(volatile kal_uint16*)MSDC_PS & MSDC_PS_PIN0)
		{
			if(MSDC_Blk[SD_EXT].ins_level == MSDC_IOCTRL_PULL_UP)
				MSDC_Blk[SD_EXT].mIsPresent = KAL_FALSE;	
			else
				MSDC_Blk[SD_EXT].mIsPresent = KAL_TRUE;	
		}
		else
		{
			if(MSDC_Blk[SD_EXT].ins_level == MSDC_IOCTRL_PULL_UP)
				MSDC_Blk[SD_EXT].mIsPresent = KAL_TRUE;
			else
				MSDC_Blk[SD_EXT].mIsPresent = KAL_FALSE;	
		}
		/*bewlow comes after JRD SIM+ issue on 2007_03_08, give power, this should be temperary solution for jrd*/
		if(MSDC_NO_EXT_LDO != GPIO_EXT_SD_LDO_SWITCH){
			if(KAL_TRUE == gMSDC_Handle->mIsPresent)
				GPIO_WriteIO(1, GPIO_EXT_SD_LDO_SWITCH);
			else if(KAL_FALSE == gMSDC_Handle->mIsPresent)
				GPIO_WriteIO(0, GPIO_EXT_SD_LDO_SWITCH);
		}
		/*end of changes of JRD SIM+ issue on 2007_03_08*/
		if(MSDC_Blk[SD_EXT].mIsPresent == KAL_FALSE && current_card == SD_EXT)
		{
			MSDC_CLR_FIFO();
			MSDC_CLR_INT();
			MSDC_CLR_INT();
			DMA_Stop(msdc_dmaport);		
		}	
	#if !defined(FMT_NOT_PRESENT)
			MSDC_SendCardInd(MOD_FMT, SD_EXT);		
	#endif	
	#else // __SIM_PLUS__
	if(msdc_int & MSDC_INT_PINIRQ)
	{
		gMSDC_Handle->mIsInitialized = KAL_FALSE;				
		gMSDC_Handle->mIsChanged = KAL_TRUE;				
		#if defined(MSDC_USE_INT)
		kal_set_eg_events(MSDC_Events,
				(EVENT_SDCMDIRQ|EVENT_SDDATIRQ|EVENT_SDMCIRQ|EVENT_SDR1BIRQ|EVENT_DMAIRQ),
				KAL_OR);		
		#endif						
		if(*(volatile kal_uint16*)MSDC_PS & MSDC_PS_PIN0)
		{
			if(gMSDC_Handle->ins_level == MSDC_IOCTRL_PULL_UP)
				gMSDC_Handle->mIsPresent = KAL_FALSE;	
			else
				gMSDC_Handle->mIsPresent = KAL_TRUE;	
		}
		else
		{
			if(gMSDC_Handle->ins_level == MSDC_IOCTRL_PULL_UP)
				gMSDC_Handle->mIsPresent = KAL_TRUE;
			else
				gMSDC_Handle->mIsPresent = KAL_FALSE;	
		}
		if(gMSDC_Handle->mIsPresent == KAL_FALSE)
		{
			MSDC_CLR_FIFO();
			MSDC_CLR_INT();
			MSDC_CLR_INT();
			//TurnOffMSDC();
			DMA_Stop(msdc_dmaport);		
		}	
		#if !defined(FMT_NOT_PRESENT)
			MSDC_SendCardInd(MOD_FMT, SD_EXT);		
		#endif
		#endif // __SIM_PLUS__
		// Set the power down bit too fast will cause MSDC failed to detect next card plug in/out
		// So, move it to GetCardStatus
		//MSDC_PDNControl(KAL_TRUE);
	}	
	#endif // USE_INT26_CARD_DETECTION
	#endif // MSDC_MS
#ifndef DRV_LSD
#ifndef __SDC_SPI_INTERFACE__
	IRQUnmask(void)(IRQ_MSDC_CODE);		
#endif
#endif
}
/*************************************************************************
* FUNCTION
*  MSDC_DMA_Callback
*
* DESCRIPTION
*	Call back while DMA has done the data transfer.
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*	
*
*************************************************************************/
void MSDC_DMA_Callback(void)
{
	kal_set_eg_events(MSDC_Events,EVENT_DMAIRQ,KAL_OR);			
}

#if defined(__SIM_PLUS__)
void MSDC_Switch_Card(sd_select_enum sel)
{
	if(current_card == sel)
		return;
	
	ENTER_CRITICAL();
	current_card = sel;	

	
	/*bewlow comes after JRD SIM+ issue on 2007_03_08, use custom setting instead of fix value*/
	if(GPIO_SELECT_MSDC == sel)
		GPIO_WriteIO(MSDC_GetSwitchDirection(), GPIO_SIM_MSDC_SWITCH);
	else if(GPIO_SELECT_SIM == sel)
		GPIO_WriteIO(1-MSDC_GetSwitchDirection(), GPIO_SIM_MSDC_SWITCH);
	else
		ASSERT(0);
	/*end of changes of JRD SIM+ issue on 2007_03_08*/
	
	gMSDC_Handle = &MSDC_Blk[sel];
	gSD = &gSD_blk[sel];
	EXIT_CRITICAL();
	
	if(MSDC_Blk[SD_EXT].mIsInitialized || MSDC_Blk[SD_SIM].mIsInitialized)
	{
		//MSDC_SetClock(gMSDC_Handle->op_clock);
		if(gSD->bus_width == 4)
			MSDC_SET_BIT32(SDC_CFG,SDC_CFG_MDLEN);
		else
			MSDC_CLR_BIT32(SDC_CFG,SDC_CFG_MDLEN);
	}		
}
#endif

#endif //end of MSDC_INT
#endif // end of  (defined(__MSDC_MS__) || defined(__MSDC_SD_MMC__))

⌨️ 快捷键说明

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