📄 mmcsd_evm.c
字号:
\param data Buffer containing data to be written to the MMC
\param numWords Number of words to be written to the MMC
\return if success, \c E_PASS, else error code
*/
STATUS MMCSD_writeNWords( Uint32 *data, Uint32 numofBytes,Uint32 cardMemAddr,Bool dmaEnable )
{
register volatile Uint16 stat;
Uint16 ii=0,jj=0,status=0,fifoDxrWrCnt=0;
Uint32 fifoWriteItrCount=0,extraBytes=0; /* Word counter */
Uint8 fifoBuff[32]={0};
Uint8 *fifoBuffPtr=(Uint8*)fifoBuff;
Uint16 fifoThrlevel =0;
/*Memory location for storing START & STOP count from Timer 1*/
Uint32 * wr_tickstart =(Uint32 *)0x80400000;
Uint32 * wr_tickstop =(Uint32 *)0x80400004;
/*EDMA Object declaration */
CSL_EdmaHandle hModule;
CSL_EdmaParamHandle hParaMmctx;
CSL_EdmaChanObj ChObjMmctx;
CSL_EdmaChanHandle hMmcChtx;
CSL_EdmaParamSetup paramSetupMmctx;
CSL_EdmaContext edmaContext;
CSL_EdmaChannelParam chParamMmctx;
CSL_EdmaRegionObj edmaShObj;
CSL_EdmaRegionParam regionParam;
CSL_EdmaHwChannelSetup chSetupMmctx;
CSL_EdmaRegionHandle shHandle;
CSL_EdmaCmdDmaRegion draeAttr;
CSL_Status chStatus;
Uint32 revision;
Uint32 intrQuery[2]; /* EDMA object declaration ends */
/*Required for EDMA setup */
Uint32 *srcBuff= NULL;
Uint32 bcnt=0x0;
Uint32 ccnt=0x0;
#ifdef THROUGHPUT
/*Initialize the Memorylocations storing the START & STOP time */
*wr_tickstart=0x0;
*wr_tickstop=0x0;
#endif
/*Check the FIFO level to used. This is set in MMCSD_init */
fifoThrlevel = CSL_FEXT(CSL_MMCSD_0_REGS->MMCFIFOCTL,MMCSD_MMCFIFOCTL_FIFOLEV);
/* reset the FIFO */
MMCSD_FIFOReset();
/* Set the Transfer direction from the FIFO as transmit*/
MMCSD_FIFOTransmit();
/* Check the FIFO Threshold Level is not as default(16bytes) set it to 32Bytes*/
if(fifoThrlevel)
{
MMCSD_FIFOThreshold(MMCSD_FIFOLEVEL_32BYTES);
fifoWriteItrCount=numofBytes/32;
extraBytes=numofBytes%32;
fifoDxrWrCnt=8;
if(extraBytes)
fifoWriteItrCount=(numofBytes/32)+1;
else
fifoWriteItrCount= numofBytes/32;
}
else
{
fifoWriteItrCount=numofBytes/16;
extraBytes=numofBytes%16;
fifoDxrWrCnt=4;
if(extraBytes){
fifoWriteItrCount=(numofBytes/16)+1;
}
else
fifoWriteItrCount= numofBytes/16;
}
/*EDMA setup*/
if(dmaEnable)
{
srcBuff= (Uint32 *)data;
bcnt = fifoDxrWrCnt;
ccnt = fifoWriteItrCount;
// Module Initialization
CSL_edmaInit(&edmaContext);
// Module Level Open
hModule = CSL_edmaOpen(NULL,CSL_EDMA_0,NULL,NULL);
// Query Module revision
CSL_edmaGetHwStatus(hModule,CSL_EDMA_QUERY_REVISION,&revision);
// Setup the DRAE Masks
// Region 0 for ARM based peripherals.
draeAttr.region = CSL_EDMA_REGION_0;
draeAttr.drae = 0xFFFFFFFF;
draeAttr.draeh = 0x1FFFFFFF;
CSL_edmaHwControl(hModule,CSL_EDMA_CMD_DMAREGION_ENABLE,&draeAttr);
// Shadow Region 0 Open: ARM Shadow Region
regionParam.regionNum = CSL_EDMA_REGION_0;
shHandle = CSL_edmaRegionOpen(&edmaShObj,CSL_EDMA_0,®ionParam,NULL);
// Channel Open
chParamMmctx.regionNum = CSL_EDMA_REGION_0;
chParamMmctx.chaNum = CSL_EDMA_MMCTXEVT; //MMCSDXEVT sync event
hMmcChtx = CSL_edmaChannelOpen(&ChObjMmctx,
CSL_EDMA_0,
&chParamMmctx,
&chStatus);
// Channel Setup
chSetupMmctx.paramEntry = 27; // This number corresponds to channel/event number=paramentry associated w/ a periph. Refer Table 5-9 (chap5)
chSetupMmctx.que = CSL_EDMA_EVT_QUE1;// Use Q1 as default, might change when building Chains.
CSL_edmaHwChannelSetup(hMmcChtx,&chSetupMmctx);
// Acquire parameters and set them up
// Acquire basic param and set it up
// Parameter entry 0
/* Basic Setup */
hParaMmctx = CSL_edmaGetParamHandle(hMmcChtx,27,NULL);// Need to put the paramentry number here too.
// Your ACNT will change depending on whether its 8 bit (ACNT=1),16-bit (ACNT=2) or 32 bit (ACNT=4)data, as ACNT is always in # of bytes
paramSetupMmctx.option = CSL_EDMA_OPT_MAKE(FALSE,FALSE,FALSE,TRUE,27,CSL_EDMA_TCC_NORMAL,CSL_EDMA_FIFOWIDTH_128BIT,FALSE,CSL_EDMA_SYNC_FRAME,CSL_EDMA_ADDRMODE_INCR,CSL_EDMA_ADDRMODE_INCR);
paramSetupMmctx.srcAddr = (Uint32)srcBuff;
//ACNT=4 since DXR is 32 bit wide, BCNT= FifoDepth/ACNT
paramSetupMmctx.elmArrCnt = CSL_EDMA_CNT_MAKE(4,bcnt);
/*MMCSD DXR Register address- Destination */
paramSetupMmctx.dstAddr = (Uint32)0x01E1002c;
// Source IDX is incremented by 4 since ACNT =4, Dst Idx=Stays same
paramSetupMmctx.srcDstBidx = CSL_EDMA_BIDX_MAKE(4,0);
//Link to NULL , BCNTRLD=0
paramSetupMmctx.linkBcntrld = CSL_EDMA_LINKBCNTRLD_MAKE(CSL_EDMA_LINK_NULL,0);
//Src Cidx is (ACNT*BCNT) Dst Cidx is 0 .
paramSetupMmctx.srcDstCidx = CSL_EDMA_CIDX_MAKE((4*bcnt),0);
//
paramSetupMmctx.cCnt = ccnt;
paramSetupMmctx.triggerWord = CSL_EDMA_TRIGWORD_NONE; //Set this as NONE for EDMA x'fers. Useful in QDMA x'fers
CSL_edmaParamSetup(hParaMmctx,¶mSetupMmctx,CSL_EDMA_PARAM_BASIC);
/*Generate EDMA Txfer Event */
CSL_FINS(CSL_MMCSD_0_REGS->MMCCMD,MMCSD_MMCCMD_DMATRIG,1);
/*Enable the EDMA channel */
CSL_edmaHwChannelControl(hMmcChtx,CSL_EDMA_CMD_CHANNEL_ENABLE,NULL);
}
/*CPU USED FOR DATA TRANSFER */
if(!dmaEnable)
{
for(ii=0; ii < fifoWriteItrCount;ii++)
{
if(ii==0)
{
#ifdef THROUGHPUT
/*Obtain the Start Count from Timer 1 */
*wr_tickstart = (CSL_FEXTR(CSL_TMR_1_REGS->TIM12, 31,16) << 16) | CSL_FEXTR(CSL_TMR_1_REGS->TIM12, 15,0) ;
#endif
if(numofBytes ==512)
{
status = MMCSD_sendCmd(0x12800 | MMCSD_WRITE_BLOCK, cardMemAddr,(Bool)0, MMCSD_STAT0_RSPDNE);
}
else
{
status = MMCSD_sendCmd(0x12880 | MMCSD_WRITE_MULTIPLE_BLOCK, cardMemAddr, (Bool)0, MMCSD_STAT0_RSPDNE);
}
}
for(jj=0;jj < fifoDxrWrCnt; jj++)
CSL_MMCSD_0_REGS->MMCDXR= (Uint32)*data++;
if(ii != (fifoWriteItrCount -1))
{
while(!(CSL_FEXT(CSL_MMCSD_0_REGS->MMCST0,MMCSD_MMCST0_DXRDY)));
}
// while(MMCSD_CheckFIFOIsEmpty());
if(extraBytes)
{
if(ii==(fifoWriteItrCount-1))
{
for(jj=0;jj < fifoDxrWrCnt; jj++)
{
CSL_MMCSD_0_REGS->MMCDXR= (Uint32)*fifoBuffPtr++;
}
}
memcpy((Uint8*)fifoBuffPtr,(Uint8*)data,extraBytes);
}
}
#ifdef THROUGHPUT
/*Obtain the Start Count from Timer 1 */
*wr_tickstop = (CSL_FEXTR(CSL_TMR_1_REGS->TIM12, 31,16) << 16) | CSL_FEXTR(CSL_TMR_1_REGS->TIM12, 15,0) ;
#endif
}
else /*EDMA USED FOR DATA TRANSFER*/
{
#ifdef THROUGHPUT
/*Obtain the Start Count from Timer 1 */
*wr_tickstart = (CSL_FEXTR(CSL_TMR_1_REGS->TIM12, 31,16) << 16) | CSL_FEXTR(CSL_TMR_1_REGS->TIM12, 15,0) ;
#endif
if(numofBytes==512)
status = MMCSD_sendCmd(0x12800 | MMCSD_WRITE_BLOCK, cardMemAddr,(Bool)0, MMCSD_STAT0_RSPDNE);
else
status = MMCSD_sendCmd(0x12880 | MMCSD_WRITE_MULTIPLE_BLOCK, cardMemAddr, (Bool)0, MMCSD_STAT0_RSPDNE);
// Poll for transfer completions, wherein in this case IPR bit 27 (TCC#) will be set
// Important to have TCCINTEN =1 in the OPT field
do
{
CSL_edmaGetHwRegionStatus(shHandle,CSL_EDMA_QUERY_REGION_INTERRUPT_PENDSTATUS,intrQuery);
} while (!(intrQuery[0] & 0x08000000));
#ifdef THROUGHPUT
/*Obtain the Stop Count from Timer 1 */
*wr_tickstop = (CSL_FEXTR(CSL_TMR_1_REGS->TIM12, 31,16) << 16) | CSL_FEXTR(CSL_TMR_1_REGS->TIM12, 15,0) ;
#endif
/*Clear Interrupt Pending Register */
hModule->ICR= 0x08000000;
/* Clear pending events */
hModule->EECR = 0x08000000;
CSL_edmaChannelClose(hMmcChtx);
CSL_edmaRegionClose(shHandle);
CSL_edmaClose(hModule);
}
return (E_PASS);
}
/**
\brief Read N words from the MMC Controller Register
\param data Buffer for storing read data from the MMC
\param numWords Number of words to be read from the MMC
\return if success, \c E_PASS, else error code
*/
Uint16 MMC_StreamReadNWords(Uint32 *data, Uint32 numofBytes,Bool dmaEnable)
{
register volatile Uint16 stat;
Uint16 status=0,ii=0,jj=0,fifoDxrRdCnt=0;
Uint32 fifoReadItrCount=0,extraBytes=0; /* Word counter */
Uint8 fifoBuff[32]={0};
Uint8 *fifoBuffPtr=(Uint8*)fifoBuff;
Uint16 fifoThrlevel=0;
Uint32 dummy[20];
/* reset the FIFO */
MMCSD_FIFOReset();
/* Set the Transfer direction from the FIFO as transmit*/
MMCSD_FIFOReceive();
/*Check the FIFO level to used. This is set in MMCSD_init */
fifoThrlevel = CSL_FEXT(CSL_MMCSD_0_REGS->MMCFIFOCTL,MMCSD_MMCFIFOCTL_FIFOLEV);
/* Check the FIFO Threshold Level is not as default(16bytes) set it to 32Bytes*/
if(fifoThrlevel){
MMCSD_FIFOThreshold(MMCSD_FIFOLEVEL_32BYTES);
fifoReadItrCount=numofBytes/32;
extraBytes=numofBytes%32;
fifoDxrRdCnt=8;
if(extraBytes)
fifoReadItrCount=(numofBytes/32)+1;
else
fifoReadItrCount= numofBytes/32;
}
else{
fifoReadItrCount=numofBytes/16;
extraBytes=numofBytes%16;
fifoDxrRdCnt=4;
if(extraBytes){
fifoReadItrCount=(numofBytes/16)+1;
}
else
fifoReadItrCount= numofBytes/16;
}
if(!dmaEnable) /*CPU used to read Data */
{
for(ii=0; ii < fifoReadItrCount;ii++)
{
// while(MMCSD_CheckFIFOIsFull());
while(!(CSL_FEXT(CSL_MMCSD_0_REGS->MMCST0,MMCSD_MMCST0_DRRDY)));
for(jj=0;jj < fifoDxrRdCnt; jj++)
{
*data++ = CSL_MMCSD_0_REGS->MMCDRR;
}
//asm(" nop");
//asm(" nop");
//asm(" nop");
if(ii==(fifoReadItrCount-1))
{
for(jj=0;jj <10; jj++)
{
dummy[jj]=CSL_MMCSD_0_REGS->MMCDRR;
if(jj==8)
{
CSL_MMCSD_0_REGS->MMCARGHL=(Uint32)0x0;
CSL_MMCSD_0_REGS->MMCCMD=(Uint32)0x138C;
//status = MMCSD_checkStatus((MMCSD_STAT0_RSPDNE|MMCSD_STAT0_BSYDNE), 0, 0); //> TimeOut = 0
//if(status!=E_PASS)
// return E_DEVICE;
}
}
}
}
if(extraBytes)
{
if(ii==(fifoReadItrCount-1))
{
for(jj=0;jj < fifoDxrRdCnt; jj++)
{
*fifoBuffPtr++ = CSL_MMCSD_0_REGS->MMCDRR;
}
}
memcpy((Uint8*)data,(Uint8*)fifoBuffPtr,extraBytes);
}
}
else
{
//status = MMCSD_EDMARead(data,fifoDxrRdCnt,fifoReadItrCount);
//if(status!=E_PASS)
//return E_FAIL;
}
return E_PASS;
}
/**
\brief Write N words to the MMC Controller Register
\param data Buffer containing data to be written to the MMC
\param numWords Number of bytes to be written to the MMC
\param cardmemAddr
\return if success, \c E_PASS, else error code
*/
Uint16 MMC_StreamWriteNWords(Uint32 cardMemAddr,Uint32 *data, Uint32 numofBytes,Bool dmaEnable)
{
register volatile Uint16 stat;
Uint16 ii=0,jj=0,status=0,fifoDxrWrCnt=0;
Uint32 fifoWriteItrCount=0,extraBytes=0; /* Word counter */
Uint8 fifoBuff[32]={0};
Uint8 *fifoBuffPtr=(Uint8*)fifoBuff;
Uint16 fifoThrlevel=0,i=0;
/* reset the FIFO */
MMCSD_FIFOReset();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -