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

📄 mmcsd270.c

📁 dm270 source code
💻 C
字号:
/*
    DM270 ARM Evaluation Software

    (c)Texas Instruments 2003
*/

/**
    \file mmcsd270.c
    \brief MMC/SD Related APIs
*/

#include <mmcsd270.h>

/**
    \brief  Set MMCSD Controller configuration

    \param  mmcsdConfig MMCSD Controller configuration paramters

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

    \see MMCSD_ConfigData
*/
STATUS MMCSD_setConfig(MMCSD_ConfigData * mmcsdConfig) {

  Uint16 modebits, modemask;

  /* Create a bit map of the values in the fields */
  modebits = MMCSD_FMK(MMCCTL, PERMDX, mmcsdConfig->writeEndian) |
             MMCSD_FMK(MMCCTL, PERMDR, mmcsdConfig->readEndian ) |
             MMCSD_FMK(MMCCTL, DATED,  mmcsdConfig->dat3Detect ) |
             MMCSD_FMK(MMCCTL, WIDTH,  mmcsdConfig->busWidth   );

  if(mmcsdConfig->spiModeEnable == TRUE)
    modebits |= MMCSD_FMK(MMCCTL, SPIEN, 1);
  else
    modebits |= MMCSD_FMK(MMCCTL, SPIEN, 0);

  if(mmcsdConfig->csEnable == TRUE)
    modebits |= MMCSD_FMK(MMCCTL, CSEN, 1);
  else
    modebits |= MMCSD_FMK(MMCCTL, CSEN, 0);

  if(mmcsdConfig->spiCrcErrCheckEnable == TRUE)
    modebits |= MMCSD_FMK(MMCCTL, SPICRC, 1);
  else
    modebits |= MMCSD_FMK(MMCCTL, SPICRC, 0);

  /* Create a bit mask for the selected fields */
  modemask = MMCSD_FMK(MMCCTL, PERMDX, 0xFFFF) |
             MMCSD_FMK(MMCCTL, PERMDR, 0xFFFF) |
             MMCSD_FMK(MMCCTL, DATED,  0xFFFF) |
             MMCSD_FMK(MMCCTL, WIDTH,  0xFFFF) |
             MMCSD_FMK(MMCCTL, SPIEN,  0xFFFF) |
             MMCSD_FMK(MMCCTL, CSEN,   0xFFFF) |
             MMCSD_FMK(MMCCTL, SPICRC, 0xFFFF);

  MMCSD_RAOI( MMCCTL, ~modemask, modebits, 0 );

  MMCSD_FSET(MMCTOR, TOR, mmcsdConfig->timeoutResponse);
  MMCSD_RSET(MMCTOD,mmcsdConfig->timeoutRead);

  return E_PASS;
}

/**
    \brief  Set MMC SD interrupt mask

    \param  mmcsdInt  Interrupt mask for MMC SD controller. Interrupt will be generated for all the interrupts that are enabled

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

    \see MMCSD_IntMode
*/
STATUS MMCSD_setIntMode(MMCSD_IntMode * mmcsdInt) {

  Uint16 intMask = 0x0;

  if(mmcsdInt->datedIntEnable == TRUE)
    intMask |= 0x0800;
  if(mmcsdInt->drRdyIntEnable == TRUE)
    intMask |= 0x0400;
  if(mmcsdInt->dxRdyIntEnable == TRUE)
    intMask |= 0x0200;
  if(mmcsdInt->spiErrIntEnable == TRUE)
    intMask |= 0x0100;
  if(mmcsdInt->crcErrReadIntEnable == TRUE)
    intMask |= 0x0080;
  if(mmcsdInt->crcErrResponseIntEnable == TRUE)
    intMask |= 0x0040;
  if(mmcsdInt->crcErrWriteIntEnable == TRUE)
    intMask |= 0x0020;
  if(mmcsdInt->timeoutResponseIntEnable == TRUE)
    intMask |= 0x0010;
  if(mmcsdInt->timeoutReadIntEnable == TRUE)
    intMask |= 0x0008;
  if(mmcsdInt->rspDneIntEnable == TRUE)
    intMask |= 0x0004;
  if(mmcsdInt->bsyDneIntEnable == TRUE)
    intMask |= 0x0002;
  if(mmcsdInt->datDneIntEnable == TRUE)
    intMask |= 0x0001;

  MMCSD_RSET(MMCIE,intMask);

  return E_PASS;
}


/**
    \brief  Set Data size for MMC SD

    \param  numBlks  Number of blocks for transfer, 0 for infinite number of blocks
    \param  blockSize  Block size for MMC SD, value of 0 is not allowed

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

*/
STATUS MMCSD_setDataSize(Uint16 numBlks, Uint16 blockSize) {

  if(blockSize == 0)
    return E_INVALID_INPUT;

  MMCSD_FSET(MMCBLEN,BLEN,blockSize);
  MMCSD_RSET(MMCNBLK,numBlks);

  return E_PASS;
}

/**
    \brief  Set and Enable clock for MMCSD card

    \param  enable      TRUE:Enable clock FALSE:Disable Clock
    \param  clockRate   MMCSD Divisor for the function clock, MMC Clock = Function Clock/clockRate. \n MMCSD Function clock is set using CLKC_setMMCClockDivValue(), range: 2..512, must be even number

    \return if success, \c E_PASS, else error code
*/
STATUS MMCSD_setClock(BOOL enable, Uint16 clockRate) {

  MMCSD_FSET(MMCCLK, CLKRT, clockRate/2 - 1);

  if(enable == TRUE)
    MMCSD_FSET(MMCCLK, CLEN, 1);
  else
    MMCSD_FSET(MMCCLK, CLEN, 0);

  return E_PASS;
}

/**
    \brief  Get Status of the MMCSD controller

    Reads the values of the status registers into the parameters passed

    \param  status0 Contents of MMCST0 received is in this parameter
    \param  status1 Contents of MMCST1 received is in this parameter

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

*/
STATUS MMCSD_getStatus(Uint16 * status0, Uint16* status1) {

  *status0 = MMCSD_RGET(MMCST0);
  *status1 = MMCSD_RGET(MMCST1);

  return E_PASS;
}

/**
    \brief  Get Response from MMC SD controller

    \param  mmcsdResponse Response data is received in this parameter

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

    \see MMCSD_ResponseData

*/
STATUS MMCSD_getResponse(MMCSD_ResponseData * mmcsdResponse) {

  mmcsdResponse->response[0] = MMCSD_RGET(MMCRSP0);
  mmcsdResponse->response[1] = MMCSD_RGET(MMCRSP1);
  mmcsdResponse->response[2] = MMCSD_RGET(MMCRSP2);
  mmcsdResponse->response[3] = MMCSD_RGET(MMCRSP3);
  mmcsdResponse->response[4] = MMCSD_RGET(MMCRSP4);
  mmcsdResponse->response[5] = MMCSD_RGET(MMCRSP5);
  mmcsdResponse->response[6] = MMCSD_RGET(MMCRSP6);
  mmcsdResponse->response[7] = MMCSD_RGET(MMCRSP7);

  mmcsdResponse->dataResponse = MMCSD_FGET(MMCDRSP,DRSP);

  mmcsdResponse->errorToken = MMCSD_FGET(MMCETOK,ETOK);

  mmcsdResponse->commandIdk = MMCSD_FGET(MMCCIDX,CIDX);

  return E_PASS;
}

/**
    \brief  Set MMCSD Controller DMA configuration

    \param  dmaConfig   MMC/SD DMA Controller configuration parameters

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

    \see MMCSD_DmaConfigData

    \note SDRAM address should be 32 bit aligned
*/
STATUS MMCSD_setDmaConfig(MMCSD_DmaConfigData * dmaConfig) {

  Uint32 addr;

  addr = dmaConfig->sdramAddress - (Uint32)SDRAM_MEMORY_BASE;
  if(addr % 4 != 0)
    return E_INVALID_INPUT;

  MMCSD_FSET(DMAMODE,DIR,dmaConfig->direction);

  if(dmaConfig->direction == MMCSD_FROM_MMC)
  {
    if(dmaConfig->wordSwapEnable == TRUE)
        MMCSD_FSET(DMAMODE,DPRMDR,1);
    else
        MMCSD_FSET(DMAMODE,DPRMDR,0);
  }
  else if(dmaConfig->direction == MMCSD_TO_MMC)
  {
    if(dmaConfig->wordSwapEnable == TRUE)
        MMCSD_FSET(DMAMODE,DPRMDX,1);
    else
        MMCSD_FSET(DMAMODE,DPRMDX,0);
  }

  MMCSD_RSET(DMATOR, dmaConfig->timeoutValue);

  if(dmaConfig->timeoutIntEnable == TRUE)
    MMCSD_FSET(DMAMODE,DTOIE,1);
  else
    MMCSD_FSET(DMAMODE,DTOIE,0);


  MMCSD_RSET(DMAAD0, addr);
  MMCSD_FSET(DMAAD1, ADRH, addr >> 16);

  return E_PASS;

}

/**
    \brief  Update the SDRAM address

    \param  sdramAddress    SDRAM address to be updated, SDRAM address should be 32 bit aligned

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

*/
STATUS MMCSD_updateDmaAddress(Uint32 sdramAddress) {

  Uint32 addr;

  addr = sdramAddress - (Uint32)SDRAM_MEMORY_BASE;

  if(addr % 4 != 0)
    return E_INVALID_INPUT;


  MMCSD_RSET(DMAAD0, addr);
  MMCSD_FSET(DMAAD1, ADRH, addr >> 16);

  return E_PASS;
}

/**
    \brief  Start DMA transfer

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

*/
STATUS MMCSD_dmaStart() {

  MMCSD_FSET(DMATRG,TRG,1);

  return E_PASS;
}

/**
    \brief  Stop DMA transfer

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

    \note This function returns just after breaking DMA transfer. Check using MMCSD_dmaWait() for the complete halt of DMA transfer
*/
STATUS MMCSD_dmaStop() {

  MMCSD_FSET(DMATRG,BRK,1);

  return E_PASS;
}

/**
    \brief  Wait for DMA transfer completion

    \return if success, \c E_PASS, Does not return if DMA is still running
*/
STATUS MMCSD_dmaWait() {

  while(MMCSD_FGET(DMASTAT1,RUNST) != 0);

  return E_PASS;
}

/**
    \brief  Get the total number of bytes remaining in dma transfer

    \return number of bytes remaining for transfer
*/
Uint32 MMCSD_getDmaCount() {

 Uint32 remBytes = 0x0;

 remBytes = MMCSD_FGET(DMASTAT1,REMH);
 remBytes = remBytes << 16;
 remBytes |= MMCSD_RGET(DMASTAT0);

 return remBytes;
}

⌨️ 快捷键说明

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