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

📄 emif270.c

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

    (c)Texas Instruments 2003
*/

/**
    \file emif270.c
    \brief EMIF Related APIs
*/

#include <emif270.h>


/**
    \brief  Set EMIF configuration

    \param  emifID      EMIF memory region ID
    \param  emifConfig  External Memory I/F configuration paramters

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

    \see EMIF_ID, EMIF_ConfigData
*/
STATUS EMIF_setConfig( EMIF_ID emifID, EMIF_ConfigData *emifConfig ) {

  switch(emifID)
  {
    case EMIF_CS0:
        if((emifConfig->oeWidth < 1) ||  (emifConfig->oeWidth > 16)
         ||(emifConfig->weWidth < 1) ||  (emifConfig->weWidth > 16)
         ||(emifConfig->ceWidth < 1) ||  (emifConfig->ceWidth > 16)
         ||(emifConfig->cycleWidth < 2) ||  (emifConfig->cycleWidth > 16)
         ||(emifConfig->idleWidth > 3) ||  (emifConfig->oeSetupWidth > 15)
         ||(emifConfig->weSetupWidth > 15) ||  (emifConfig->ceSetupWidth > 15))
         {
            return E_INVALID_INPUT;
         }

        EMIF_FSET(CS0CTRL1,OEC0,emifConfig->oeWidth - 1);
        EMIF_FSET(CS0CTRL1,WEC0,emifConfig->weWidth - 1);
        EMIF_FSET(CS0CTRL1,CEC0,emifConfig->ceWidth - 1);
        EMIF_FSET(CS0CTRL1,CYCL0,emifConfig->cycleWidth - 1);
        EMIF_FSET(CS0CTRL2,IDLE0,emifConfig->idleWidth);
        EMIF_FSET(CS0CTRL2,OESU0,emifConfig->oeSetupWidth);
        EMIF_FSET(CS0CTRL2,WESU0,emifConfig->weSetupWidth);
        EMIF_FSET(CS0CTRL2,CESU0,emifConfig->ceSetupWidth);
        break;

    case EMIF_CS1:
        if((emifConfig->oeWidth < 1) ||  (emifConfig->oeWidth > 32)
         ||(emifConfig->weWidth < 1) ||  (emifConfig->weWidth > 32)
         ||(emifConfig->ceWidth < 1) ||  (emifConfig->ceWidth > 32)
         ||(emifConfig->cycleWidth < 2) ||  (emifConfig->cycleWidth > 32)
         ||(emifConfig->idleWidth > 3) ||  (emifConfig->oeSetupWidth > 15)
         ||(emifConfig->weSetupWidth > 15) ||  (emifConfig->ceSetupWidth > 15))
         {
            return E_INVALID_INPUT;
         }

        EMIF_FSET(CS1CTRL1B,OEC1,emifConfig->oeWidth - 1);
        EMIF_FSET(CS1CTRL1B,WEC1,emifConfig->weWidth - 1);
        EMIF_FSET(CS1CTRL1A,CEC1,emifConfig->ceWidth - 1);
        EMIF_FSET(CS1CTRL1A,CYCL1,emifConfig->cycleWidth - 1);
        EMIF_FSET(CS1CTRL2,IDLE1,emifConfig->idleWidth);
        EMIF_FSET(CS1CTRL2,OESU1,emifConfig->oeSetupWidth);
        EMIF_FSET(CS1CTRL2,WESU1,emifConfig->weSetupWidth);
        EMIF_FSET(CS1CTRL2,CESU1,emifConfig->ceSetupWidth);
        break;

    case EMIF_CS2:
        if((emifConfig->oeWidth < 1) ||  (emifConfig->oeWidth > 16)
         ||(emifConfig->weWidth < 1) ||  (emifConfig->weWidth > 16)
         ||(emifConfig->cycleWidth < 2) ||  (emifConfig->cycleWidth > 16)
         ||(emifConfig->idleWidth > 3) ||  (emifConfig->oeSetupWidth > 15)
         ||(emifConfig->weSetupWidth > 15)
         ||(emifConfig->ceSetupWidth < 3) ||  (emifConfig->ceSetupWidth > 18))
         {
            return E_INVALID_INPUT;
         }

        EMIF_FSET(CS2CTRL1,OEC2,emifConfig->oeWidth - 1);
        EMIF_FSET(CS2CTRL1,WEC2,emifConfig->weWidth - 1);
        EMIF_FSET(CS2CTRL1,CYCL2,emifConfig->cycleWidth - 1);
        EMIF_FSET(CS2CTRL2,IDLE2,emifConfig->idleWidth);
        EMIF_FSET(CS2CTRL2,OESU2,emifConfig->oeSetupWidth);
        EMIF_FSET(CS2CTRL2,WESU2,emifConfig->weSetupWidth);
        EMIF_FSET(CS2CTRL2,RESU2,emifConfig->ceSetupWidth - 3);
        break;

    case EMIF_CS3:
        if((emifConfig->oeWidth < 1) ||  (emifConfig->oeWidth > 16)
         ||(emifConfig->weWidth < 1) ||  (emifConfig->weWidth > 16)
         ||(emifConfig->ceWidth < 1) ||  (emifConfig->ceWidth > 16)
         ||(emifConfig->cycleWidth < 2) ||  (emifConfig->cycleWidth > 16)
         ||(emifConfig->idleWidth > 3) ||  (emifConfig->oeSetupWidth > 15)
         ||(emifConfig->weSetupWidth > 15) ||  (emifConfig->ceSetupWidth > 15)
         ||(emifConfig->busWidth < EMIF_BUSWID_8) ||  (emifConfig->busWidth > EMIF_BUSWID_16))
         {
            return E_INVALID_INPUT;
         }

        EMIF_FSET(CS3CTRL1,OEC3,emifConfig->oeWidth - 1);
        EMIF_FSET(CS3CTRL1,WEC3,emifConfig->weWidth - 1);
        EMIF_FSET(CS3CTRL1,CEC3,emifConfig->ceWidth - 1);
        EMIF_FSET(CS3CTRL1,CYCL3,emifConfig->cycleWidth - 1);
        EMIF_FSET(CS3CTRL2,IDLE3,emifConfig->idleWidth);
        EMIF_FSET(CS3CTRL2,OESU3,emifConfig->oeSetupWidth);
        EMIF_FSET(CS3CTRL2,WESU3,emifConfig->weSetupWidth);
        EMIF_FSET(CS3CTRL2,CESU3,emifConfig->ceSetupWidth);
        EMIF_FSET(CS3CTRL2,BUSW3,emifConfig->busWidth);
        break;

    case EMIF_CS4:
        if((emifConfig->oeWidth < 1) ||  (emifConfig->oeWidth > 16)
         ||(emifConfig->weWidth < 1) ||  (emifConfig->weWidth > 16)
         ||(emifConfig->ceWidth < 1) ||  (emifConfig->ceWidth > 16)
         ||(emifConfig->cycleWidth < 1) ||  (emifConfig->cycleWidth > 16)
         ||(emifConfig->idleWidth > 3) ||  (emifConfig->oeSetupWidth > 15)
         ||(emifConfig->weSetupWidth > 15) ||  (emifConfig->ceSetupWidth > 15)
         ||(emifConfig->busWidth < EMIF_BUSWID_8) ||  (emifConfig->busWidth > EMIF_BUSWID_16)
         ||(emifConfig->cePolarity < EMIF_CE_LOW) ||  (emifConfig->cePolarity > EMIF_CE_HIGH) )
         {
            return E_INVALID_INPUT;
         }

        EMIF_FSET(CS4CTRL1,OEC4,emifConfig->oeWidth - 1);
        EMIF_FSET(CS4CTRL1,WEC4,emifConfig->weWidth - 1);
        EMIF_FSET(CS4CTRL1,CEC4,emifConfig->ceWidth - 1);
        EMIF_FSET(CS4CTRL1,CYCL4,emifConfig->cycleWidth - 1);
        EMIF_FSET(CS4CTRL2,IDLE4,emifConfig->idleWidth);
        EMIF_FSET(CS4CTRL2,OESU4,emifConfig->oeSetupWidth);
        EMIF_FSET(CS4CTRL2,WESU4,emifConfig->weSetupWidth);
        EMIF_FSET(CS4CTRL2,CESU4,emifConfig->ceSetupWidth);
        EMIF_FSET(CS4CTRL2,BUSW4,emifConfig->busWidth);
        EMIF_FSET(CS4CTRL2,CESL4,emifConfig->cePolarity);
        break;
    default:
        return E_INVALID_INPUT;
  }

  return E_PASS;
}

/**
    \brief  Set EMIF access Priority

    Set the priority for EMIF access from ARM/DMA/Image Buffer/DSP(HPIB)

    \param  moduleID    Module ID of the module for which priority is to be set
    \param  emifPriority Priority of the module

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

    \see EMIF_MOD_ID, EMIF_PRIORITY
*/
STATUS EMIF_setPriority( EMIF_MOD_ID moduleID, EMIF_PRIORITY emifPriority ){

    switch(emifPriority)
    {
        case EMIF_PRIORITY_1:
            EMIF_FSET(PRIOCTL,PRY1,moduleID);
            break;
        case EMIF_PRIORITY_2:
            EMIF_FSET(PRIOCTL,PRY2,moduleID);
            break;
        case EMIF_PRIORITY_3:
            EMIF_FSET(PRIOCTL,PRY3,moduleID);
            break;
        case EMIF_PRIORITY_4:
            EMIF_FSET(PRIOCTL,PRY4,moduleID);
            break;
        default:
            return E_INVALID_INPUT;
    }
    return E_PASS;
}

/**
    \brief  Set DMA Configuration for EMIF

    \param  emifDmaConfig   DMA Configuration Parameters

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

    \see EMIF_DMAConfigData

    \note
     - Source Address should be the offset from base address of source device
     - Source Address should be 4 byte aligned
     - Destination Address should be the offset from base address of destination device
     - Destination Address should be 4 byte aligned
     - DMA size should be multiple of 4 bytes
*/
STATUS EMIF_setDmaConfig(EMIF_DMAConfigData *emifDmaConfig) {

  Uint32 srcAddr = (Uint32)(emifDmaConfig->source);
  Uint32 destAddr = (Uint32)(emifDmaConfig->destination);

  if(((srcAddr % 4) != 0) || ((destAddr % 4) != 0) || ((emifDmaConfig->dmaSize)%4 != 0))
    return E_INVALID_INPUT;

  EMIF_RSET(SOURCEADDL,srcAddr);
  EMIF_FSET(SOURCEADDH,SAH,srcAddr >> 16);
  if(emifDmaConfig->srcAddrFixed == TRUE)
    EMIF_FSET(SOURCEADDH,SAFIX,1);
  else
    EMIF_FSET(SOURCEADDH,SAFIX,0);

  EMIF_RSET(DESTADDL,destAddr);
  EMIF_FSET(DESTADDH,DAH,destAddr >> 16);
  if(emifDmaConfig->destAddrFixed == TRUE)
    EMIF_FSET(DESTADDH,DAFIX,1);
  else
    EMIF_FSET(DESTADDH,DAFIX,0);

  EMIF_RSET(DMASIZE,emifDmaConfig->dmaSize);

  EMIF_FSET(DMADEVSEL,SDV,emifDmaConfig->srcDev);
  EMIF_FSET(DMADEVSEL,DDV,emifDmaConfig->destDev);

  EMIF_FSET(DMACTL,ENDI,emifDmaConfig->swapMode);

  return E_PASS;
}

/**
    \brief  Update DMA Source Address

    Used when only the source address has to be modified in dmaConfig

    \param  source  Pointer to source data

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

    \note
     - Source Address should be the offset from base address of source device
     - Source Address should be 4 byte aligned
*/
STATUS EMIF_updateSrcAddr(Uint32 * source) {

  Uint32 srcAddr = (Uint32)(source);

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

  EMIF_RSET(SOURCEADDL,srcAddr);
  EMIF_FSET(SOURCEADDH,SAH,srcAddr >> 16);

  return E_PASS;
}

/**
    \brief  Update DMA Destination Address

    Used when only the Destination address has to be modified in dmaConfig

    \param  destination     Pointer to Destination data

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

    \note
     - Destination Address should be the offset from base address of Destination device
     - Destination Address should be 4 byte aligned
*/
STATUS EMIF_updateDestAddr(Uint32 * destination) {

  Uint32 destAddr = (Uint32)destination;

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

  EMIF_RSET(DESTADDL,destAddr);
  EMIF_FSET(DESTADDH,DAH,destAddr >> 16);

  return E_PASS;
}

/**
    \brief  Start DMA Transfer

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

*/
STATUS EMIF_dmaStart() {

  EMIF_FSET(DMACTL,GO,1);

  return E_PASS;
}

/**
    \brief  Wait for transfer of DMA completion

    \param  timeOut     Wait for DMA completion for this timeout value

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

    \note   Currently, timeout is not used

*/
STATUS EMIF_dmaWait(Uint32 timeOut) {

  while(EMIF_FGET(DMACTL,GO) != 0);

    return E_PASS;
}

/**
    \brief  Get the Start Address of any EMIF region

    \param  emifID  EMIF region ID, including SDRAM region

    \return start address of EMIF region, error if invalid input

*/
Uint32 EMIF_getStartAddress(EMIF_ID emifID) {

  Uint32 retAddress;

  switch(emifID)
  {
    case EMIF_CS0:
        retAddress = 0x100000;
        break;
    case EMIF_SDRAM:
        retAddress = (Uint32)( EMIF_FGET(DPSTR0,DST0) << 20 );
        break;
    case EMIF_CS1:
        retAddress = (Uint32)( EMIF_FGET(DPSTR1,DST1) << 20 );
        break;
    case EMIF_CS2:
        retAddress = (Uint32)( EMIF_FGET(DPSTR2,DST2) << 20 );
        break;
    case EMIF_CS3:
        retAddress = (Uint32)( EMIF_FGET(DPSTR3,DST3) << 20 );
        break;
    case EMIF_CS4:
        retAddress = (Uint32)( EMIF_FGET(DPSTR4,DST4) << 20 );
        break;
    default:
        return 0;
  }

  return retAddress;
}

/**
    \brief  Set the Start Address of an EMIF region

    \param  emifID  EMIF region ID, including SDRAM region, except EMIF_CS0, whose start address is fixed to 0x100000
    \param  address Absolute start address for EMIF region, must be aligned on a MB boundary

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

    \see EMIF_ID

    \note  address should be absolute

*/
STATUS EMIF_setStartAddress(EMIF_ID emifID, Uint32 address) {
    STATUS status=E_PASS;
    
    switch(emifID)
    {
        case EMIF_SDRAM:
            EMIF_FSET(DPSTR0,DST0,address >> 20 );
            break;
        case EMIF_CS1:
            EMIF_FSET(DPSTR1,DST1,address >> 20 );
            break;
        case EMIF_CS2:
            EMIF_FSET(DPSTR2,DST2,address >> 20 );
            break;
        case EMIF_CS3:
            EMIF_FSET(DPSTR3,DST3,address >> 20 );
            break;
        case EMIF_CS4:
            EMIF_FSET(DPSTR4,DST4,address >> 20 );
            break;
        default:
            status = E_INVALID_INPUT;
            break;
    }

    return status;
}

/**
    \brief  Configure data transfer between Image buffer and EMIF or DSP internal memory and EMIF

    \param  imgOrDspTransfer    TRUE:Image Buffer to EMIF transfer, FALSE:DSP internal memory to EMIF transfer
    \param  emifID              EMIF region ID, SDRAM region is only valid for transfers involving DSP internal memory
    \param  address             source/destination address, must be specified as offset from start of respective EMIF region. Valid only when source/destination is EMIF_CS1 or EMIF_CS2, In this case the address is fixed (i.e no auto-increment of address)

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

    \see EMIF_ID
*/
STATUS EMIF_setImgDspConfig(BOOL imgOrDspTransfer, EMIF_ID emifID, Uint32 address) {

    if(imgOrDspTransfer == TRUE)
        EMIF_FSET(IMGDSPDEST,IDST,emifID);
    else
        EMIF_FSET(IMGDSPDEST,DDST,emifID);

    if(emifID == EMIF_CS1 || emifID == EMIF_CS2)
    {
        EMIF_RSET(IMGDSPADDL,address);
        EMIF_FSET(IMGDSPADDH,CDAH, address >> 16);
    }

    return E_PASS;
}

⌨️ 快捷键说明

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