📄 sdio_drv.c
字号:
}
// 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 + -