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

📄 sdrc270.c

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

    (c)Texas Instruments 2003
*/

/**
    \file sdrc270.c
    \brief SDRAM Controller Related APIs
*/

#include <sdrc270.h>

Uint16 *SDRC_Buffer16 = (Uint16 *)SDRC_ADDR(SDBUFD0L); ///< base address of SDRAM buferred access registers

/**
    \brief  Set SDRAM Controller configuration

    \param  sdrcConfig  SDRAM Controller configuration paramters

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

    \see SDRC_ConfigData
*/
STATUS SDRC_setConfig( SDRC_ConfigData *sdrcConfig ) {

  Int16  step;
  Uint16 modebits, modemask;
  Uint16 refbits, refmask;

  /* Create a bit map of the values in the fields */
  modebits = SDRC_FMK( SDMODE, TRDL,  sdrcConfig->trdlSelect  ) |
             SDRC_FMK( SDMODE, SDBW,  sdrcConfig->busWidth    ) |
             SDRC_FMK( SDMODE, TRCD,  sdrcConfig->trcdSelect  ) |
             SDRC_FMK( SDMODE, CASL,  sdrcConfig->casLatency  ) |
             SDRC_FMK( SDMODE, BNS,   sdrcConfig->bankSelect  ) |
             SDRC_FMK( SDMODE, MEMT,  sdrcConfig->memoryType  ) |
             SDRC_FMK( SDMODE, APO,   sdrcConfig->autoPowerDownMode == TRUE ? 1 : 0 ) |
             SDRC_FMK( SDMODE, DQMC,  sdrcConfig->dqmControl  ) |
             SDRC_FMK( SDMODE, SDCTL, SDRC_CTRLSEL_NOP );

  /* Create a bit mask for the selected fields */
  modemask = SDRC_FMK( SDMODE, TRDL,  0xFFFF               ) |
             SDRC_FMK( SDMODE, SDBW,  0xFFFF               ) |
             SDRC_FMK( SDMODE, TRCD,  0xFFFF               ) |
             SDRC_FMK( SDMODE, CASL,  0xFFFF               ) |
             SDRC_FMK( SDMODE, BNS,   0xFFFF               ) |
             SDRC_FMK( SDMODE, MEMT,  0xFFFF               ) |
             SDRC_FMK( SDMODE, DQMC,  0xFFFF               ) |
             SDRC_FMK( SDMODE, APO,   0xFFFF               ) |
             SDRC_FMK( SDMODE, SDCTL, 0xFFFF               );

  SDRC_RAOI( SDMODE, ~modemask, modebits, 0 );

  /* Create a bit map of the values in the fields */
  refbits = SDRC_FMK( REFCTL, REFC,  sdrcConfig->autoRefreshInterval ) |
            SDRC_FMK( REFCTL, REFEN, sdrcConfig->autoRefresh == TRUE ? 1 : 0 );

  /* Create a bit mask for the selected fields */
  refmask = SDRC_FMK( REFCTL, REFC,  0xFFFF ) |
            SDRC_FMK( REFCTL, REFEN, 0xFFFF );

  SDRC_RAOI( REFCTL, ~refmask, refbits, 0 );

  for (step = 0; step < sdrcConfig->numSequenceSteps; step++) {
    SDRC_RSET( SDMODE,  modebits | sdrcConfig->setupSequence[step] );
  }

  SDRC_FSET( SDMODE, DQMC, 0 ); // make DQMC normal

  return E_PASS;
}

/**
    \brief  Set SDRAM Controller Priority

    Set the priority for SDRAM transfers to different modules.

    By default DM270 uses default priorities for SDRAM access.
    In order to use the SDRAM priorities set by the user, use SDRC_enableUserDefinedPriority().

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

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

    \see SDRC_MOD_ID, SDRC_PRIORITY
*/
STATUS SDRC_setPriority( SDRC_MOD_ID moduleID, SDRC_PRIORITY sdrcPriority ){

    switch(moduleID)
    {
        case SDRC_CCDC:
            SDRC_RSET(SDPRTY1,sdrcPriority);
            break;
        case SDRC_PREV:
            SDRC_RSET(SDPRTY2,sdrcPriority);
            break;
        case SDRC_H3A:
            SDRC_RSET(SDPRTY3,sdrcPriority);
            break;
        case SDRC_OSD:
            SDRC_RSET(SDPRTY4,sdrcPriority);
            break;
        case SDRC_EXT_HOST:
            SDRC_RSET(SDPRTY5,sdrcPriority);
            break;
        case SDRC_ARM_CPU:
            SDRC_RSET(SDPRTY6,sdrcPriority);
            break;
        case SDRC_EM2:
            SDRC_RSET(SDPRTY7,sdrcPriority);
            break;
        case SDRC_EM1:
            SDRC_RSET(SDPRTY8,sdrcPriority);
            break;
        case SDRC_IMG_BUF:
            SDRC_RSET(SDPRTY9,sdrcPriority);
            break;
        case SDRC_AUTO_REF:
            SDRC_RSET(SDPRTY10,sdrcPriority);
            break;
        default:
            return E_INVALID_INPUT;
    }

    return E_PASS;
}

/**
    \brief  Enable User Defined Priority

    Enable the priority defined using SDRC_setPriority()

    \param  enable  TRUE:Enable, FALSE:Disable

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

*/
STATUS SDRC_enableUserDefinedPriority(BOOL enable) {

  if(enable == TRUE)
    SDRC_FSET( PRTYON,  USEPRTY, 1);
  else
    SDRC_FSET( PRTYON,  USEPRTY, 0);

  return E_PASS;
}

/**
    \brief  Select DMA Channel for EMIF/MMCSD/USB/SPI/DSP

    \param  dmaModuleID Module ID of the module for which DMA Channel is to be selected
    \param  dmaChannelID ID of the DMA Channel

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

    \see SDRC_DMA_MOD_ID, SDRC_DMA_CH
*/
STATUS SDRC_selectDmaChannel( SDRC_DMA_MOD_ID dmaModuleID, SDRC_DMA_CH dmaChannelID ){

  switch(dmaChannelID)
  {
    case SDRC_DMACH_1:
        SDRC_FSET(REFCTL,SDMA1, dmaModuleID);
        break;
    case SDRC_DMACH_2:
        SDRC_FSET(REFCTL,SDMA2, dmaModuleID);
        break;
    default:
        return E_INVALID_INPUT;
  }

  return E_PASS;
}

/**
    \brief  Clear data (to 0) present in SDRAM buffered access data registers

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

*/
STATUS SDRC_clearBufferData() {

  SDRC_FSET( SDBUFCTL, BUFC, 1 );

  return E_PASS;
}

/**
    \brief  Read from SDRAM using SDRAM buffered access mode

    Here data is read from SDRAM to SDRAM buffered access data registers. \n
    The data is then transferred from these data buffers to a user specified address (dataAddress). \n
    Typically, dataAddress should be an IRAM address

    \param  sdramAddress Absolute SDRAM address from where data is to be read
    \param  dataAddress  Data address where the read data is to be put
    \param  dataSize     Size of data to be read
    \param  portID       Port ID of the port used for SDRAM Access

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

    \see SDRC_PORT

    \note
    - dataSize should be a multiple of 32 bytes
    - sdramAddress must 32 byte aligned
    - When a port is used for SDRAM burst Access, the peripheral for that port cannot access SDRAM

*/
STATUS SDRC_burstRead(Uint32 *sdramAddress, Uint32 *dataAddress, Uint32 dataSize, SDRC_PORT portID ) {

  Uint32 addr;
  Uint32 bursts, words;
  Uint32 burstCount;

  addr = (Uint32)sdramAddress - SDRAM_MEMORY_BASE;

  //Data size has to be a multiple of 32 bytes
  if((dataSize%32) != 0 || (addr % 32) != 0)
    return E_INVALID_INPUT;


  //Address has to be a multiple of 32
  addr = addr / 32;

  burstCount = dataSize >> 5;

  SDRC_RSET( SDBUFAD2, addr );
  SDRC_FSET( SDBUFAD1, SDAH, addr >> 16 );
  SDRC_FSET( SDBUFAD1, AAI, 1);   /* enable address auto-increment */
  SDRC_FSET( SDBUFCTL, PTSEL, portID);

  /*-- Loop over bursts --*/
  for (bursts = 0; bursts < burstCount; bursts++) {

    /*-- Burst data from SDRAM to buffer --*/
    SDRC_FSET(SDBUFCTL,RSD,1);

    while (SDRC_FGET(SDBUFCTL,RSD) != 0 );

    /*-- Write data from buffer to destination --*/
    for (words = 0; (words < 16); words = words + 2) {
      *(dataAddress) = SDRC_Buffer16[words + 1];
      *(dataAddress) = (*(dataAddress) << 16);
      *(dataAddress) |= SDRC_Buffer16[words];
      dataAddress ++;
    }

  } /* end loop over bursts */

  return E_PASS;
}

/**
    \brief  Write to SDRAM using SDRAM buffered access mode

    Here data is transferred from user specified address (dataAddress) to SDRAM buffered access data registers. \n
    The data is then transferred from these data buffers to the user specified SDRAM address by using SDRAM bufferred access mode \n
    Typically, dataAddress should be an IRAM address

    \param  sdramAddress Absolute SDRAM address to where data is to be written
    \param  dataAddress  Source data address
    \param  dataSize     Size of data to be written
    \param  portID       Port ID of the port used for SDRAM Access
    \param  writeMode    Write Mode (Write All or Write Modified)

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

    \see SDRC_PORT

    \note
    - dataSize should be a multiple of 32 bytes
    - sdramAddress must 32 byte aligned
    - When a port is used for SDRAM burst Access, the peripheral for that port cannot access SDRAM

*/
STATUS SDRC_burstWrite(Uint32 *sdramAddress, Uint32 *dataAddress, Uint32 dataSize, SDRC_PORT portID, SDRC_WRITE_MODE writeMode) {
  Uint32 addr;
  Uint32 bursts, words;
  Uint32 burstCount;

  addr = (Uint32)sdramAddress - SDRAM_MEMORY_BASE;

  //Data size has to be a multiple of 32 bytes
  if((dataSize%32) != 0 || (addr % 32) != 0)
    return E_INVALID_INPUT;

  //Address has to be a multiple of 32
  addr = addr / 32;

  burstCount = dataSize >> 5;

  SDRC_RSET( SDBUFAD2, addr );
  SDRC_FSET( SDBUFAD1, SDAH, addr >> 16 );
  SDRC_FSET( SDBUFAD1, AAI, 1);   /* enable address auto-increment */
  SDRC_FSET( SDBUFCTL, PTSEL, portID);

  /*-- Loop over bursts --*/
  for (bursts = 0; bursts < burstCount; bursts++) {

    /*-- Read data from source into Buffer */
    for (words = 0; (words < 16); words = words + 2) {
      SDRC_Buffer16[words] = *(dataAddress);
      SDRC_Buffer16[words+1] = (*(dataAddress) >> 16);
      dataAddress ++;
    }
    /*-- Burst data from buffer to SDRAM --*/
    if(writeMode == SDRC_WRITE_ALL)
      SDRC_FSET(SDBUFCTL,WA,1);
    else
      SDRC_FSET(SDBUFCTL,WM,1);

    while ((SDRC_FGET(SDBUFCTL,WA) | SDRC_FGET(SDBUFCTL,WM))!= 0 );

  } /* end loop over bursts */

  return(E_PASS);
}

⌨️ 快捷键说明

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