?? zl5011xdmampc8260.c
字號:
ZL5011X_FALSE,
{NULL,NULL}
};
#else
static zl5011xIdmaMonitorS IdmaMonitor =
{
{ZL5011X_FALSE,ZL5011X_FALSE,ZL5011X_FALSE,ZL5011X_FALSE},
OS_ERROR,
ZL5011X_FALSE,
{NULL,NULL,NULL,NULL}
};
#endif
/***************** EXPORTED FUNCTION DEFINTIONS ***************************/
/*******************************************************************************
Function:
zl5011xDmaDetermineStatus
Description:
This function will determine the status of the DMA channel
Inputs:
dmaChannel DMA channel that requires checking
Outputs:
None
Returns:
zl5011xDmaStatusE Any of: ZL5011X_DMA_STOPPED (DMA has responded to stop
command),
ZL5011X_DMA_OUT_OF_BUFFERS (DMA has no valid
buffers to process),
ZL5011X_DMA_EXTERNAL_ABORT (DMA received an
external abort command,
ZL5011X_DMA_BUFFER_DONE, (DMA processed a buffer
with interrupt (I) bit set)
ZL5011X_DMA_ACTIVE (DMA still active)
Remarks:
*******************************************************************************/
extern zl5011xDmaStatusE zl5011xDmaDetermineStatus(zl5011xDmaChannelS *dmaChannel)
{
zl5011xDmaStatusE dmaStatus;
zl5011xDmaStructS *dma = (zl5011xDmaStructS *)dmaChannel->dma;
Uint32T regValue;
//ZL5011X_TRACE(ZL5011X_DMA_FN_ID,"zl5011xDmaDetermineStatus:", 0, 0, 0, 0, 0, 0);
/* Read idsr status register to determine status */
regValue = dma->reg->idsr;
/* Process register to determine status */
if ((regValue & PPC8260_IDMA_IDSR_SC) != 0)
{
dmaStatus = ZL5011X_DMA_STOPPED;
}
else
{
if ((regValue & PPC8260_IDMA_IDSR_OB) != 0)
{
dmaStatus = ZL5011X_DMA_OUT_OF_BUFFERS;
}
else
{
if ((regValue & PPC8260_IDMA_IDSR_EDN) != 0)
{
dmaStatus = ZL5011X_DMA_EXTERNAL_ABORT;
}
else
{
if ((regValue & PPC8260_IDMA_IDSR_BC) != 0)
{
dmaStatus = ZL5011X_DMA_BUFFER_DONE;
}
else
{
/* Assume that DMA is active because no other bits are set! */
dmaStatus = ZL5011X_DMA_ACTIVE;
}
}
}
}
return dmaStatus;
}
/*******************************************************************************
Function:
zl5011xDmaIssueCommand
Description:
This function will gain access to the Communication Processor Module (CPM),
and issue the appropriate IDMA command (start or stop)
Inputs:
dmaChannel DMA channel to issue command to
dmaCommand Any of: ZL5011X_DMA_START_COMMAND,
ZL5011X_DMA_STOP_COMMAND
Outputs:
None
Returns:
zlStatusE
Remarks:
*******************************************************************************/
extern zlStatusE zl5011xDmaIssueCommand(zl5011xDmaChannelS *dmaChannel,
zl5011xDmaCommandE dmaCommand)
{
zlStatusE status = ZL5011X_OK;
zl5011xDmaStructS *dma = (zl5011xDmaStructS *)dmaChannel->dma;
Uint32T timeout;
volatile Uint32T *cpmRegister =
(Uint32T *)(dmaChannel->imm + PPC8260_IMM_CPM_CPCR);
if (status == ZL5011X_OK)
{
ZL5011X_TRACE(ZL5011X_DMA_FN_ID,"zl5011xDmaIssueCommand:", 0, 0, 0, 0, 0, 0);
/* Wait for CPM to become free for new command */
for(timeout=0;timeout<ZL5011X_CPM_MODULE_TIMEOUT;timeout++)
{
if ((*cpmRegister & PPC8260_CPM_BUSY) == 0)
{
break;
}
OS_TICK_DELAY(1); /* Wait 1 processor tick before checking again */
}
if (timeout == ZL5011X_CPM_MODULE_TIMEOUT)
{
status = ZL5011X_DMA_QUEUE_FAIL;
}
/* issue IDMA command */
if (status == ZL5011X_OK)
{
/* Clear IDSR register */
dma->reg->idsr = PPC8260_IDMA_IDSR_BC
| PPC8260_IDMA_IDSR_EDN
| PPC8260_IDMA_IDSR_OB
| PPC8260_IDMA_IDSR_SC;
if (dmaCommand == ZL5011X_DMA_START_COMMAND)
{
dma->params->istate = 0; /* Clear before every start command */
zl5011xConnectDreq(dmaChannel);
/* Formulate CPM start command for DMA channel */
*cpmRegister = PPC8260_CPM_IDMA_START
+(PPC8260_CPM_COMMAND_INC*dmaChannel->channelNumber);
}
else
{
zl5011xDisconnectDreq(dmaChannel);
/* Formulate CPM stop command for DMA channel */
*cpmRegister = PPC8260_CPM_IDMA_STOP
+(PPC8260_CPM_COMMAND_INC*dmaChannel->channelNumber);
/* Wait for DMA to stop */
for(timeout=0;timeout<ZL5011X_IDMA_STOP_TIMEOUT;timeout++)
{
if ((dma->reg->idsr & PPC8260_IDMA_IDSR_SC) != 0)
{
break;
}
}
if (timeout == ZL5011X_IDMA_STOP_TIMEOUT)
{
status = ZL5011X_DMA_QUEUE_FAIL;
}
}
}
}
return status;
}
/*******************************************************************************
Function:
zl5011xDmaInitialise
Description:
Initialises the the IDMA channel and creates the chain of descriptor buffers
Inputs:
dmaChannel DMA channel to initialise
Outputs
None
Returns:
zlStatusE
Remarks:
Note: This function also sets the device to use active
high signalling for its DREQ signal and active low
signalling for its DACK signal.
*******************************************************************************/
extern zlStatusE zl5011xDmaInitialise(zl5011xDmaChannelS *dmaChannel)
{
zlStatusE status = ZL5011X_OK;
zl5011xDmaStructS *dma;
Uint32T n;
Uint16T *dmaChannelBaseAddress;
/* Allocate IDMA parameter (dual port) RAM */
if (status == ZL5011X_OK)
{
ZL5011X_TRACE(ZL5011X_DMA_FN_ID,"zl5011xDmaInitialise:", 0, 0, 0, 0, 0, 0);
/* Determine which of the global structures to access */
if (dmaChannel->dmaDirection == ZL5011X_DMA_TRANSMIT)
{
dma = &TxRamPtrs;
}
else
{
dma = &RxRamPtrs;
}
dmaChannel->dma = dma;
/* Get imm base address */
dmaChannel->imm = OS_IMMR_GET();
/* Allocate memory for the DMA channel parameters */
dma->params = (zl5011xDmaParametersS*)sys82xxDpramAlignedMalloc
(sizeof(zl5011xDmaParametersS),ZL5011X_DPRAM_BASE_ADDRESS);
/* Allocate memory for the buffer descriptors and store the lowest 16
bits */
dma->bufferDescrip =
(zl5011xDmaBufferDescripS *)sys82xxDpramAlignedMalloc
(sizeof(zl5011xDmaBufferDescripS)*dmaChannel->numberOfBuffers,
ZL5011X_DB_BASE_ADDRESS);
if ((dma->params == NULL) || (dma->bufferDescrip == NULL))
{
status = ZL5011X_RTOS_MEMORY_FAIL;
}
dma->params->ibase =
(Uint16T)((Uint32T)dma->bufferDescrip & 0xFFFF);
dma->params->ibdptr = dma->params->ibase;
}
if (status == ZL5011X_OK)
{
/* Set up the registers for DMA the channel */
dma->reg = (zl5011xDmaRegistersS *)
(dmaChannel->imm +PPC8260_IMM_IDSR
+(PPC8260_IMM_IDSR_INC*dmaChannel->channelNumber));
/* Disable all interrupts from reaching the core */
dma->reg->idmr = 0;
/* Store the base address for the DMA in the appropriate place in the
parameter RAM. Note only the lowest 16 bits are stored */
dmaChannelBaseAddress = (Uint16T *)(dmaChannel->imm +PPC8260_IMM_IDMA_BASE
+(PPC8260_IMM_IDMA_BASE_INC*dmaChannel->channelNumber));
*dmaChannelBaseAddress = (Uint16T)(((Uint32T)dma->params) & 0xFFFF);
/* Setup parameter RAM transfer buffer size */
dma->params->dcm = (ZL5011X_DMA_WRAP << ZL5011X_DMA_WRAP_BIT_SHIFT);
/* Device present - can do a real transfer */
if (dmaChannel->dmaDirection == ZL5011X_DMA_TRANSMIT)
{
dma->params->dcm = dma->params->dcm
| PPC8260_IDMA_SD_MEM_PER
| PPC8260_IDMA_SINC
| PPC8260_IDMA_ERM
| PPC8260_IDMA_DT;
dma->params->ss_max = (Uint16T)zl5011xDmaProps.alignmentSize;
dma->params->dts = (Uint16T)ZL5011X_PER_PORT_TRANSFER_SIZE;
dma->params->sts = (Uint16T)zl5011xDmaProps.alignmentSize;
}
else
{
dma->params->dcm = dma->params->dcm
| PPC8260_IDMA_SD_PER_MEM
| PPC8260_IDMA_DINC
| PPC8260_IDMA_ERM
| PPC8260_IDMA_DT;
dma->params->ss_max = (Uint16T)zl5011xDmaProps.alignmentSize;
dma->params->dts = (Uint16T)zl5011xDmaProps.alignmentSize;
dma->params->sts = (Uint16T)ZL5011X_PER_PORT_TRANSFER_SIZE;
}
/* Allocate memory in the parameter RAM for the transfer buffer, and store
the lowest 16 bits of this address */
dma->params->dpr_buf =
(Uint16T)(0xFFFF & ((Uint32T)sys82xxDpramAlignedMalloc
(zl5011xDmaProps.transferBufferSize,zl5011xDmaProps.transferBufferSize)));
/* Setup buffer descriptors. First allocate the memory to store all the
memory pointers */
dmaChannel->buffer = (Uint8T **)OS_MALLOC(
dmaChannel->numberOfBuffers*sizeof(Uint8T *));
if (dmaChannel->buffer == NULL)
{
status = ZL5011X_RTOS_MEMORY_FAIL;
}
else
{
dmaChannel->bufferIndex = 0;
for(n=0;n<dmaChannel->numberOfBuffers && status == ZL5011X_OK;n++)
{
/* Allocate a block of non-cached memory, which is aligned to the
transfer buffer size */
dmaChannel->buffer[n] = (Uint8T *)OS_CACHE_DMA_MALLOC(
(dmaChannel->bufferSize*sizeof(Uint32T))
+zl5011xDmaProps.alignmentSize);
if (dmaChannel->buffer[n] == NULL)
{
status = ZL5011X_RTOS_MEMORY_FAIL;
}
else
{
if (dmaChannel->dmaDirection == ZL5011X_DMA_TRANSMIT)
{
dma->bufferDescrip[n].source =
ZL5011X_DMA_BUFFER_BURST_ALIGNED(dmaChannel->buffer[n]);
dma->bufferDescrip[n].destination =
dmaChannel->devParams->baseAdd + ZL5011X_CPU_PACKET_TX;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -