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

📄 mmc.c

📁 包含了NXP众多的MCU的例子程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************
 *
 *    Used with ICCARM and AARM.
 *
 *    (c) Copyright IAR Systems 2005
 *
 *    File name   : mmc.c
 *    Description : MMC
 *
 *    History :
 *    1. Data        : July 1, 2005
 *       Author      : Stanimir Bonev
 *       Description : Create
 *
 *    $Revision: 1.2.2.1 $
**************************************************************************/
#define MMC_GLOBAL
#include "mmc.h"
#include "mmc_ll_SPI1.c"

#define MMC_RET_ERROR(Res)          MmcLastError = Res;return(MmcCardError)
#define MMC_RET_DATA_ERR(Res)       MmcLastError = Res;return(MmcDataError)

#define CSD_GET_TRAN_SPEED_EXP()      (MmcSdCsd[ 3]&0x07)
#define CSD_GET_TRAN_SPEED_MANT()    ((MmcSdCsd[ 3]&0xF8)>>3)
#define CSD_GET_NSAC()                (MmcSdCsd[ 2]        )
#define CSD_GET_TAAC_EXP()            (MmcSdCsd[ 1]&0x7)
#define CSD_GET_TAAC_MANT()          ((MmcSdCsd[ 1]&0xF8)>>3)
#define CSD_GET_R2W_FACTOR()         ((MmcSdCsd[12]&0x1C)>>2)
#define CSD_GET_READ_BL_LEN()         (MmcSdCsd[ 5]&0x0F)
#define CSD_GET_C_SIZE()            (((MmcSdCsd[ 6]&0x03)<<10) + (MmcSdCsd[7]<<2) + ((MmcSdCsd[8]&0xc0)>>6))
#define CSD_GET_C_SIZE_MULT()       (((MmcSdCsd[ 9]&0x03)<<1 ) +((MmcSdCsd[10]&0x80)>>7))
#define CSD_GET_PERM_WRITE_PROTECT() ((MmcSdCsd[14]&0x20)>>5)
#define CSD_GET_TMP_WRITE_PROTECT()  ((MmcSdCsd[14]&0x10)>>4)

const Int32U MmcTransfExp[] =
{
     10000UL,
    100000UL,
   1000000UL,
  10000000UL,
         0UL,
         0UL,
         0UL,
         0UL,
};

const Int32U MmmcAccessTime [] =
{
 10000000UL,
  1000000UL,
   100000UL,
    10000UL,
     1000UL,
      100UL,
       10UL,
        1UL,
};

const Int32U MmcCsdMant[] =
{
  0UL,10UL,12UL,13UL,15UL,
  20UL,25UL,
  30UL,35UL,
  40UL,45UL,
  50UL,55UL,
  60UL,
  70UL,
  80UL,
};

const Int32U MmcAccessTimeMant[] =
{
  0UL,100UL,83UL,77UL,67UL,
  50UL,40UL,
  33UL,29UL,
  25UL,22UL,
  20UL,18UL,
  17UL,
  14UL,
  13UL,
};

const MmcCommads_t MmcCmd[CMD_END] =
{
  // CMD0
  {0x40,MmcNoArg    ,MmcR1 },
  // CMD1
  {0x41,MmcNoArg    ,MmcR1 },
  // CMD9
  {0x49,MmcNoArg    ,MmcR1 },
  // CMD10
  {0x4A,MmcNoArg    ,MmcR1 },
  // CMD12
  {0x4C,MmcNoArg    ,MmcR1 },
  // CMD13
  {0x4D,MmcNoArg    ,MmcR2 },
  // CMD16
  {0x50,MmcBlockLen ,MmcR1 },
  // CMD17
  {0x51,MmcDataAdd  ,MmcR1 },
  // CMD18
  {0x52,MmcDataAdd  ,MmcR1 },
  // CMD24
  {0x58,MmcDataAdd  ,MmcR1 },
  // CMD25
  {0x59,MmcDataAdd  ,MmcR1 },
  // CMD27
  {0x5B,MmcNoArg    ,MmcR1 },
  // CMD28
  {0x5C,MmcDataAdd  ,MmcR1b},
  // CMD29
  {0x5D,MmcDataAdd  ,MmcR1b},
  // CMD30
  {0x5E,MmcDataAdd  ,MmcR1 },
  // CMD32
  {0x60,MmcDataAdd  ,MmcR1 },
  // CMD33
  {0x61,MmcDataAdd  ,MmcR1 },
  // CMD34
  {0x62,MmcDataAdd  ,MmcR1 },
  // CMD35
  {0x63,MmcDataAdd  ,MmcR1 },
  // CMD36
  {0x64,MmcDataAdd  ,MmcR1 },
  // CMD37
  {0x65,MmcDataAdd  ,MmcR1 },
  // CMD38
  {0x66,MmcDummyWord,MmcR1b},
  // CMD42
  {0x6A,MmcDummyWord,MmcR1b},
  // CMD55
  {0x77,MmcNoArg    ,MmcR1 },
  // CMD56
  {0x78,MmcNoArg    ,MmcR1 },
  // CMD58
  {0x7A,MmcNoArg    ,MmcR3 },
  // CMD59
  {0x7B,MmcDummyWord,MmcR1 },
  // ACMD41
  {0x69,MmcNoArg    ,MmcR1 }
};

DiskStatus_t MmcDskStatus;
Int32U MmcLastError,Tnac,Twr;
Int8U MmcSdCsd[16];
Boolean bMmcChanged;
/*************************************************************************
 * Function Name: MmcSendCmd
 * Parameters: MmcSpiCmdInd_t ComdInd,Int32U Arg
 *
 * Return: Int32U
 *
 * Description: MMC commands implemet
 *
 *************************************************************************/
Int32U MmcSendCmd(MmcSpiCmdInd_t ComdInd,Int32U Arg)
{
Int32U ch = 0xFF;
Int32U i;
  // Chip Select
  MmcChipSelect(1);
  // Send command code
  MmcTranserByte(MmcCmd[ComdInd].TxData);
  // Send command's argulents
  if(MmcCmd[ComdInd].Arg == MmcNoArg)
  {
    MmcTranserByte(0x00);
    MmcTranserByte(0x00);
    MmcTranserByte(0x00);
    MmcTranserByte(0x00);
  }
  else
  {
    MmcTranserByte(Arg >> 24);
    MmcTranserByte(Arg >> 16);
    MmcTranserByte(Arg >> 8 );
    MmcTranserByte(Arg      );
  }
  // Send CRC
  if(ComdInd == CMD0)
  {
    MmcTranserByte(0x95);
  }
  else
  {
    MmcTranserByte(0xFF);
  }

  for(i = 9; i && (ch == 0xFF); --i) ch = MmcTranserByte(0xFF);

  if (i == 0)
  {
    MmcChipSelect(0);
    return((Int32U)-1);
  }

  switch (MmcCmd[ComdInd].Resp)
  {
  case MmcR1b:
    for (Int32U Busy = 0,i = Twr; i && (Busy != 0xFF); --i)
    {
      Busy = MmcTranserByte(0xFF);
    }
  case MmcR1:
    return(ch);
  case MmcR2:
    Arg  = ((Int32U)ch << 8) & 0x0000FF00;
    Arg |= MmcTranserByte(0xFF) & 0xFF;
    return(Arg);
  case MmcR3:
  default:
    Arg  = ((Int32U)ch << 24) & 0xFF000000;
    Arg |= ((Int32U)MmcTranserByte(0xFF) << 16) & 0x00FF0000;
    Arg |= ((Int32U)MmcTranserByte(0xFF) << 8 ) & 0x0000FF00;
    Arg |= MmcTranserByte(0xFF) & 0xFF;
    return(Arg);
  }
}

/*************************************************************************
 * Function Name: MmcSetBlockLen
 * Parameters: Int32U Length
 *
 * Return: Int32U
 *
 * Description: Set Block length Return command's result
 *
 *************************************************************************/
Int32U MmcSetBlockLen(Int32U length)
{
Int32U res = MmcSendCmd(CMD16,length);
  MmcChipSelect(0);
  return(res);
}

/*************************************************************************
 * Function Name: MmcInitMedia
 * Parameters: none
 *
 * Return: MmcState_t
 *
 * Description: Mmc detect and initialize
 *
 *************************************************************************/
MmcState_t MmcInitMedia (void)
{
Int32U i,res;
  Tnac = 1;
  if(!MmcPresent())
  {
    return(MmcNoPresent);
  }
  // Clock Freq. Identification Mode < 400kHz
  MmcSetClockFreq(IdentificationModeClock);

  // Set maximum time out
  Tnac = IdentificationModeClock/SD_READ_TIME_OUT;

  // Power up cycles
  for(i = 0; i<2; i++)
  {
    // After power up at least 74 clock cycles are required prior to
    // starting bus communication
    MmcChipSelect(0);
    for(res = 10; res; --res)
    {
      MmcTranserByte(0xFF);
    }
    // CMD0 (Go to IDLE) to put MMC in SPI mode
    res = MmcSendCmd(CMD0,0);
    MmcChipSelect(0);
    if(res == MMC_ILDE_STATE)
    {
      break;
    }
  }

  if(res != MMC_ILDE_STATE)
  {
    return(MmcNoResponse);
  }

  // Determinate Card type SD or MMC
  MmcDskStatus.DiskType = DiskMMC;
  for(i=100;i;--i)
  {
    MmcChipSelect(0);
    MmcTranserByte(0xFF);
    res = MmcSendCmd(CMD55,0);
    MmcChipSelect(0);
    MmcChipSelect(0);
    MmcTranserByte(0xFF);
    res = MmcSendCmd(ACMD41,0);
    MmcChipSelect(0);
    if(res & MMC_ILLEGAL_CMD)
    {
      // MMC card may be
      // CMD1 for MMC Init sequence
      // will be complete within 500ms
      for (i = 100; i;--i)
      {
        MmcChipSelect(0);
        MmcTranserByte(0xFF);
        res = MmcSendCmd(CMD1,0);
        MmcChipSelect(0);
        if(res == MMC_OK)
        {
          // Init complete
          break;
        }
        MmcDly_1ms(50);
      }
      break;
    }
    if(res == MMC_OK)
    {
      // SD card is find
      MmcDskStatus.DiskType = DiskSD;
      break;
    }
    MmcDly_1ms(50);
  }

  if(i == 0)
  {
    return(MmcNoResponse);
  }

  // Read CSD
  res = MmcReadCardInfo(MmcSdCsd,CMD9);
  if(res != MmcOk)
  {
    // CSD must be always valid
    return(MmcNoResponse);
  }

  // Implement CSD data
  MmcCsdImplemet();

  // Set Block size
  MmcSetBlockLen(MmcDskStatus.BlockSize);

  return(MmcOk);
}

/*************************************************************************
 * Function Name: MmcReadCardInfo
 * Parameters: pInt8U pData,
 *             MmcSpiCmdInd_t Command - CMD9, CMD10 are only allowed
 *
 * Return: MmcState_t
 *
 * Description: Read CSD or CID  registers depend of commoand
 *
 *************************************************************************/
MmcState_t MmcReadCardInfo(pInt8U pData, MmcSpiCmdInd_t Command)
{
Int32U i;
Int32U res;
  switch(Command)
  {
  case CMD9:
  case CMD10:
    break;
  default:
    return(MmmcParameterError);
  }
  MmcChipSelect(0);
  MmcTranserByte(0xFF);
  res = MmcSendCmd(Command,0);
  if (res == MMC_OK)
  {
    for(i = 8; i ; --i)
    {
      res = MmcTranserByte(0xFF);
      if((res | MMC_DATA_ERR_TOLKEN) == MMC_DATA_ERR_TOLKEN)
      {
        MMC_RET_DATA_ERR(res);
      }
      else if (res == MMC_DATA_TOLKEN)
      {
        for(i = 0; i <16 ; ++i)
        {
          *pData++ = MmcTranserByte(0xFF);
        }
        // CRC receive
        MmcTranserByte(0xFF);
        MmcTranserByte(0xFF);
        MmcChipSelect(0);
        return(MmcOk);
      }
    }
  }
  MmcChipSelect(0);
  MMC_RET_ERROR(res);
}

/*************************************************************************
 * Function Name: MmcCsdImplemet
 * Parameters:  none
 *
 * Return: none
 *
 * Description: Implemet data from CSD
 *
 *************************************************************************/

⌨️ 快捷键说明

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