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

📄 mmcsd_protocol.c

📁 TI的DM6446的硬件平台搭建的相关例子
💻 C
📖 第 1 页 / 共 3 页
字号:
     CSL_EdmaRegionObj    edmaShObj;
     CSL_EdmaRegionParam  regionParam;

     CSL_EdmaHwChannelSetup chSetupMmcrx;

     CSL_EdmaRegionHandle   shHandle;
     CSL_EdmaCmdDmaRegion draeAttr;

     CSL_Status chStatus;

     Uint32 revision;
     Uint32 intrQuery[2];/*EDMA object declaration ends */

     /*Required for EDMA setup */
     Uint32 *dstBuff= NULL;
     Uint32 bcnt=0x0;
     Uint32 ccnt=0x0; /*EDMA Objects */

#ifdef THROUGHPUT
           /*Initialize the Memorylocations storing the START & STOP count from TIMER1 for READ operation */
           *rd_tickstart=0x0;
           *rd_tickstop=0x0;
#endif


   if(mmcsdCSDRegInfo.readBlkLenBytes != blklength){
        if(mmcsdCSDRegInfo.readBlkPartial != 1)
            return E_INVALID_INPUT;
      }

      if(cardMemAddr%512){
        if(mmcsdCSDRegInfo.readBlkMisalign != 1) {
            return E_INVALID_INPUT;
        }
      }



     fifoThrlevel= fifoLevel;
     /*Required for EDMA setup */
     if(fifoThrlevel)
     {
        MMCSD_FIFOThreshold(MMCSD_FIFOLEVEL_32BYTES);
        fifoReadItrCount=blklength/32;
        fifoDxrRdCnt=8;

     }
     else
     {
         fifoReadItrCount=blklength/16;
         fifoDxrRdCnt=4;

     }


     if (dmaEnable)
     {

            /* reset the FIFO  */
                MMCSD_FIFOReset();

            /* Set the Transfer direction from the FIFO as receive*/
                MMCSD_FIFOReceive();



            dstBuff= (Uint32 *)dest;
            bcnt = fifoDxrRdCnt;
            ccnt = fifoReadItrCount;

                 // 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,&regionParam,NULL);

            // Channel Open
            chParamMmcrx.regionNum = CSL_EDMA_REGION_0;
            chParamMmcrx.chaNum = CSL_EDMA_MMCRXEVT; //MMCSDREVT sync event
            hMmcChrx = CSL_edmaChannelOpen(&ChObjMmcrx,
                            CSL_EDMA_0,
                            &chParamMmcrx,
                            &chStatus);


            // Channel Setup
            chSetupMmcrx.paramEntry = 26; // This number corresponds to channel/event number=paramentry associated w/ a periph. Refer Table 5-9 (chap5)
            chSetupMmcrx.que  = CSL_EDMA_EVT_QUE1;// Use Q1 as default, might change when building Chains.
            CSL_edmaHwChannelSetup(hMmcChrx,&chSetupMmcrx);
            // Acquire parameters and set them up
            // Acquire basic param and set it up
            // Parameter entry 0
            /* Basic Setup */
            hParaMmcrx = CSL_edmaGetParamHandle(hMmcChrx,26,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
            paramSetupMmcrx.option = CSL_EDMA_OPT_MAKE(FALSE,FALSE,FALSE,TRUE,26,CSL_EDMA_TCC_NORMAL,CSL_EDMA_FIFOWIDTH_128BIT,FALSE,CSL_EDMA_SYNC_FRAME,CSL_EDMA_ADDRMODE_INCR,CSL_EDMA_ADDRMODE_INCR);
            /*MMCSD DRR Register  - Source Address */
            paramSetupMmcrx.srcAddr = (Uint32)0x01E10028;
             //ACNT=4 since DRR is 32 bit wide, BCNT= FifoDepth/ACNT
            paramSetupMmcrx.elmArrCnt = CSL_EDMA_CNT_MAKE(4,bcnt);

            paramSetupMmcrx.dstAddr = (Uint32)dstBuff;
             // Source BIDX stays same, Dst Idx changes by 4 since ACNT =4
            paramSetupMmcrx.srcDstBidx = CSL_EDMA_BIDX_MAKE(0,4);

            //Link to NULL , BCNTRLD=0.
            paramSetupMmcrx.linkBcntrld = CSL_EDMA_LINKBCNTRLD_MAKE(CSL_EDMA_LINK_NULL,0);

             //Dst Cidx is (ACNT*BCNT) Src Cidx is 0 .
            paramSetupMmcrx.srcDstCidx = CSL_EDMA_CIDX_MAKE(0,(4*bcnt));

            paramSetupMmcrx.cCnt = ccnt;

            paramSetupMmcrx.triggerWord = CSL_EDMA_TRIGWORD_NONE;   //Set this as NONE for EDMA x'fers. Useful in QDMA x'fers


            CSL_edmaParamSetup(hParaMmcrx,&paramSetupMmcrx,CSL_EDMA_PARAM_BASIC);


            status = MMCSD_sendCmd(MMCSD_SET_BLOCKLEN, blklength, (Bool)0, MMCSD_STAT0_RSPDNE);
            if(status != E_PASS)
                return  E_FAIL;

             MMCSD_clearResponse();

            status = MMCSD_setDataSize(1, blklength); /* num_blks = 1, num_of_bytes = blklength */
            if(status != E_PASS)
                return  E_FAIL;

            /*EDMA Channel Enable */
             CSL_edmaHwChannelControl(hMmcChrx,CSL_EDMA_CMD_CHANNEL_ENABLE,NULL);

             #ifdef THROUGHPUT
                        /*Obtain the Read Start Count from Timer 1 */
            *rd_tickstart = (CSL_FEXTR(CSL_TMR_1_REGS->TIM12, 31,16) << 16) | CSL_FEXTR(CSL_TMR_1_REGS->TIM12, 15,0) ;

            #endif

             /*Send read single Block Command */
            status = MMCSD_sendCmd(0x12000 | MMCSD_READ_SINGLE_BLOCK, cardMemAddr, (Bool)0, MMCSD_STAT0_RSPDNE);
            if(status != E_PASS)
                return E_FAIL;



            // Poll for transfer completions, wherein in this case IPR bit 26 (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] & 0x04000000));



            #ifdef THROUGHPUT
                  /*Obtain the Start Count from Timer 1 */
                 *rd_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= 0x04000000;

            /*Clear pending events */
              hModule->EECR= 0x04000000;

            CSL_edmaChannelClose(hMmcChrx);

            CSL_edmaRegionClose(shHandle);
            CSL_edmaClose(hModule);


            for(i=0;i<100;i++);

            if(status == E_PASS)
            {
              if(MMCSD_checkStatus(MMCSD_STAT0_DATDNE,0,0)==E_PASS)
                  return E_PASS;
                 else
                  return E_FAIL;
            }


     }
     else /* CPU used for transfer */
     {
        status = MMCSD_sendCmd(MMCSD_SET_BLOCKLEN, blklength, (Bool)0, MMCSD_STAT0_RSPDNE);
         if(status != E_PASS)
            return  E_FAIL;

         MMCSD_clearResponse();

        status = MMCSD_setDataSize(1, blklength); /* num_blks = 1, num_of_bytes = blklength */
        if(status != E_PASS)
            return  E_FAIL;

         /* reset the FIFO  */
        MMCSD_FIFOReset();

        /* Set the Transfer direction from the FIFO as receive*/
         MMCSD_FIFOReceive();

         #ifdef THROUGHPUT
                        /*Obtain the Read Start Count from Timer 1 */
            *rd_tickstart = (CSL_FEXTR(CSL_TMR_1_REGS->TIM12, 31,16) << 16) | CSL_FEXTR(CSL_TMR_1_REGS->TIM12, 15,0) ;
        #endif

         /*Send read single Block Command */
        status = MMCSD_sendCmd(0x12000 | MMCSD_READ_SINGLE_BLOCK, cardMemAddr, (Bool)0, MMCSD_STAT0_RSPDNE);
          if(status != E_PASS)
                return E_FAIL;



        status=MMCSD_readNWords((Uint32*)dest, blklength,cardMemAddr,dmaEnable);
        if(status !=E_PASS)
         return E_FAIL;

         for(i=0;i<100;i++);

         if(status == E_PASS)
         {
              if(MMCSD_checkStatus(MMCSD_STAT0_DATDNE,0,0)==E_PASS)
                  return E_PASS;
                 else
                  return E_FAIL;
         }
        #ifdef THROUGHPUT
                  /*Obtain the Start Count from Timer 1 */
          *rd_tickstop = (CSL_FEXTR(CSL_TMR_1_REGS->TIM12, 31,16) << 16) | CSL_FEXTR(CSL_TMR_1_REGS->TIM12, 15,0) ;
        #endif
      }
      return E_PASS;
}

/**
    \brief  Send command to write a single block of data to the MMC/SD card

    \param  cardAddr  Address of the location on the card to be written (should be a multiple of )
    \param  src  Buffer to write data from, into the MMC/SD card
    \param  blklength  Size of the block in bytes, to be written to MMC/SD card
    \param  dmaEnable  0: Disable DMA, 1: Enable DMA
    \param  endian  Endianness of the data to be written to the MMC/SD card

    \return if success, \c E_PASS, else error code

*/
STATUS MMCSD_singleBlkWrite( Uint32 cardMemAddr, Uint32 *src, Uint32 blklength, Bool dmaEnable, Uint32 endian,MMCSD_FIFOTHR_LEVEL fifolevel)
{
    STATUS status = E_PASS,i=0;

     /* Check for the Valid block length of the Card */

      if(mmcsdCSDRegInfo.writeBlkLenBytes != blklength)
         status=E_INVALID_INPUT;

      if(mmcsdCSDRegInfo.writeBlkLenBytes != blklength)
      {
        if(mmcsdCSDRegInfo.writeBlkPartial != 1)
            return E_INVALID_INPUT;
      }

      if(cardMemAddr%512)
        {
        if(mmcsdCSDRegInfo.writeBlkMisalign != 1)
            return E_INVALID_INPUT;
      }


      status = MMCSD_setDataSize( 1, blklength ); /* num_blks = 1, num_of_bytes = blklength */

      status = MMCSD_sendCmd(MMCSD_SET_BLOCKLEN, blklength, (Bool)0, MMCSD_STAT0_RSPDNE);

      if(status == E_PASS)
      {
          /* Write Data, every time MMCDXR Reg full */
           status = MMCSD_writeNWords((Uint32*)src, blklength,cardMemAddr,dmaEnable);

           /*Delay Required*/
           for(i=0;i<100;i++);

           if(status == E_PASS)
           {
                /* command been sent */
                 if(MMCSD_checkStatus(MMCSD_STAT0_DATDNE,0,0)!=E_PASS)
                    return E_FAIL;

           }
           else
             return E_FAIL;
      }
    return E_PASS;

}

/**
    \brief  Send command to read multiple blocks of data from the MMC/SD card

    \param  cardAddr  Address of the location on the card to be read (should be a multiple of )
    \param  dest  Buffer to read data into, from MMC/SD card
    \param  numBlks  Number of blocks to be read during multiple blk read operation, from MMC/SD
    \param  blklength  Size of the block in bytes, to be read from MMC/SD card
    \param  dmaEnable  0: Disable DMA, 1: Enable DMA
    \param  endian  Endianness of the data to be read from the MMC/SD card

    \return if success, \c E_PASS, else error code

*/
STATUS MMCSD_multipleBlkRead( Uint32 cardMemAddr, Uint32 *dest, Uint32 datalength, Bool dmaEnable, Uint32 endian )
{
    STATUS status;
    Uint32 numBlks;
    int num_extra_words;
    Uint16 fifoDxrRdCnt=0,fifoThrlevel=0;
    Uint32 fifoReadItrCount=0;


/*EDMA Objects */

     CSL_EdmaHandle       hModule;
     CSL_EdmaParamHandle  hParaMmcrx;
     CSL_EdmaChanObj      ChObjMmcrx;
     CSL_EdmaChanHandle   hMmcChrx;
     CSL_EdmaParamSetup   paramSetupMmcrx;
     CSL_EdmaContext      edmaContext;
     CSL_EdmaChannelParam chParamMmcrx;
     CSL_EdmaRegionObj    edmaShObj;
     CSL_EdmaRegionParam  regionParam;

     CSL_EdmaHwChannelSetup chSetupMmcrx;

     CSL_EdmaRegionHandle   shHandle;
     CSL_EdmaCmdDmaRegion draeAttr;

     CSL_Status chStatus;

     Uint32 revision;
     Uint32 intrQuery[2];/*EDMA object declaration ends */

     /*Required for EDMA setup */
     Uint32 *dstBuff= NULL;
     Uint32 bcnt=0x0;
     Uint32 ccnt=0x0; /*EDMA Objects */


      //Check whether address is valid
     if(cardMemAddr%512){
        if(mmcsdCSDRegInfo.readBlkMisalign != 1)
            return E_INVALID_INPUT;
      }



        /*Required for EDMA setup */
     fifoThrlevel= CSL_FEXT(CSL_MMCSD_0_REGS->MMCFIFOCTL,MMCSD_MMCFIFOCTL_FIFOLEV);

     if(fifoThrlevel)
     {
        MMCSD_FIFOThreshold(MMCSD_FIFOLEVEL_32BYTES);
        fifoReadItrCount=datalength/32;
        fifoDxrRdCnt=8;

     }
     else
     {
         fifoReadItrCount=datalength/16;
         fifoDxrRdCnt=4;

     }

     if(dmaEnable)
     {
            /* reset the FIFO  */
             MMCSD_FIFOReset();

            /* Set the Transfer direction from the FIFO as transmit*/
             MMCSD_FIFOReceive();


            /* Clear all the response registers */
             MMCSD_clearResponse();

            /* Determine the minimum number of extra bytes  */
            num_extra_words = datalength % (mmcsdCSDRegInfo.readBlkLenBytes);
                 /* To find the Number of blocks to be read in terms of 512 Bytes */
            numBlks = datalength / (mmcsdCSDRegInfo.readBlkLenBytes);

            /*Check whether partial reads are supported */
            if(num_extra_words != 0)
             {
                if(mmcsdCSDRegInfo.readBlkPartial != 1) {
                    return E_INVALID_INPUT;
                }
             }

            dstBuff= (Uint32 *)dest;
            bcnt = fifoDxrRdCnt;
            ccnt = fifoReadItrCount;

                 // 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,&regionParam,NULL);

            // Channel Open
            chParamMmcrx.regionNum = CSL_EDMA_REGION_0;
            chParamMmcrx.chaNum = CSL_EDMA_MMCRXEVT; //MMCSDREVT sync event
            hMmcChrx = CSL_edmaChannelOpen(&ChObjMmcrx,
                            CSL_EDMA_0,
                            &chParamMmcrx,
                            &chStatus);


            // Channel Setup
            chSetupMmcrx.paramEntry = 26; // This number corresponds to channel/event number=paramentry associated w/ a periph. Refer Table 5-9 (chap5)
            chSetupMmcrx.que  = CSL_EDMA_EVT_QUE1;// Use Q1 as default, might change when building Chains.
            CSL_edmaHwChannelSetup(hMmcChrx,&chSetupMmcrx);
            // Acquire parameters and set them up
            // Acquire basic param and set it up

⌨️ 快捷键说明

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