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

📄 mmcsd_protocol.c

📁 TI的DM6446的硬件平台搭建的相关例子
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
    DaVinci ARM Evaluation Software

    (c)Texas Instruments 2004
*/


/**
    \file mmcsd_protocol.c
    \brief  Contains APIs common to MMC and SD, which are protocol specific
*/

#include <cslr_mmcsd.h>
#include <memcd_rettypes.h>
#include <mmcsd_protocol.h>
#include <mmc_protocol.h>
#include <mmcsd_evm.h>
#include <csl_edma.h>
//#include <davinci64plus.h>
#define CSL_EDMA_0                         0

extern MMCSD_ResponseData mmcsdResponse;
extern MMCSD_csdRegInfo mmcsdCSDRegInfo;
Uint32 relCardAdress;

/**
    \brief  Send command to set all the MMC/SD cards to Idle State

    \return if success, \c E_PASS, else error code
*/
STATUS MMCSD_goIdleState()
{
    STATUS status;

    status = MMCSD_sendCmd( (0x4000 | MMCSD_GO_IDLE_STATE), MMCSD_STUFF_BITS, (Bool)0, MMCSD_STAT0_RSPDNE);

    return ( status );
}

/**
    \brief  Send command to read the contents of the Card Identification (CID) register, on the MMC/SD

    \return if success, \c E_PASS, else error code
*/
STATUS MMCSD_allSendCID( void )
{
    volatile Uint16 stat;
    STATUS status;

    status = MMCSD_sendCmd( MMCSD_ALL_SEND_CID, MMCSD_STUFF_BITS, (Bool)1, MMCSD_STAT0_RSPDNE);

    return ( status );
}

/**
    \brief  Send command to set the Driver Stage Register (DSR) on the MMC/SD

    \param  dsr  The DSR value to be programmed into the card (default value of DSR = 0x04040000, where last 6bits are stuff bits)

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

*/
STATUS MMCSD_setDSR( Uint32 dsr )
{
    STATUS status;

    if( mmcsdCSDRegInfo.dsrImp != 1 )
        return E_DEVICE;

    status = MMCSD_sendCmd( MMCSD_SET_DSR, dsr, (Bool)1, MMCSD_STAT0_RSPDNE);

    return ( status );
}

/**
    \brief  Send command to read the status of the MMC/SD

    \param  rca  Relative Card Address assigned to the card
    \param  cardStatus  Status of the card is received in this structure

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

*/
STATUS MMCSD_sendStatus( Uint32 rca, MMCSD_cardStatusReg *cardStatus )
{
    STATUS status;

    /*  the rca value is sent as the upper 16 bits of the command argument  */
    status = MMCSD_sendCmd( MMCSD_SEND_STATUS, rca<<16, (Bool)1, MMCSD_STAT0_RSPDNE);

    if( status == E_PASS ) {
        /* Response expected: R1 in native mode and R2 in SPI mode*/
        MMCSD_getCardStatus( &mmcsdResponse, cardStatus );
        return ( E_PASS );
    }

    return ( status );
}

/**
    \brief  Send command to select a particular MMC/SD, using it's assigned RCA

    \param  rca  Relative Card Address assigned to the card

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

*/
STATUS MMCSD_selectCard( Uint32 rca )
{
    STATUS status;
    MMCSD_cardStatusReg cardStatus;

    /*  the rca value is sent as the upper 16 bits of the command argument  */
    status = MMCSD_sendCmd( MMCSD_SELECT_CARD, rca<<16, (Bool)1, MMCSD_STAT0_RSPDNE );

    if( status == E_PASS ) {
     /* no timeout */
     if ( rca > 0 ) {
       if( (MMCSD_sendStatus( rca, &cardStatus ) == E_PASS) ) {
          if( (cardStatus.currentState == MMCSD_STATE_TRAN) || (cardStatus.currentState == MMCSD_STATE_PRG ) ) {
            return ( E_PASS );
          }
       }
     }
    }

    return ( status );
}

/**
    \brief  Send command to deselect all MMCs / SDs (rca=0) or only the currently selected MMC/SD  (rca != current MMCs/SDs rca)

    \param  newRCA  a new RCA value, used for deselecting only the currently selected MMC/SD
    \param  oldRCA    the currently selected MMCs/SDs RCA value, used for checking if that MMC/SD is deselected

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

*/
STATUS MMCSD_deSelectCard( Uint16 newRCA, Uint16 oldRCA )
{
    STATUS status;
    MMCSD_cardStatusReg cardStatus;
    int i=0;
      /* Deselect the card then check status to see if
         we are in the proper state.  Because we are
         using rca = 0 to deselect there will not be
         the typical R1 response. : This is true if u want to deselect
         all cards with 1 cmd - Rati
      */
      if( newRCA == oldRCA ){
         status = MMCSD_sendCmd( MMCSD_DESELECT_CARD, 0, (Bool)0, MMCSD_STAT0_RSPDNE );
      } else {
         status = MMCSD_sendCmd( MMCSD_DESELECT_CARD, newRCA, (Bool)0, MMCSD_STAT0_RSPDNE );
      }

      /* delay reqd. */
      for( i=0; i<1000; i++ );

      /* Check if card is de-selected */
      if( status == E_PASS ) {
        status = MMCSD_sendStatus( oldRCA, &cardStatus );
        if( status == E_PASS )
           if( (cardStatus.currentState == MMCSD_STATE_STBY) || (cardStatus.currentState == MMCSD_STATE_DIS ) ) {
             return ( E_PASS );
           }
      }

      return ( E_DEVICE );
}

/**
    \brief  Send command to read the contents of the Card Specific Data (CSD) register, on the MMC/SD

    \param  rca  Relative Card Address assigned to the card
    \param  cardCSD  CSD of the card is received in this structure

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

*/
STATUS MMCSD_sendCSD( Uint32 rca, Uint16 *cardCSD )
{
    STATUS status;

    /*  the rca value is sent as the upper 16 bits of the command argument  */
    status = MMCSD_sendCmd( MMCSD_SEND_CSD, rca<<16, (Bool)1, MMCSD_STAT0_RSPDNE);

    if( status == E_PASS ) {
        MMCSD_getCardCSD( &mmcsdResponse, cardCSD, &mmcsdCSDRegInfo );
        return ( E_PASS );
    }

    return ( status );
}

/**
    \brief  Send command to read the contents of the Card Identification (CID) register, on the MMC/SD

    \param  rca  Relative Card Address assigned to the card
    \param  cardCID  CID of the card is received in this structure

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

*/
STATUS MMCSD_sendCID( Uint32 rca, Uint16 *cardCID )
{
    STATUS status;

    /*  the rca value is sent as the upper 16 bits of the command argument  */
    status = MMCSD_sendCmd( MMCSD_SEND_CID, rca<<16, (Bool)1, MMCSD_STAT0_RSPDNE);

    if( status == E_PASS ) {
        MMCSD_getCardCID( &mmcsdResponse, cardCID );
        return ( E_PASS );
    }

    return ( status );
}

/**
    \brief  Send command to send the specified MMC/SD (selected using RCA) into Inactive State

    \param  rca  Relative Card Address assigned to the card

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

*/
STATUS MMCSD_goInactiveState( Uint32 rca )
{
    STATUS status;

    /*  the rca value is sent as the upper 16 bits of the command argument  */
    status = MMCSD_sendCmd( MMCSD_GO_INACTIVE_STATE, rca<<16, (Bool)1, MMCSD_STAT0_RSPDNE);
    return ( status );
}

/**
    \brief  Send command to set the block length of data to be transferred to/from the MMC/SD

    \param  blkLength  Block length, in bytes, of data to be transferred to/from MMC/SD
    \param  write  0: read data from MMC/SD, 1: write data to MMC/SD

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

*/
STATUS MMCSD_setBlkLen( Uint32 blkLength, Bool write )
{
    STATUS status;

    if( blkLength%512 )
      if( write == 1 ){
         if( mmcsdCSDRegInfo.writeBlkPartial != 1 ){
            return E_FAIL;   /* Command not supported */
         }
      }else {
         if( mmcsdCSDRegInfo.readBlkPartial != 1 ){
            return E_FAIL;   /* Command not supported */
         }
      }

    status = MMCSD_sendCmd( MMCSD_SET_BLOCKLEN, blkLength, (Bool)1, MMCSD_STAT0_RSPDNE);

    return ( status );
}


/**
    \brief  Send command to program the programmable fields of the CSD register of MMC/SD

    \param  rca  Relative Card Address assigned to the card
    \param  numBlks

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

*/
STATUS MMCSD_programCSD( Uint32 rca, MMCSD_cardStatusReg *cardStatus, DM_BOOL writeProtect,Uint32 cardMemAddr )
{
    STATUS status;
    Uint16 cardCSD[8];
    Uint32 numWords;


      status = MMCSD_sendCSD( rca, cardCSD ) ;
      if( status != E_PASS ) {
          return E_DEVICE;
      }
      // Set the temporary write protection
      if(writeProtect) {
         cardCSD[7] = cardCSD[7]|0x10;
      } else {
         cardCSD[7] = cardCSD[7]&0xEF;
      }
      numWords = 2;
      status = MMCSD_writeNWords( (Uint32 *)cardCSD , numWords,cardMemAddr,FALSE );
      if( status == E_PASS ) {
         status = MMCSD_checkStatus( (MMCSD_STAT0_DATDNE|MMCSD_STAT0_BSYDNE), 0, 0 );  //> TimeOut = 0
      }

      status = MMCSD_sendCmd( MMCSD_PROGRAM_CSD, MMCSD_STUFF_BITS, (Bool)1, MMCSD_STAT0_RSPDNE);
      if( status == E_PASS ) {
        /* Response expected: R1 */
        MMCSD_getCardStatus( &mmcsdResponse, cardStatus );
        return ( E_PASS );
      }
      numWords = 6;
      status = MMCSD_writeNWords( (Uint32 *)cardCSD+2 , numWords,cardMemAddr,FALSE );
      if( status == E_PASS ) {
         status = MMCSD_checkStatus( (MMCSD_STAT0_DATDNE|MMCSD_STAT0_BSYDNE), 0, 0 );  //> TimeOut = 0
      }
      return ( status );
}


/**
    \brief  Send command to set Write Protection features of the addressed group on the MMC/SD

    \param  addr  Address of the WP Group to be write protected

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

    \note The user application should check the Write Protect Grp Size, for determining how many sectors get write protected.
    \note This value is present in the CSD structure of the MMC/SD cards.

*/
STATUS MMCSD_setWriteProtect( Uint32 addr )
{
   STATUS status;

      if( mmcsdCSDRegInfo.wpGrpEnable != 1 )
          return E_FAIL;      /* Command Not supported */

      status = MMCSD_sendCmd( MMCSD_SET_WRITE_PROT, addr, (Bool)1, MMCSD_STAT0_RSPDNE );
      if( status == E_PASS )
        status = MMCSD_checkStatus( MMCSD_STAT0_BSYDNE, 0, 0 );  /* TimeOut = 0 */

      return ( status );
}

/**
    \brief  Send command to clear the Write Protection feature set for the addressed group on the MMC/SD

    \param  addr  Address of the WP Group from which to remove write protection

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

    \note The user application should check the Write Protect Grp Size, for determining how many sectors get write protected.
    \note This value is present in the CSD structure of the MMC/SD cards.

*/
STATUS MMCSD_clearWriteProtect( Uint32 addr )
{
   STATUS status;

      if( mmcsdCSDRegInfo.wpGrpEnable != 1 )
          return E_FAIL;      /* Command Not supported */

      status = MMCSD_sendCmd( MMCSD_CLR_WRITE_PROT, addr, (Bool)1, MMCSD_STAT0_RSPDNE );
      if( status == E_PASS )
        status = MMCSD_checkStatus( MMCSD_STAT0_BSYDNE, 0, 0 );  /* TimeOut = 0 */

      return ( status );
}

/**
    \brief  Send command to check the status of the write protection bits of MMC/SD

    \param  addr  Address of the WP Group for which write protection property is checked
    \param  writeProtBits  write protect bits, representing 32 write protect groups, starting from 'addr'

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

    \note The user application should check the Write Protect Grp Size, for determining how many sectors get write protected.
    \note This value is present in the CSD structure of the MMC/SD cards.

*/
STATUS MMCSD_sendWriteProtect( Uint32 addr, Uint16 *writeProtBits,Uint32 cardMemAddr )
{
   STATUS status;

      if( mmcsdCSDRegInfo.wpGrpEnable != 1 )
          return E_FAIL;      /* Command Not supported */

      status = MMCSD_sendCmd( MMCSD_SET_BLOCKLEN, 4, (Bool)1, MMCSD_STAT0_RSPDNE);
      if( status != E_PASS )
        return E_FAIL;

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

      if( status == E_PASS ){
          status = MMCSD_sendCmd( (0xA080 | MMCSD_SEND_WRITE_PROT), addr, (Bool)1, MMCSD_STAT0_RSPDNE);
          if( status == E_PASS ) {
            status = MMCSD_readNWords( (Uint32 *)writeProtBits, 2,cardMemAddr,FALSE );
            /* Check for MMCSD_DATDNE signal */
            if( status == E_PASS )
                status = MMCSD_checkStatus( MMCSD_STAT0_DATDNE, 0, 0 );  //> TimeOut = 0
          }
      }

      return ( status );
}

/**
    \brief  Send command to indicate that the next command is an application specific command

    \param  rca  Relative Card Address assigned to the card

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

*/
STATUS MMCSD_appCmd( Uint32 rca )
{
   STATUS status;

      /*  the rca value is sent as the upper 16 bits of the command argument  */
      status = MMCSD_sendCmd( MMCSD_APP_CMD, rca<<16, (Bool)1, MMCSD_STAT0_RSPDNE);

      return ( status );
}

/**
    \brief  Send command to read a single block 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  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_singleBlkRead( Uint32 cardMemAddr, Uint32 *dest, Uint32 blklength, Bool dmaEnable, Uint32 endian,MMCSD_FIFOTHR_LEVEL fifoLevel )
{
  STATUS status=0,i=0 ;
  Uint16 fifoDxrRdCnt=0;
  Uint32 fifoReadItrCount=0;          /* Word counter */
  Uint16 fifoThrlevel =0;


  /*Memory location for storing START & STOP count from Timer 1*/
      Uint32 * rd_tickstart =(Uint32 *)0x80400008;
      Uint32 * rd_tickstop =(Uint32 *)0x8040000c;


  /*EDMA Objects */

     CSL_EdmaHandle       hModule;
     CSL_EdmaParamHandle  hParaMmcrx;
     CSL_EdmaChanObj      ChObjMmcrx;
     CSL_EdmaChanHandle   hMmcChrx;
     CSL_EdmaParamSetup   paramSetupMmcrx;
     CSL_EdmaContext      edmaContext;
     CSL_EdmaChannelParam chParamMmcrx;

⌨️ 快捷键说明

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