📄 mmccmd.c
字号:
if(ret)
return ret;
_MMCGetResponses(&rp,MMCB_R2);
for(i=0;i<16;i++)
{
pBuff[i]=rp.CID[i];
}
return 0;
}
/******************************************************************************
Function Name : _MMCStopTransmission()
Input Parameters : VOID
Output Parameters: VOID
Value returned : int 0: Sucessful operation, others: meet Error
Description : CMD12: Forces the card to stop transmission
Cautions :
Prev Condition : VOID
Post Condition : VOID
******************************************************************************/
MMC_STATUS _MMCStopTransmission()
{
MMC_RESPONSES rp;
MMC_STATUS ret;
ret=_MMCNoDataCommand(MMC_CMD12,0,MMCB_R1);
if(ret)
return ret;
_MMCGetResponses(&rp,MMCB_R1);
return rp.status&MMC_STATUS_NOERROR;
}
/******************************************************************************
Function Name : _MMCSendStatus(U32 addr,P_U32 pStatus)
Input Parameters : U32 addr relative address
Output Parameters: VOID
Value returned : U32 Card Status
Description : CMD13 addressed card sends its status register
Cautions :
Prev Condition : VOID
Post Condition : VOID
******************************************************************************/
U32 _MMCSendStatus(U32 addr,P_U32 pStatus)
{
MMC_RESPONSES rp;
MMC_STATUS ret;
ret=_MMCNoDataCommand(MMC_CMD13,addr<<16,MMCB_R1);
if(ret)
return ret;
_MMCGetResponses(&rp,MMCB_R1);
*pStatus=rp.status;
return rp.status&MMC_STATUS_NOERROR;
}
/******************************************************************************
Function Name : _MMCSendSCR()
Input Parameters : VOID
Output Parameters: VOID
Value returned : int 0: Sucessful operation, others: meet Error
Description : ACMD51 Read the SD Configuration Register(SCR)
Cautions :
Prev Condition : VOID
Post Condition : VOID
******************************************************************************/
MMC_STATUS _SDSendStatus(P_U8 pBuff)
{
MMC_RESPONSES rp;
MMC_STATUS ret;
int i=0;
U16 status;
P_U16 pbuff;
pbuff=(P_U16)pBuff;
while(_MMCIsRun())
_MMCStopClk();
_MMCSetCmd(MMC_CMD13,_gCardInfo.card_adr,MMCB_DATEN|MMCB_R1);
*(P_U16)MMCR_INT_MASK=(~MMC_CMD_DONE)&0xF;
_gMMCIsIrpt=1;
_MMCStartClk();
while(_gMMCIsIrpt)i++; //wait for CMD_DONE interrupt
TRACE(" CMD Result: 0x%04X,wait time %d\n",(*(P_U16)MMCR_STATUS),i); //TEST omit response CRC Error
ret=(*(P_U16)MMCR_STATUS)&MMC_CMD_TIMEOUT; //Time Out Error
if(ret)
{ _MMCStopClk();
return ret;
}
while((*((P_U16)MMCR_STATUS)&0x800)==0)
{ //If Fifo is empty
ret=(*((P_U16)MMCR_STATUS))&0x1;
if( ret )
return ret;
}
for(i=0;i<MMC_BLOCK_SIZE/(sizeof(U16));i++)
{
//If MMC meet Time-Out of Response or CRC Read Error.
if( ret )
{
TRACE(" Read SCR Time Out\n");
break;
}
*pbuff=*((P_U16)(MMCR_BUFFER_ACCESS)); //data tranferring
pbuff++;
}
_MMCStopClk();
return ret;
}
/******************************************************************************
Function Name : _MMCSetBlockLen(U32 size)
Input Parameters : U32 size block size
Output Parameters: VOID
Value returned : int 0: Sucessful operation, others: meet Error
Description : CMD16 sets the block length (in bytes) for all following
block commands(read and write). Default block length
is specified in the CSD.
Cautions :
Prev Condition : VOID
Post Condition : VOID
******************************************************************************/
MMC_STATUS _MMCSetBlockLen(U32 size)
{
MMC_RESPONSES rp;
MMC_STATUS ret;
_MMCSetBlockLenReg(size);
_MMCSetNumberOfBlockReg(1);
ret=_MMCNoDataCommand(MMC_CMD16,size,MMCB_R1);
if(ret)
return ret;
_MMCGetResponses(&rp,MMCB_R1);
return rp.status&MMC_STATUS_NOERROR;
}
/******************************************************************************
Function Name :MMC_STATUS _MMCReadBlock(P_MMC_CARD_INFO pCurrentCardInfo,U32 start_addr,U16 nsects, P_U8 buff );
Input Parameters : U32 addr address
P_U8 buff data buff
Output Parameters: VOID
Value returned : int 0: Sucessful operation, others: meet Error
Description : CMD17 or CMD18 reads a block of the size selected by the Set_Block
command
Cautions :
Prev Condition : VOID
Post Condition : VOID
******************************************************************************/
MMC_STATUS _MMCReadBlock(P_MMC_CARD_INFO pCurrentCardInfo,U32 addr,U16 nsects, P_U8 buff )
{
MMC_RESPONSES rp;
MMC_STATUS ret;
int i=0;
U16 status;
P_U16 pbuff;
U8 cmd;
U32 length;
pbuff=(P_U16)buff;
while(_MMCIsRun())
_MMCStopClk();
if(nsects==1)
cmd=MMC_CMD17;
else
cmd=MMC_CMD18;
_MMCSetNumberOfBlockReg(nsects);
if(pCurrentCardInfo->buswidth&SD_BUS_WIDTH4)
_MMCSetCmd(cmd,addr,MMCB_BUSW|MMCB_DATEN|MMCB_R1);
else
_MMCSetCmd(cmd,addr,MMCB_DATEN|MMCB_R1);
// *(P_U16)MMCR_INT_MASK=(~MMC_CMD_DONE)&0xF;
*(P_U16)MMCR_INT_MASK=0xF;
_gMMCIsIrpt=1;
*(P_U16)MMCR_STR_STP_CLK=0x06; //start clk
//while(_gMMCIsIrpt)i++; //wait for CMD_DONE interrupt
while(!((*(P_U16)MMCR_STATUS)&0x2000))i++;
TRACE(" CMD Result: 0x%04X,wait time %d\n",(*(P_U16)MMCR_STATUS),i); //TEST omit response CRC Error
ret=(*(P_U16)MMCR_STATUS)&MMC_CMD_TIMEOUT; //Time Out Error
if(ret)
{ _MMCStopClk();
return ret;
}
/*because block size is always larger than FIFO Size, after command done,there are not anthor interrupt
before start transfer. */
_gMMCIsIrpt=1;
*(P_U16)MMCR_INT_MASK=~MMC_DATA_TRANS_DONE;
if(_gMMCDMAChannel!=0xFF) //Use DMA
{
// Start DMA
_gMMCIsTransferDone=0;
if(_DmaStartTransfer(_gMMCDMAChannel,((P_VOID)MMCR_BUFFER_ACCESS),buff,MMC_BLOCK_SIZE*nsects,DMA_IOTOMEM)
==SYS_OK)
{ ret=_MMCWaitDataTransDone(); //wait DMA tranferring over
ret|= (*(P_U16)MMCR_STATUS)&0xF;
_MMCStopClk();
return ret;
}
}
TRACE("Don't Use DMA Transfer Data\n");
length=nsects*MMC_BLOCK_SIZE/sizeof(U16);
for(i=0;i<length;i++)
{
if(i>0&&((i&0xFF)==0)) //if(i>0 && i%256==0)
_MMCStartClk();
if((*((P_U16)MMCR_STATUS)&0x40)!=0)//If Fifo is empty
while((*((P_U16)MMCR_STATUS)&0x80)==0) //wait for buff full
{
ret=(*((P_U16)MMCR_STATUS))&0x1;
if( ret )
break;
}
//If MMC meet Time-Out of Response or CRC Read Error.
if( ret )
{
TRACE(" Read Data Time Out\n");
break;
}
*pbuff=*((P_U16)(MMCR_BUFFER_ACCESS)); //data tranferring
pbuff++;
}
i=0;
while(!((*(P_U16)MMCR_STATUS)&0x800))i++; //wait data transfer done
ret|= (*(P_U16)MMCR_STATUS)&0xF;
_MMCStopClk();
return ret;
}
/******************************************************************************
Function Name : MMC_STATUS _MMCWriteBlock(P_MMC_CARD_INFO,U32 start_addr,U16 nsects, P_U8 buff );
Input Parameters : U32 addr address
P_U8 buff data buff
Output Parameters: VOID
Value returned : int 0: Sucessful operation, others: meet Error
Description : CMD24 : Write a block of the size selected by the
Set_Block command
Cautions :
Prev Condition : VOID
Post Condition : VOID
******************************************************************************/
MMC_STATUS _MMCWriteBlock(P_MMC_CARD_INFO pCurrentCardInfo,U32 addr,U16 nsects, P_U8 buff )
{
MMC_RESPONSES rp;
int i=0;
U16 status;
U8 cmd;
U32 length;
MMC_STATUS ret;
if(nsects==1)
cmd=MMC_CMD24;
else
cmd=MMC_CMD25;
while(_MMCIsRun())
_MMCStopClk();
_MMCSetNumberOfBlockReg(nsects);
if(pCurrentCardInfo->buswidth&SD_BUS_WIDTH4)
_MMCSetCmd(cmd,addr,MMCB_BUSW|MMCB_DATEN|MMCB_R1|MMCB_WRRD);//bus width is 4 only for SD Card
else
_MMCSetCmd(cmd,addr,MMCB_DATEN|MMCB_R1|MMCB_WRRD);
//*(P_U16)MMCR_INT_MASK=(~MMC_CMD_DONE)&0xF; //set irpt mask register, only for CMD DONE
*(P_U16)MMCR_INT_MASK=0xF;
*(P_U16)MMCR_STR_STP_CLK=0x06; //start clk
while(!((*(P_U16)MMCR_STATUS)&0x2000))i++;
TRACE(" CMD Result: 0x%04X,wait time %d\n",(*(P_U16)MMCR_STATUS),i);//TEST omit response CRC Error
ret=(*(P_U16)MMCR_STATUS)&MMC_CMD_TIMEOUT; //Time Out Error
if(ret)
{ _MMCStopClk();
return ret;
}
/*because block size is always larger than FIFO Size, after command done,there are not anthor interrupt
before start transfer. */
_gMMCIsIrpt=1;
*(P_U16)MMCR_INT_MASK=~MMC_DATA_TRANS_DONE;
if(_gMMCDMAChannel!=0xFF) //Use DMA
{ //Start DMA
_gMMCIsTransferDone=0;
if(_DmaStartTransfer(_gMMCDMAChannel,buff,(P_VOID)MMCR_BUFFER_ACCESS,MMC_BLOCK_SIZE*nsects,DMA_MEMTOIO)
==SYS_OK);
{ ret=_MMCWaitDataTransDone(); //wait DMA data tranferring over
ret|= (*(P_U16)MMCR_STATUS)&0x4;
_MMCStopClk();
return ret;
}
}
//don't use DMA
TRACE("Don't use DMA Transfer Data\n");
length=nsects*MMC_BLOCK_SIZE/sizeof(U16);
for(i=0;i<length;i++)
{
//if(i>0&&((i&0xFF)==0)) //if(i>0 && i%256==0)
//_MMCStartClk();
//if FIFO full
if(((*(P_U16)MMCR_STATUS)&0x80)!=0)
while(((*(P_U16)MMCR_STATUS)&0x40)==0); //wait till FIFO empty
*(P_U16)MMCR_BUFFER_ACCESS=*((P_U16)buff+i); //data tranferring
}
i=0;
while(!((*(P_U16)MMCR_STATUS)&0x800))i++; //wait data transfer done
i=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -