📄 emif270.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 + -