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

📄 mmc.c

📁 包含了NXP众多的MCU的例子程序
💻 C
📖 第 1 页 / 共 2 页
字号:
void MmcCsdImplemet (void)
{
Int32U Freq;
  // Calculate SPI max clock
  Freq = MmcTransfExp[CSD_GET_TRAN_SPEED_EXP()] * MmcCsdMant[CSD_GET_TRAN_SPEED_MANT()];
  if(Freq > (20MHZ))
  {
    Freq = (20MHZ);
  }
  Freq = MmcSetClockFreq(Freq);
  if(MmcDskStatus.DiskType == DiskMMC)
  {
    // Calculate Time outs
    Tnac = MmmcAccessTime[CSD_GET_TAAC_EXP()] * MmcAccessTimeMant[CSD_GET_TAAC_MANT()];
    Tnac = Freq/Tnac;
    // (2^NSAC)*16 ~ (100*2^NSAC)/8
    Tnac += 1<<(CSD_GET_NSAC()+4);
    // Max time out
    Tnac *= 10;
    Twr   = Tnac * CSD_GET_R2W_FACTOR();
    // Calculate Block size and Block Number
  }
  else
  {
    Tnac = Freq/SD_READ_TIME_OUT;
    Twr  = Freq/SD_WRITE_TIME_OUT;
  }
  MmcDskStatus.BlockSize = 1<<CSD_GET_READ_BL_LEN();
  MmcDskStatus.BlockNumb = (CSD_GET_C_SIZE()+1)*(4<<CSD_GET_C_SIZE_MULT());
  // Set Write Protect
  MmcDskStatus.WriteProtect = MmcWriteProtect() |\
                              CSD_GET_PERM_WRITE_PROTECT() |\
                              CSD_GET_TMP_WRITE_PROTECT();
}

/*************************************************************************
 * Function Name: MmcRead
 * Parameters: pInt8U pData, Int32U Add, Int32U Length
 *
 * Return: MmcState_t
 *
 * Description: Read from a Mmc
 *
 *************************************************************************/
inline
MmcState_t MmcRead(pInt8U pData, Int32U Add, Int32U Length)
{
Int32U res,i;
  // For synchronization
  MmcChipSelect(0);
  MmcTranserByte(0xFF);
  res = MmcSendCmd(CMD17,Add);
  if(res == MMC_OK)
  {
    for(i = Tnac; 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)
      {
        // Receive block
        MmcReceiveBlock(pData,Length);
        // CRC receive
        MmcTranserByte(0xFF);
        MmcTranserByte(0xFF);
        MmcChipSelect(0);
        return(MmcOk);
      }
    }
    MmcChipSelect(0);
    return(MmcNoResponse);
  }
  MmcChipSelect(0);
  MMC_RET_ERROR(res);
}

/*************************************************************************
 * Function Name: MmcWrite
 * Parameters: pInt8U pData, Int32U Add, Int32U Length
 *
 * Return: MmcState_t
 *
 * Description: Write to a Mmc
 *
 *************************************************************************/
inline MmcState_t MmcWrite(pInt8U pData, Int32U Add, Int32U Length)
{
Int32U res,i;
  // For synchronization
  MmcChipSelect(0);
  MmcTranserByte(0xFF);

  res = MmcSendCmd(CMD24,Add);
  if(res == MMC_OK)
  {
    MmcTranserByte(0xFF);
    MmcTranserByte(MMC_DATA_TOLKEN);
    // Send block
    MmcSendBlock(pData,Length);
    // CRC Send
    MmcTranserByte(0xFF);
    MmcTranserByte(0xFF);
    if((MmcTranserByte(0xFF) & 0x1F) != 0x05)
    {
      MMC_RET_ERROR(res);
    }

    for(i = Twr; i ;i--)
    {
      if(MmcTranserByte(0xFF) == 0xFF)
      {
        break;
      }
    }
    MmcChipSelect(0);
    if (i == 0)
    {
      return(MmcNoResponse);
    }
    return(MmcOk);
  }
  MmcChipSelect(0);
  MMC_RET_ERROR(res);
}

/*************************************************************************
 * Function Name: MmcVerify
 * Parameters: pInt8U pData, Int32U Add, Int32U Length
 *
 * Return: MmcState_t
 *
 * Description: Verify on a Mmc
 *
 *************************************************************************/
inline
MmcState_t MmcVerify(pInt8U pData, Int32U Add, Int32U Length)
{
Int32U res,i;
  // For synchronization
  MmcChipSelect(0);
  MmcTranserByte(0xFF);
  res = MmcSendCmd(CMD17,Add);
  if(res == MMC_OK)
  {
    for(i = Tnac;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)
      {
        res = 0;
        for(i = 0; i<Length;++i,++pData)
        {
          *pData ^= MmcTranserByte(0xFF);
          if (*pData != 0)
          {
            res = 1;
          }
        }
        // CRC receive
        MmcTranserByte(0xFF);
        MmcTranserByte(0xFF);
        MmcChipSelect(0);
        MmcTranserByte(0xFF);
        MmcTranserByte(0xFF);
        if (res)
        {
          return(MmcMiscompare);
        }
        return(MmcOk);
      }
    }
    return(MmcNoResponse);
  }
  MMC_RET_ERROR(res);
}

/*************************************************************************
 * Function Name: MmcGetLastError
 * Parameters: none
 *
 * Return: Int32U
 *
 * Description: Return Last error
 *
 *************************************************************************/
Int32U MmcGetLastError(void)
{
  return(MmcLastError);
}

/*************************************************************************
 * Function Name: MmcStatusUpdate
 * Parameters: none
 *
 * Return: none
 *
 * Description: Update status of SD/MMC card
 *
 *************************************************************************/
void MmcStatusUpdate (void)
{
  if(MmcDskStatus.DiskStatus != DiskCommandPass)
  {
    switch (MmcInitMedia())
    {
    case MmcOk:
      MmcCsdImplemet();
      MmcDskStatus.DiskStatus = DiskCommandPass;
      MmcDskStatus.MediaChanged = TRUE;
      break;
    case MmcCardError:
    case MmcDataError:
      MmcDskStatus.DiskStatus = DiskNotReady;
      break;
    default:
      MmcDskStatus.DiskStatus = DiskNotPresent;
      break;
    }
  }
  else if (MmcReadCardInfo(MmcSdCsd,CMD9) != MmcOk)
  {
    MmcDskStatus.DiskStatus = DiskNotReady;
  }
}

/*************************************************************************
 * Function Name: MmcDiskInit
 * Parameters:  none
 *
 * Return: none
 *
 * Description: Init MMC/SD disk
 *
 *************************************************************************/
void MmcDiskInit (void)
{
  MmcDskStatus.BlockNumb =\
  MmcDskStatus.BlockSize =\
  MmcLastError           = 0;
  // Init SPI
  MmcInit();
  // Media Init
  switch (MmcInitMedia())
  {
  case MmcOk:
    MmcCsdImplemet();
    MmcDskStatus.DiskStatus = DiskCommandPass;
    MmcDskStatus.MediaChanged = TRUE;
    break;
  case MmcCardError:
  case MmcDataError:
    MmcDskStatus.DiskStatus = DiskNotReady;
    break;
  default:
    MmcDskStatus.DiskStatus = DiskNotPresent;
    break;
  }
}

/*************************************************************************
 * Function Name: MmcDiskInfo
 * Parameters:  pInt8U pData, DiskInfoType_t DiskInfoType
 *
 * Return: Int32U
 *
 * Description: Return pointer to Info stucture of the disk
 * (Inquiry or Format capacity)
 *
 *************************************************************************/
Int32U MmcDiskInfo (pInt8U pData, DiskInfoType_t DiskInfoType)
{
pMmc3FormatCapResponse_t pFormatCapacity;
  switch (DiskInfoType)
  {
  case DiskInquiry:
    memcpy(pData,MmcDskInquiry,SizeOfInquiryDescMmcDsk);
    return(SizeOfInquiryDescMmcDsk);
  case DiskFormatCapacity:
    pFormatCapacity = (pMmc3FormatCapResponse_t)pData;
    memset(pFormatCapacity,0,sizeof(Mmc3FormatCapResponse_t));
    pFormatCapacity->CapacityListLength = sizeof(Mmc3FormatCapDescriptor_t);
    if (MmcDskStatus.DiskStatus != DiskCommandPass)
    {
      pFormatCapacity->MaximumDescriptor.DescriptorType    = FormattedMedia;
      pFormatCapacity->MaximumDescriptor.BlockLength[0]    = (MmcDskStatus.BlockSize >> 16) & 0xFF;
      pFormatCapacity->MaximumDescriptor.BlockLength[1]    = (MmcDskStatus.BlockSize >>  8) & 0xFF;
      pFormatCapacity->MaximumDescriptor.BlockLength[2]    = (MmcDskStatus.BlockSize      ) & 0xFF;
      pFormatCapacity->MaximumDescriptor.NumberofBlocks[0] = (MmcDskStatus.BlockNumb >> 24) & 0xFF;
      pFormatCapacity->MaximumDescriptor.NumberofBlocks[1] = (MmcDskStatus.BlockNumb >> 16) & 0xFF;
      pFormatCapacity->MaximumDescriptor.NumberofBlocks[2] = (MmcDskStatus.BlockNumb >>  8) & 0xFF;
      pFormatCapacity->MaximumDescriptor.NumberofBlocks[3] = (MmcDskStatus.BlockNumb      ) & 0xFF;
    }
    else
    {
      pFormatCapacity->MaximumDescriptor.DescriptorType    = NoMediaPresent;
      pFormatCapacity->MaximumDescriptor.BlockLength[0]    = (2048       >> 16) & 0xFF;
      pFormatCapacity->MaximumDescriptor.BlockLength[1]    = (2048       >>  8) & 0xFF;
      pFormatCapacity->MaximumDescriptor.BlockLength[2]    = (2048            ) & 0xFF;
      pFormatCapacity->MaximumDescriptor.NumberofBlocks[0] = (0xFFFFFFFF >> 24) & 0xFF;
      pFormatCapacity->MaximumDescriptor.NumberofBlocks[1] = (0xFFFFFFFF >> 16) & 0xFF;
      pFormatCapacity->MaximumDescriptor.NumberofBlocks[2] = (0xFFFFFFFF >>  8) & 0xFF;
      pFormatCapacity->MaximumDescriptor.NumberofBlocks[3] = (0xFFFFFFFF      ) & 0xFF;
    }
    return(sizeof(Mmc3FormatCapResponse_t));
  }
  return(0);
}

/*************************************************************************
 * Function Name: MmcDiskStatus
 * Parameters:  none
 *
 * Return: pDiskStatus_t
 *
 * Description: Return pointer to status stucture of the disk
 *
 *************************************************************************/
pDiskStatus_t MmcDiskStatus (void)
{
  return(&MmcDskStatus);
}

/*************************************************************************
 * Function Name: MmcDiskIO
 * Parameters: pInt8U pData,Int32U BlockStart,
 *             Int32U BlockNum, DiskIoRequest_t IoRequest
 *
 * Return: DiskStatusCode_t
 *
 * Description: MMC/SD disk I/O
 *
 *************************************************************************/
DiskStatusCode_t MmcDiskIO (pInt8U pData,Int32U BlockStart,
                             Int32U BlockNum, DiskIoRequest_t IoRequest)
{
  if((pData == NULL) || (BlockStart+BlockNum > MmcDskStatus.BlockNumb))
  {
    return(DiskParametersError);
  }
  if (MmcDskStatus.DiskStatus)
  {
    return(MmcDskStatus.DiskStatus);
  }
  switch (IoRequest)
  {
  case DiskWrite:
    if(MmcDskStatus.WriteProtect)
    {
      return(DiskParametersError);
    }
    switch (MmcWrite(pData,BlockStart*MmcDskStatus.BlockSize,BlockNum*MmcDskStatus.BlockSize))
    {
    case MmcOk:
      break;
    case MmcCardError:
    case MmcDataError:
      MmcDskStatus.DiskStatus = DiskNotReady;
      break;
    default:
      MmcDskStatus.DiskStatus = DiskNotPresent;
      break;
    }
    break;
  case DiskRead:
    switch (MmcRead(pData,BlockStart*MmcDskStatus.BlockSize,BlockNum*MmcDskStatus.BlockSize))
    {
    case MmcOk:
      break;
    case MmcCardError:
    case MmcDataError:
      MmcDskStatus.DiskStatus = DiskNotReady;
      break;
    default:
      MmcDskStatus.DiskStatus = DiskNotPresent;
      break;
    }
    break;
  case DiskVerify:
    switch (MmcVerify(pData,BlockStart*MmcDskStatus.BlockSize,BlockNum*MmcDskStatus.BlockSize))
    {
    case MmcOk:
      break;
    case MmcMiscompare:
      return(DiskMiscompareError);
    case MmcCardError:
    case MmcDataError:
      MmcDskStatus.DiskStatus = DiskNotReady;
      break;
    default:
      MmcDskStatus.DiskStatus = DiskNotPresent;
      break;
    }
    break;
  default:
    return(DiskParametersError);
  }
  return(MmcDskStatus.DiskStatus);
}

⌨️ 快捷键说明

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