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

📄 msdc.c

📁 8032底层驱动部分。因为可以移植 所以单独来拿出来
💻 C
📖 第 1 页 / 共 3 页
字号:
	{
		msdc_input.type = DMA_HWRX;	
		if(count <= MSDC_READ_THD_POLL)
		//if(0)
		{
			msdc_input.callback = NULL;
			is_poll = KAL_TRUE;
		}
		else
		{
			msdc_input.callback = MSDC_DMA_Callback;
			is_poll = KAL_FALSE;
		}
	}
	if(kal_query_systemInit() == KAL_TRUE)
	{
		msdc_input.callback = NULL;
		is_poll = KAL_TRUE;
	}	
	if(adrs%4 == 0)
	{
		is_aligned = KAL_TRUE;
		total_count = count;
	}
	else
	{
		is_aligned = KAL_FALSE;
		total_count = count<<2;
	}
	gMSDC_Handle.total_count = total_count;
	gMSDC_Handle.is_poll = is_poll;
	gMSDC_Handle.is_aligned = is_aligned;
	{
		if(is_aligned)
		{
			#if defined(USE_DMA_BURST)
			MSDC_SET_FIFO(4);
			#else
			msdc_menu.TMOD.burst_mode = KAL_FALSE;
			#endif
			
			msdc_input.count = (total_count > 65024)?(65024):(total_count);
			msdc_input.size = DMA_LONG;		
			DMA_Config_B2W(msdc_dmaport,&msdc_input,KAL_TRUE,KAL_FALSE);
			msdc_menu.addr += msdc_input.count*4;
		}
		else
		{
			#if defined(USE_DMA_BURST)
			MSDC_SET_FIFO(1);
			#else
			
			msdc_menu.TMOD.burst_mode = KAL_TRUE;
			#endif
			msdc_input.count = (total_count > 65024)?(65024):(total_count);
			msdc_input.size = DMA_BYTE;
			DMA_Config_B2W(msdc_dmaport,&msdc_input,KAL_TRUE,KAL_TRUE);
			msdc_menu.addr += msdc_input.count;
		}
		
	}
}
kal_uint32 MSDC_DMATransferFinal(void)
{
	kal_uint32 total_count = gMSDC_Handle.total_count, t1;
	kal_bool is_poll = gMSDC_Handle.is_poll;
	kal_bool is_aligned = gMSDC_Handle.is_aligned;

	t1 = drv_get_current_time();
	if(gMSDC_Handle.timeout_period > MSDC_TIMEOUT_PERIOD_DAT)
		gMSDC_Handle.timeout_period = MSDC_TIMEOUT_PERIOD_DAT;
	MSDC_START_TIMER(gMSDC_Handle.timeout_period);
	if(is_poll)
	{
		while(IS_MSDC_DMA_RUN && 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;
		}
	}
	else
	{
		kal_uint32 flags;
		kal_retrieve_eg_events(MSDC_Events,(EVENT_DMAIRQ),KAL_OR_CONSUME,&flags,KAL_SUSPEND);				
	}				
	MSDC_STOP_TIMER();
	total_count -= msdc_input.count;
	if(total_count == 0)
		return MSDC_NOERROR;
	
	while(1)
	{
		if(is_aligned)
		{
			#if defined(USE_DMA_BURST)
			MSDC_SET_FIFO(4);
			#else
			msdc_menu.TMOD.burst_mode = KAL_FALSE;
			#endif
			
			msdc_input.count = (total_count > 65024)?(65024):(total_count);
			msdc_input.size = DMA_LONG;		
			DMA_Config_B2W(msdc_dmaport,&msdc_input,KAL_TRUE,KAL_FALSE);
			msdc_menu.addr += msdc_input.count*4;
			gMSDC_Handle.timeout_period = 1 + (msdc_input.count>>7);
		}
		else
		{
			#if defined(USE_DMA_BURST)
			MSDC_SET_FIFO(1);
			#else
			
			msdc_menu.TMOD.burst_mode = KAL_TRUE;
			#endif
			msdc_input.count = (total_count > 65024)?(65024):(total_count);
			msdc_input.size = DMA_BYTE;
			DMA_Config_B2W(msdc_dmaport,&msdc_input,KAL_TRUE,KAL_TRUE);
			msdc_menu.addr += msdc_input.count;
			gMSDC_Handle.timeout_period = 1 + (msdc_input.count>>9);
		}
		
		// wait until running bit clr
		if(msdc_input.type == DMA_HWTX)
			gMSDC_Handle.timeout_period <<= 2 ;
		if(gMSDC_Handle.mMSDC_type == MMC_CARD)
			gMSDC_Handle.timeout_period <<= 1;
		
		t1 = drv_get_current_time();
		MSDC_START_TIMER(gMSDC_Handle.timeout_period);
		if(is_poll)
		{
			while(IS_MSDC_DMA_RUN && MSDC_Check_Card_Present() && !gMSDC_Handle.is_timeout)
			{
				if(drv_get_duration_ms(t1) > gMSDC_Handle.timeout_period*11)
					gMSDC_Handle.is_timeout = KAL_TRUE;				
			}
		}
		else
		{
			kal_uint32 flags;
			kal_retrieve_eg_events(MSDC_Events,(EVENT_DMAIRQ),KAL_OR_CONSUME,&flags,KAL_SUSPEND);				
		}				
		MSDC_STOP_TIMER();
		if(IS_MSDC_DMA_RUN && gMSDC_Handle.is_timeout)
			return MSDC_GPT_TIMEOUT_ERR;
		total_count -= msdc_input.count;
		if(total_count == 0)
			break;		
	}
	
	return MSDC_NOERROR;
}

#endif // DMA

#ifdef MSDC_INT

#ifdef USE_INT26_CARD_DETECTION
void MSDC_CardDetect_LISR(void)
{
	IRQMask(IRQ_MSDC_CD_CODE);
	gMSDC_Handle.mIsChanged = KAL_TRUE;
	drv_active_hisr(DRV_MSDC_HISR_ID);
}
#endif //USE_INT26_CARD_DETECTION

/*************************************************************************
* FUNCTION
*  MSDC_INT_Init
*
* DESCRIPTION
*	Initialize MSDC's interrupt
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*	
*
*************************************************************************/
void MSDC_INT_Init(void)
{
   MSDC_Events = kal_create_event_group("MSDC Events");
   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
   
}
void MSDC_LISR(void)
{
	IRQMask(IRQ_MSDC_CODE);
	drv_active_hisr(DRV_MSDC_HISR_ID);
}
/*************************************************************************
* 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;
	
	#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);			
		#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);			
		#endif		
		//MSDC_PDNControl(KAL_TRUE);	
	}
	#endif //USE_INT26_CARD_DETECTION
#else // sd/mmc
	#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);			
		#endif
		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(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);			
		#endif
		// 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
	IRQUnmask(IRQ_MSDC_CODE);				
}
/*************************************************************************
* 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);			
}

#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 + -