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

📄 sdio_drv.c

📁 SDIO实现底层驱动文件.非常有用.经典!
💻 C
📖 第 1 页 / 共 4 页
字号:
	}

	// send cmd53	   
   //if(p->rw == SDIO_WRITE)
   if(0)/*R1b*/
   {
      cmd &= ~0x380;
      cmd |= 0x380;
   }   
   else/*R1*/
   {
       cmd &= ~0x380;
      cmd |= 0x80;      
   }      
	if((status = SD_Send_Cmd_poll(cmd, arg))!=NO_ERROR)
	{ 
	   goto ERROR_EXIT;		
	}		
	MSDC_ReadReg32(SDC_RESP0,&status);	
	status = (status & 0xff00)>>8;
	gSDIO.resp = status;   			
	/* start data transfer*/
	if(p->rw == SDIO_READ)
	{

		if(p->block)
		{
			kal_uint32 total;

			total = (p->count*gSDIO.block_size[p->func]+3)>>2;
			for(i=0;i< total;)
			{
			      
				if(!MSDC_IS_FIFO_EMPTY)
				{
					*(ptr+i) = *(volatile kal_uint32*)MSDC_DAT;
					i++;
					if(i%((gSDIO.block_size[p->func]+3) >> 2)==0)
				{
					debug_flag = 1;
					if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
					   goto ERROR_EXIT;					
				}
			}
				
			}
		}
		else
		{
			for(i=0;i< (p->count+3)>>2;)
			{			      
				if(!MSDC_IS_FIFO_EMPTY)
				{
					*(ptr+i) = *(volatile kal_uint32*)MSDC_DAT;
					i++;
					if(i%((p->count+3)>> 2)==0)
				{
					debug_flag = 1;
					if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
					   goto ERROR_EXIT;					
				}
			}

		}

		}
	}
	else
	{	// SDIO_WRITE
		if(p->block)
		{
			kal_uint32 total;

			total = (p->count*gSDIO.block_size[p->func]+3)>>2;
			for(i=0;i< total;)
			{			      			      
				if(!MSDC_IS_FIFO_FULL)
				{
					*(volatile kal_uint32*)MSDC_DAT = *(ptr+i);
					i++;
					if(i%((gSDIO.block_size[p->func]+3) >> 2)==0)
				{
					debug_flag = 1;
					if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
					   goto ERROR_EXIT;					
				}
				}
				

			}
		}
		else
		{
			for(i=0;i< (p->count+3)>>2;)
			{			   
				if(!MSDC_IS_FIFO_FULL)
				{
					*(volatile kal_uint32*)MSDC_DAT = *(ptr+i);
					i++;
					if(i%((p->count+3) >> 2)==0)
				{
					debug_flag = 1;
					if((status=SDIO_WaitDatRdyOrTo())!=NO_ERROR)
					   goto ERROR_EXIT;						     
				}
			}

		}

		}
	}   	
	if(p->block)
	  SD_StopTrans_poll();
   SDIO_stop();	
	return NO_ERROR;
	ERROR_EXIT:
   {  
      kal_uint32 tmp;      
      #ifdef MSDC_DMA  
      DisableMSDC_DMA();
      #endif
      if(p->block)
	      SD_StopTrans_poll();
      SDIO_stop();
		MSDC_ReadReg32(SDC_CMDSTA,&tmp);
		MSDC_ReadReg32(SDC_DATSTA,&tmp);
		MSDC_CLR_FIFO();    
   	return status;
   }
}
/*************************************************************************
* FUNCTION
*  SDIO_Cmd52
*
* DESCRIPTION
*	IO_RW_DIRECT command
*
* PARAMETERS
*  command 52 structrue
*
* RETURNS
*  SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*	
*************************************************************************/
/* refer to the IO_RW_DIRECT command (CMD52) in SDIO 1.1 chapter 5.1*/
SDC_CMD_STATUS SDIO_Cmd52(cmd52_config_struct *p)
{
	SDC_CMD_STATUS status;
	kal_uint32 arg = 0;
	kal_uint32 cmd;	
   
   IRQMask(IRQ_MSDC_CODE);
	if(p->rw == SDIO_WRITE)
	{
		arg |= (IO_ARG_RW_FLAG|p->data);
	}
	arg |= ((p->raw << 27)|(p->func << 28)|(p->adrs <<9));

	cmd = SDC_CMD_CMD52 ;
	if(p->stop)
		cmd |= SDC_CMD_STOP;
      
   if(p->stop)
    //if(0)
    {
      cmd &= ~0x380;
      cmd |= 0x380;
   }   
   #if 1
   else
   {
      cmd &= ~0x380;
      cmd |= 0x80;      
   }    
   #endif
	if((status = SD_Send_Cmd_poll(cmd, arg))!=NO_ERROR)
		goto ERROR_EXIT;         		
	while(*(volatile kal_uint16*)(SDC_STA) & SDC_STA_R1BSY);	
	MSDC_ReadReg32(SDC_RESP0,&status);
	if(p->rw == SDIO_READ)
	{
		p->data = status & 0xff;
	}
	status = (status & 0xff00)>>8;
	gSDIO.state = (status & 0x30)>>4;	
	gSDIO.resp = status;	
	IRQUnmask(IRQ_MSDC_CODE);   
   return NO_ERROR;   
   ERROR_EXIT:
   {
      kal_uint32 tmp;
		MSDC_ReadReg32(SDC_CMDSTA,&tmp);
		MSDC_CLR_FIFO();
      IRQUnmask(IRQ_MSDC_CODE);	   
   	return status;
   }	
	
	
}
SDC_CMD_STATUS SDIO_Cmd52_isr(cmd52_config_struct *p)
{
	SDC_CMD_STATUS status;
	kal_uint32 arg = 0;
	kal_uint32 cmd;

	if(p->rw == SDIO_WRITE)
	{
		arg |= (IO_ARG_RW_FLAG|p->data);
	}
	arg |= ((p->raw << 27)|(p->func << 28)|(p->adrs <<9));

	cmd = SDC_CMD_CMD52 ;
	if(p->stop)
		cmd |= SDC_CMD_STOP;
	   if(p->stop)
    //if(0)
    {
      cmd &= ~0x380;
      cmd |= 0x380;
   }   
   #if 1
   else
   {
      cmd &= ~0x380;
      cmd |= 0x80;      
   }    
   #endif	
	if((status = SD_Send_Cmd_poll(cmd, arg))!=NO_ERROR)		
		goto ERROR_EXIT;	
   while(*(volatile kal_uint16*)(SDC_STA) & SDC_STA_R1BSY);
	MSDC_ReadReg32(SDC_RESP0,&status);
	if(p->rw == SDIO_READ)
	{
		p->data = status & 0xff;
	}
	status = (status & 0xff00)>>8;
	gSDIO.state = (status & 0x30)>>4;	
	gSDIO.resp = status;   
	return NO_ERROR;   
	/*error handle*/
   ERROR_EXIT:
   {  
      kal_uint32 tmp;  
		MSDC_ReadReg32(SDC_CMDSTA,&tmp);
		MSDC_CLR_FIFO();      
   	return status;
   }		

}   

/* for SDIO*/
/*************************************************************************
* FUNCTION
*  SDIO_Cmd5
*
* DESCRIPTION
*	SDIO initialization command
*
* PARAMETERS
*
*
* RETURNS
*  SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*	it is similar to the operation of ACMD41 for SD memory cards.
*
*************************************************************************/
SDC_CMD_STATUS SDIO_Cmd5(kal_uint32 ocr)
{
	SDC_CMD_STATUS status;     
   
	if((status = SD_Send_Cmd_poll(SDC_CMD_CMD5,ocr))!=NO_ERROR)	
		return status;

	/*read R4*/
	MSDC_ReadReg32(SDC_RESP0,&status);
	gSDIO.ocr = status &0xFFFFFF;
	status >>= 24;
	gSDIO.num_func = (kal_uint8)(status & 0x70) >> 4;	
	gSDIO.mem_present = ((status & 0x08) != 0) ;	
	gSDIO.io_ready = ((status & SDIO_R4_CARD_READY)!=0);
	#ifdef _SDIO_DEBUG_
	dbg_print("card function number %d\r\n", gSDIO.num_func);							
	dbg_print("memory card present %d\r\n", gSDIO.mem_present);						
	dbg_print("card ready %d\r\n", gSDIO.io_ready);	
	#endif
	return NO_ERROR;
}

void SDIO_dispatch_IO(SDIO_function_id_enum function)   
{
   /*single function*/   
   kal_take_mutex(sdio_mutex);    
   /*multiple function*/
   /*not support now*/
}

void SDIO_resume_IO(SDIO_function_id_enum function)   
{
   /*single function*/   
   kal_give_mutex(sdio_mutex);    
   /*multiple function*/
   /*not support now*/
   
}
/*************************************************************************
* FUNCTION
*  SDIO_read_CIS
*
* DESCRIPTION
*	This function is to read function's CIS
*
* PARAMETERS
*  function: function id
*
* RETURNS
*  SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*	This function is only user for SDIO bus driver
*
*************************************************************************/
SDC_CMD_STATUS SDIO_read_CIS(SDIO_function_id_enum function)
{
   kal_uint32 i=0, j=0;
   SDC_CMD_STATUS status;
   cmd52_config_struct cmd52;      
   ASSERT(function<8);          
   /* read all configuration register of CCCR*/
   while(1)
   {
	   cmd52.rw = SDIO_READ;
	   cmd52.func = function;
	   cmd52.raw = KAL_FALSE;
	   cmd52.stop = KAL_FALSE;
	   if(function==0)
	      cmd52.adrs =(kal_uint32)((sdio_cccr_reg[11]<<16)|(sdio_cccr_reg[10]<<8)|
	                                      (sdio_cccr_reg[9]<<8)+i);
	   else 
	      cmd52.adrs =(kal_uint32)((sdio_fbr_reg[11]<<16)|(sdio_fbr_reg[10]<<8)|
	                                      (sdio_fbr_reg[9]<<8)+i);
	   cmd52.data = 0;
	   if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
	      return status;
	   sdio_tuple[function][i]=cmd52.data;
	   i++;
	   if(cmd52.data==CISTPL_NULL||cmd52.data==CISTPL_END)
	      return NO_ERROR;
	   else
	   {
	      kal_uint32 tuple_size=0;
	      cmd52.rw = SDIO_READ;	      
	      cmd52.raw = KAL_FALSE;
	      cmd52.stop = KAL_FALSE;
	      cmd52.adrs++;
	      if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
	         return status;
	      sdio_tuple[function][i]=cmd52.data;	      
	      tuple_size=cmd52.data;
	      i++;
	      for(j=0;j<tuple_size;j++)
	      {
	         cmd52.adrs++;
	         if((status = SDIO_Cmd52(&cmd52))!=NO_ERROR)
	            return status;
	         sdio_tuple[function][i]=cmd52.data;	      
	         i++;
	      }      
	   }         
	}   
}
/*************************************************************************
* FUNCTION
*  SDIO_read_CCCR_ver
*
* DESCRIPTION
*	This function is to read card's CCCR version 
*
* PARAMETERS
*  *version
*
* RETURNS
*  SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*	
*
*************************************************************************/   
/*read SDIO CCCR version*/
SDC_CMD_STATUS SDIO_read_CCCR_ver(kal_uint8 *version)
{
   SDC_CMD_STATUS status=NO_ERROR;
      
   #if 1
   *version=sdio_cccr_reg[0]&SDIO_CCCR_VERISON_MASK;	   
   #else  
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
	#endif
	return status;
	
}

SDC_CMD_STATUS SDIO_stop(void)
{
   SDC_CMD_STATUS status=NO_ERROR;
         
   cmd52_config_struct cmd52;   
   cmd52.rw = SDIO_WRITE;
	cmd52.func = 0;
	cmd52.raw = KAL_FALSE;
	cmd52.stop = KAL_TRUE;
	cmd52.adrs = 6;
	cmd52.data = 1;
	status = SDIO_Cmd52(&cmd52);	   
	/*wait card is not busy*/	
   SDIO_WaitCardNotBusy();		
	return status;	
}
SDC_CMD_STATUS SDIO_WaitDatRdyOrTo(void)
{
	// maybe have to add a timer
	register kal_uint16 sdc_datsta = 0;

	int counter = 0;
	//while(DRV_Reg(SDC_STA)&0x4){};
	do{
		sdc_datsta = *(volatile kal_uint16*)SDC_DATSTA;
		if(sdc_datsta & SDC_DATSTA_DATTO)
			return ERR_DAT_TIMEOUT;
		else if(sdc_datsta & SDC_DATSTA_DATCRCERR)
			return ERR_DAT_CRCERR;
		else if(sdc_datsta & SDC_DATSTA_BLKDONE)
			break;
	}while(1);//(counter++  < 1000);

	if (counter >= 1000)
		return ERR_NORESP;
	return NO_ERROR;
}
/*************************************************************************
* FUNCTION
*  SDIO_read_SDIO_ver
*
* DESCRIPTION
*	This function is to read card's SDIO version 
*
* PARAMETERS
*  *version
*
* RETURNS
*  SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*	
*
*************************************************************************/   
/*read SDIO spec version*/
SDC_CMD_STATUS SDIO_read_SDIO_ver(kal_uint8 *version)
{
   SDC_CMD_STATUS status=NO_ERROR;
   
   #if 1
   *version=sdio_cccr_reg[0]&SDIO_VERISON_MASK>>SDIO_VERISON_SHIFT;	
   #else
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
	#endif
	return status;
	
}   
/*************************************************************************
* FUNCTION
*  SDIO_read_SD_ver
*
* DESCRIPTION
*	This function is to read card's SD version 
*
* PARAMETERS
*  *version
*
* RETURNS
*  SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*	
*
*************************************************************************/
/*read SD spec version*/
SDC_CMD_STATUS SDIO_read_SD_ver(kal_uint8 *version)
{
   SDC_CMD_STATUS status=NO_ERROR;
   
   #if 1
   *version=sdio_cccr_reg[1]&SDIO_SD_VERISON_MASK;	
   #else
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
	#endif
	return status;
}   
/*************************************************************************
* FUNCTION
*  SDIO_read_CCCR
*
* DESCRIPTION
*	This function is to read card CCCR
*
* PARAMETERS
*  *version
*
* RETURNS
*  SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*	only used for SDIO bus driver
*************************************************************************/
SDC_CMD_STATUS SDIO_read_CCCR(void)
{
   #if 1
   kal_uint32 i;
    SDC_CMD_STATUS status;
   cmd52_config_struct cmd52;      
   cmd52.rw = SDIO_READ;
	cmd52.func = 0;
	cmd52.raw = KAL_FALSE;
	cmd52.stop = KAL_FALSE;
	for(i=0;i<SDIO_CCCR_SIZE;i++)
	{
	   cmd52.adrs =i;
	   status = SDIO_Cmd52(&cmd52);	
	   sdio_cccr_reg[i]=cmd52.data;	   
	}   
   #else
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
	#endif
	return status;
}
/*************************************************************************
* FUNCTION
*  SDIO_read_FBR
*
* DESCRIPTION
*	This function is to read card FBR
*
* PARAMETERS
*  function: function id
*
* RETURNS
*  SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*	only used for SDIO bus driver
*************************************************************************/
SDC_CMD_STATUS SDIO_read_FBR(SDIO_function_id_enum function)
{
   #if 1  /*to cover 5911 issue*/ 
   SDC_CMD_STATUS status;   
   cmd52_config_struct cmd52;   
   kal_uint32 i=0;
      
   cmd52.rw = SDIO_READ;
	cmd52.func = 0;
	cmd52.raw = KAL_FALSE;
	cmd52.stop = KAL_FALSE;	
	cmd52.data = 0;
	for(i=0;i<SDIO_FBR_SIZE;i++)

⌨️ 快捷键说明

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