📄 zl5011xdma.c
字号:
(Unused in this function)
par Pointer to the structure for configuration items.
Outputs:
None
Returns:
zlStatusE
Remarks:
*******************************************************************************/
zlStatusE zl5011xHostRxInitialiseStructInit(zl5011xParamsS *zl5011xParams, zl5011xHostRxInitialiseS *par)
{
zlStatusE status = ZL5011X_OK;
Uint32T n;
status = ZL5011X_CHECK_POINTERS(zl5011xParams, par);
if (status == ZL5011X_OK)
{
status = ZL5011X_CHECK_RUNNING(zl5011xParams);
}
if (status == ZL5011X_OK)
{
ZL5011X_TRACE(ZL5011X_DMA_FN_ID,
"zl5011xHostRxInitialiseStructInit:", 0, 0, 0, 0, 0, 0);
#ifdef _ZARLINK_ZLE5011X_BOARD
par->dmaChannel = 1; /* ZARLINK evaluation board uses DMA channel 0 for
packet transmission from CPU, and 1 for reception */
#else
par->dmaChannel = 0;
#endif
par->numberOfBuffers = 2;
par->bufferSize = 99200;
for (n=0;n<ZL5011X_CPQ_QUEUES;n++)
{
par->queueNumberOfBuffers[n] = 256;
par->queueBufferSize[n] = ZL5011X_MAXIMUM_PACKET_SIZE;
par->queueGranuleThreshold[n] = ZL5011X_CPQ_DEFAULT_GRAN_THLD;
}
/* Set the total threshold to the sum of granules for each receive queue */
par->totalGranuleThreshold = ZL5011X_CPQ_QUEUES * ZL5011X_CPQ_DEFAULT_GRAN_THLD;
/* disable use of the packet Rx interrupt by default */
par->packetRxInterruptEnable = ZL5011X_FALSE;
}
return status;
}
/*******************************************************************************
Function:
zl5011xHostRxInitialise
Description:
Configures a DMA channel for reception and partially initialises the device
including Qos thresholds. It will then start the zl5011xPktRx for receiving
packets
Inputs:
zl5011xParams Pointer to the structure for this device instance
par Pointer to the structure for configuration items. See below:
Structure inputs:
dmaChannel DMA channel to configure
numberOfBuffers Size of buffer chain
bufferSize Size of data buffer to create for each descriptor
queueNumberOfBuffers[] Size of storage to create for each queue
queueBufferSize[] Maximum size of packet that may be received
queueGranuleThreshold[] Maximum number of granules that cab be used by the
receive queue
totalGranuleThreshold Total number of granules that can be used by all
receive queues
packetRxInterruptEnable set to ZL5011X_TRUE to allow the DMA functionality to
make use of the packet Rx interrupt
Structure outputs:
None
Outputs
None
Returns:
zlStatusE
Remarks:
*******************************************************************************/
zlStatusE zl5011xHostRxInitialise(zl5011xParamsS *zl5011xParams,
zl5011xHostRxInitialiseS *par)
{
zlStatusE status = ZL5011X_OK;
Uint32T n;
status = ZL5011X_CHECK_POINTERS(zl5011xParams, par);
if (status == ZL5011X_OK)
{
status = ZL5011X_CHECK_RUNNING(zl5011xParams);
}
if (status == ZL5011X_OK)
{
if (par->packetRxInterruptEnable == ZL5011X_TRUE)
{
zl5011xBooleanE isrStatus;
/* check that the ISR is running */
status = zl5011xIsrCheckDevice(zl5011xParams, &isrStatus);
if (status == ZL5011X_OK)
{
if (isrStatus == ZL5011X_FALSE)
{
status = ZL5011X_INTERRUPT_NOT_RUNNING;
}
}
}
}
if (status == ZL5011X_OK)
{
ZL5011X_TRACE(ZL5011X_DMA_FN_ID,"zl5011xHostRxInitialise:", 0, 0, 0, 0, 0, 0);
}
/* Check DMA channel is in range for the micro */
ZL5011X_CHECK_PARAMETER_RANGE(par->dmaChannel,0,
zl5011xDmaProps.maxNumberOfChannels,ZL5011X_PARAMETER_INVALID)
/* Now check the number of descriptors is in range for micro */
if (status == ZL5011X_OK)
{
if (par->numberOfBuffers > zl5011xDmaProps.maxDescriptorChainSize)
{
status = ZL5011X_PARAMETER_INVALID;
}
}
/* Check and set the threshold values for QoS control */
for (n=0;n<ZL5011X_CPQ_QUEUES && status == ZL5011X_OK;n++)
{
ZL5011X_CHECK_PARAMETER_RANGE(par->queueGranuleThreshold[n],0,
ZL5011X_MAX_GRANULE_ALLOC,ZL5011X_PARAMETER_INVALID)
}
ZL5011X_CHECK_PARAMETER_RANGE(par->totalGranuleThreshold,0,
ZL5011X_MAX_GRANULE_ALLOC,ZL5011X_PARAMETER_INVALID)
/* Now initialise DMA channel and build chain of descriptors */
if ((status == ZL5011X_OK) && (rxQParams != NULL))
{
status = ZL5011X_DMA_QUEUE_ALREADY_INIT;
}
if (status == ZL5011X_OK)
{
/* Allocate memory for rx structure */
status = zl5011xDmaAllocateStructure(zl5011xParams,ZL5011X_DMA_RECEIVE);
}
if (status == ZL5011X_OK)
{
rxQParams->dmaChannel.numberOfBuffers = par->numberOfBuffers;
rxQParams->dmaChannel.channelNumber = par->dmaChannel;
/* Specify the buffer size as a whole number of words and a whole number
of buffers transfer sizes */
rxQParams->dmaChannel.bufferSize = (((par->bufferSize-1)/
(sizeof(Uint32T)*ZL5011X_WORDS_PER_TRANSFER))+1) *ZL5011X_WORDS_PER_TRANSFER;
rxQParams->dmaChannel.devParams = zl5011xParams;
rxQParams->dmaChannel.dmaDirection = ZL5011X_DMA_RECEIVE;
/* Initialise message queue and parameters */
for (n=0;n<ZL5011X_CPQ_QUEUES;n++)
{
rxQParams->length[n] = par->queueNumberOfBuffers[n];
rxQParams->size[n] = ((par->queueBufferSize[n]-1)/sizeof(Uint32T)) +1;
}
}
if (status == ZL5011X_OK)
{
if (par->packetRxInterruptEnable == ZL5011X_TRUE)
{
status = zl5011xDmaRxInterruptInitialise(zl5011xParams);
rxQParams->useInterrupt = ZL5011X_TRUE;
}
}
if (status == ZL5011X_OK)
{
/* Initialise the DMA channel */
status = zl5011xDmaInitialise(&rxQParams->dmaChannel);
if (status == ZL5011X_OK)
{
/* Put the DMA into a known state */
status = zl5011xDmaIssueCommand(&rxQParams->dmaChannel,
ZL5011X_DMA_STOP_COMMAND);
}
}
/* Initialise the device */
if (status == ZL5011X_OK)
{
for (n=0;n<ZL5011X_CPQ_QUEUES && status == ZL5011X_OK;n++)
{
/* Set the thresholds for each queue */
status = zl5011xCpqConfigureQueue(zl5011xParams,(zl5011xQueueE)n,
par->queueGranuleThreshold[n],
ZL5011X_TRUE /* Enable packet dropping */);
}
}
if (status == ZL5011X_OK)
{
/* Set the total threshold */
status = zl5011xCpqSetGranuleUsage(zl5011xParams,par->totalGranuleThreshold);
}
if (status == ZL5011X_OK)
{
/* Apply the required padding to device */
status = zl5011xCpuDmaSetPadding(zl5011xParams,zl5011xDmaProps.padding);
}
if (status == ZL5011X_OK)
{
/* Program the device into continuous mode */
status = zl5011xCpuDmaSetRxMode(zl5011xParams,ZL5011X_DMA_RX_CONTIN);
}
if (status == ZL5011X_OK)
{
/* Initialise starting sequence Number */
status = zl5011xCpuDmaGetRxSeqNum(rxQParams->dmaChannel.devParams, &rxQParams->lastPktSeqNumber);
}
if (status == ZL5011X_OK)
{
rxQParams->lastPktSeqNumber = (Uint16T)(rxQParams->lastPktSeqNumber-1);
}
if (status == ZL5011X_OK)
{
/* Enable the Rx function */
status = zl5011xCpuDmaSetRxControl(rxQParams->dmaChannel.devParams,
ZL5011X_DMA_ENABLED);
}
/* Start task */
if (status == ZL5011X_OK)
{
rxQParams->goFlag = ZL5011X_TRUE;
if ((rxQParams->pktRxId = OS_TASK_SPAWN("zlDmaPktRx",
ZL5011X_DMA_TASK_PRIORITY,
OS_VX_NO_STACK_FILL,
ZL5011X_DMA_TASK_STACK_SIZE,
(FUNCPTR)zl5011xPktRx,
0,0,0,0,0,0,0,0,0,0)) == (OS_TASK_ID)OS_ERROR)
{
status = ZL5011X_RTOS_TASK_CREATE_FAIL;
}
}
if (status == ZL5011X_OK)
{
zl5011xParams->osExclusion.dmaRxEnabled = ZL5011X_TRUE;
}
return status;
}
/*******************************************************************************
Function:
zl5011xHostRxDisableStructInit
Description:
Sets up the default parameters for zl5011xHostRxDisable
Inputs:
zl5011xParams Pointer to the structure for this device instance.
(Unused in this function)
par Pointer to the structure for configuration items.
(Unused in this function)
Outputs:
None
Returns:
zlStatusE
Remarks:
*******************************************************************************/
zlStatusE zl5011xHostRxDisableStructInit(zl5011xParamsS *zl5011xParams, zl5011xHostRxDisableS *par)
{
zlStatusE status = ZL5011X_OK;
status = ZL5011X_CHECK_POINTERS(zl5011xParams, par);
if (status == ZL5011X_OK)
{
status = ZL5011X_CHECK_RUNNING(zl5011xParams);
}
if (status == ZL5011X_OK)
{
ZL5011X_TRACE(ZL5011X_DMA_FN_ID,"zl5011xHostRxDisableStructInit:",0,0,0,0,0,0);
}
return status;
}
/*******************************************************************************
Function:
zl5011xHostRxDisable
Description:
Send a request to the zl5011xPktRx task to stop receiving packets and disable
the DMA channel
Inputs:
zl5011xParams Pointer to the structure for this device instance.
(Unused in this function)
par Pointer to the structure for configuration items. See below:
(Unused in this function)
Structure inputs:
unused reserved for future use
Structure outputs:
None
Outputs:
None
Returns:
zlStatusE
Remarks:
*******************************************************************************/
zlStatusE zl5011xHostRxDisable(zl5011xParamsS *zl5011xParams, zl5011xHostRxDisableS *par)
{
zlStatusE status = ZL5011X_OK;
status = ZL5011X_CHECK_POINTERS(zl5011xParams, par);
if (status == ZL5011X_OK)
{
status = ZL5011X_CHECK_RUNNING(zl5011xParams);
}
if (status == ZL5011X_OK)
{
ZL5011X_TRACE(ZL5011X_DMA_FN_ID,"zl5011xHostRxDisable:", 0, 0, 0, 0, 0, 0);
ZL5011X_CHECK_FOR_INVALID_VALUE(rxQParams,NULL,ZL5011X_DMA_QUEUE_NOT_INIT)
if (status == ZL5011X_OK)
{
if ((rxQParams->useInterrupt == ZL5011X_TRUE) && (rxQParams->rxPktSemId != OS_SEM_INVALID))
{
/* currently using the packet Rx interrupt. If no packets are being received, then
there may be some interval before the DMA actually completes processing. So,
disable use of the interrupt and then give the semaphore to spark the DMA into
life. */
rxQParams->useInterrupt = ZL5011X_FALSE;
(void)OS_MUTEX_GIVE(rxQParams->rxPktSemId);
}
rxQParams->goFlag = ZL5011X_FALSE;
}
}
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -