📄 xsmsl.c
字号:
* CALLED BY:
* Tests
*
* PROTOTYPE:
* UINT32 XsMslReceivePacket(XsMslContextT *ctxP, UINT32 channel_offset,
* PCHAR bufferP, UINT32 length);
*
*******************************************************************************
*/
UINT32 XsMslReceivePacket(XsMslContextT *ctxP, UINT32 channel_offset,
PCHAR bufferP, UINT32 length)
{
XsMslLLElemTPT current;
PUCHAR buffer8P = (PUCHAR) bufferP;
PUCHAR data8P;
UINT32 status = ERR_S_MSL_NONE;
UINT32 rxCount, i;
DM_FUNC("XsMslReceivePacket");
DM_ENTER(DM_CW_MSL_1);
DM_CwDbgPrintf(DM_CW_MSL_1, "channel_offset: %d", channel_offset);
DM_CwDbgPrintf(DM_CW_MSL_1, "bufferP: %x", bufferP);
DM_CwDbgPrintf(DM_CW_MSL_1, "length: %d", length);
// Check for Valid Channel
if (channel_offset >= XSMSL_CHANNEL_NUM)
{
LOGERRORX(ctxP->loggedError, ERR_L_MSL, ERR_S_MSL_RECEIVE, 17,
ERR_T_BADRANGE, 0, 0, 0);
DM_LEAVE(DM_CW_MSL_1);
return (ctxP->loggedError);
}
if(ctxP->rx_fifoservice[channel_offset] == RXSERVICE_NONE)
{
DM_CwDbgPrintf(DM_CW_MSL_1, "Receive packet polled");
// Read from the receive FIFO.
rxCount = ReadRxFifo(ctxP, channel_offset, bufferP, length);
if (!rxCount)
{
status = ctxP->loggedError;
}
}
else if (ctxP->rx_fifoservice[channel_offset] == RXSERVICE_INT) // INT case
{
DM_CwDbgPrintf(DM_CW_MSL_1, "Receive packet interrupt");
// Point to the first element in the list.
current = ctxP->rx_llfirst[channel_offset];
while ((current != NULL) && (current->length != 0)) // if (XsMslPacketAvail(ctxP, channel_offset))
{
DM_CwDbgPrintf(DM_CW_MSL_1, "Copy packet");
// Get the pointer to the buffer.
data8P = (PUCHAR)¤t->buffer[0];
for (i = 0; i < current->length; i++)
{
// Get the data.
*buffer8P++ = *data8P++;
}
DM_CwDbgPrintf(DM_CW_MSL_1, "Remove element from list");
// remove head of linked list
if(current == ctxP->rx_lllast[channel_offset])
{ // only one list in array
ctxP->rx_llfirst[channel_offset] = NULL;
ctxP->rx_lllast[channel_offset] = NULL;
}
else
{
// Point to the next element.
ctxP->rx_llfirst[channel_offset] = current->next;
}
DM_CwDbgPrintf(DM_CW_MSL_1, "Free buffer and element");
// Free the buffers.
free(current->buffer);
free(current);
// Get the next element.
current = ctxP->rx_llfirst[channel_offset];
}
}
else // DMA case
{
DM_CwDbgPrintf(DM_CW_MSL_1, "Receive packet DMA");
if (ctxP->xferRxComplete[channel_offset])
{
DM_CwDbgPrintf(DM_CW_MSL_1, "Setup descriptor");
// setup Descriptor for copy from Queue to user
ctxP->rx2_firstDescVtP[channel_offset]->commandRegister &=
~DCMD_LEN_MASK;
ctxP->rx2_firstDescVtP[channel_offset]->commandRegister |=
ctxP->rx_length;
ctxP->rx2_firstDescVtP[channel_offset]->sourceVirtualAddr =
ctxP->rx1_firstDescVtP[channel_offset]->targetVirtualAddr;
ctxP->rx2_firstDescVtP[channel_offset]->sourcePhysicalAddr =
ctxP->rx1_firstDescVtP[channel_offset]->targetPhysicalAddr;
ctxP->rx2_firstDescVtP[channel_offset]->targetVirtualAddr =
bufferP;
ctxP->rx2_firstDescVtP[channel_offset]->targetPhysicalAddr =
(UINT32) bufferP;
DM_CwDbgPrintf(DM_CW_MSL_1, "XsDmaLoadFirstDescriptorAddr");
XsDmaLoadFirstDescriptorAddr(ctxP->dma_rx_channel2[channel_offset],
ctxP->rx2_firstDescVtP[channel_offset]);
DM_CwDbgPrintf(DM_CW_MSL_1, "Calling XsDmaStart");
status = XsDmaStart(ctxP->dma_rx_channel2[channel_offset]);
if (status)
{
LOGERRORX(ctxP->loggedError, ERR_L_MSL, ERR_S_MSL_RECEIVE,
19, ERR_T_ILLPARAM, 0, 0, 0);
DM_LEAVE(DM_CW_MSL_1);
return (ctxP->loggedError);
}
DM_CwDbgPrintf(DM_CW_MSL_1, "XsDmaWaitUntilStopped");
// finish dma transfer before returning to user
status = XsDmaWaitUntilStopped(ctxP->dma_rx_channel2[channel_offset]);
if(status)
{
LOGERRORX(ctxP->loggedError, ERR_L_MSL, ERR_S_MSL_RECEIVE,
20, ERR_T_TIMEOUT, 0, 0, 0);
DM_LEAVE(DM_CW_MSL_1);
return (ctxP->loggedError);
}
// Clear the receive flag
ctxP->xferRxComplete[channel_offset] = FALSE;
}
else //data not available yet
{
bufferP[0] = 0; //set to NULL char
LOGERRORX(ctxP->loggedError, ERR_L_MSL, ERR_S_MSL_RECEIVE,
21, ERR_T_FIFO, 0, 0, 0);
DM_LEAVE(DM_CW_MSL_1);
return (ctxP->loggedError);
}
}
DM_LEAVE(DM_CW_MSL_1);
return (status); //successful exit
}
/*
*******************************************************************************
*
* FUNCTION:
* XsMslChannelStatus
*
* DESCRIPTION:
* Retrieves the MSL status register.
*
* INPUT PARAMETERS:
* XsMslContextT ctxP
* UINT32 channel_offset transmit channel [1:XSMSL_CHANNEL_NUM]
*
* RETURNS:
* Status Register of specified channel
*
* GLOBAL EFFECTS:
* None
*
* ASSUMPTIONS:
* channel_offset is correct.
*
* CALLS:
* None
*
* CALLED BY:
* XsMslTransmitPacket, XsMslReceivePacket, XsMslBgReceivePacket
*
* PROTOTYPE:
* UINT32 XsMslChannelStatus(XsMslContextT *ctxP, UINT32 channel_offset);
*
*******************************************************************************
*/
UINT32 XsMslChannelStatus(XsMslContextT *ctxP, UINT32 channel_offset)
{
volatile XsMslRegsT* RegsP = (XsMslRegsT*) ctxP->RegsP;
// DM_FUNC("XsMslChannelStatus");
// DM_ENTER(DM_CW_MSL_1);
// DM_LEAVE(DM_CW_MSL_1);
return RegsP->BBSTAT[channel_offset];
}
/*
*******************************************************************************
*
* FUNCTION:
* XsMslPacketAvail
*
* DESCRIPTION:
* Returns whether a valid data exists in the queue.
*
* INPUT PARAMETERS:
* XsMslContextT ctxP
* UINT32 channel_offset transmit channel [1:XSMSL_CHANNEL_NUM]
*
* RETURNS:
* 1: Valid Packet Exists
* 0: Valid Packet Does Not Exist
*
* GLOBAL EFFECTS:
* None
*
* ASSUMPTIONS:
* channel_offset is correct.
*
* CALLS:
* None
*
* CALLED BY:
* Tests
*
* PROTOTYPE:
* UINT32 XsMslPacketAvail(XsMslContextT *ctxP, UINT32 channel_offset);
*
*******************************************************************************
*/
UINT32 XsMslPacketAvail(XsMslContextT *ctxP, UINT32 channel_offset)
{
XsMslLLElemTPT current;
// DM_FUNC("XsMslPacketAvail");
// DM_ENTER(DM_CW_MSL_1);
// Check for interrupt mode.
if (ctxP->rx_fifoservice[channel_offset] == RXSERVICE_INT) // INT case
{
// Get first element in list.
current = ctxP->rx_llfirst[channel_offset];
// Check the length field to determine if data is ready.
if ((current != NULL) && (current->length != 0))
{
DM_CwDbgPrintf(DM_CW_MSL_1, "Receive packet available");
// DM_LEAVE(DM_CW_MSL_1);
return (1); //data is ready
}
// DM_LEAVE(DM_CW_MSL_1);
return (0); //data is not ready
}
else if (ctxP->rx_fifoservice[channel_offset] == RXSERVICE_DMA) // DMA case
{
if (ctxP->xferRxComplete[channel_offset])
{
DM_CwDbgPrintf(DM_CW_MSL_1, "Receive packet available");
// DM_LEAVE(DM_CW_MSL_1);
return (1); //data is ready
}
// DM_LEAVE(DM_CW_MSL_1);
return (0); //data is not ready
}
else
{
DM_CwDbgPrintf(DM_CW_MSL_1, "Receive channel not configured");
}
// DM_LEAVE(DM_CW_MSL_1);
return (0); //should never happen
}
/*
*******************************************************************************
*
* FUNCTION:
* XsMslChangeConfiguration
*
* DESCRIPTION:
* Changes the channel configuration.
*
* INPUT PARAMETERS:
* XsMslContext* ctxP
* UINT32 channel_offset transmit channel [1:XSMSL_CHANNEL_NUM]
*
* RETURNS:
* SUCCESS: ERR_S_MSL_NONE
* FAILURE: Non-Zero
*
* GLOBAL EFFECTS:
* NONE
*
* ASSUMPTIONS:
* None.
*
* CALLS:
* None.
*
* CALLED BY:
* Tests
*
* PROTOTYPE:
* UINT32 XsMslChangeConfiguration(XsMslContextT *ctxP);
*
*******************************************************************************
*/
UINT32 XsMslChangeConfiguration(XsMslContextT *ctxP, UINT32 channel_offset)
{
DM_FUNC("XsMslChangeConfiguration");
DM_ENTER(DM_CW_MSL_1);
// Reconfigurate the parameters.
SetMslConfiguration(ctxP);
// Reconfigure both transmit and receive channel registers.
WriteMslConfigReg(ctxP, channel_offset);
DM_LEAVE(DM_CW_MSL_1);
return (ERR_S_MSL_NONE);
}
/*
*******************************************************************************
*
* FUNCTION:
* XsMslEnableTxService
*
* DESCRIPTION:
* Enables Interrupt or DMA service for transmit channel channel_offset.
*
* INPUT PARAMETERS:
* XsMslContext* ctxP
* UINT32 channel_offset Transmit channel [1:XSMSL_CHANNEL_NUM]
*
* RETURNS:
* SUCCESS: ERR_S_MSL_NONE
* FAILURE: Non-Zero
*
* GLOBAL EFFECTS:
* NONE
*
* ASSUMPTIONS:
* Trasmit channel channel_offset has been configured properly.
*
* CALLS:
* XsDmaStart
*
* CALLED BY:
* Tests
*
* PROTOTYPE:
* UINT32 XsMslEnableTxService(XsMslContextT *ctxP, UINT32 channel_offset);
*
*******************************************************************************
*/
UINT32 XsMslEnableTxService(XsMslContextT *ctxP, UINT32 channel_offset)
{
UINT32 work_register;
MslCfgT *mslCfgP = ctxP->mslCfgP;
volatile XsMslRegsT* RegsP = (XsMslRegsT*) ctxP->RegsP;
DM_FUNC("XsMslEnableTxService");
DM_ENTER(DM_CW_MSL_1);
DM_CwDbgPrintf(DM_CW_MSL_1, "channel_offset: %d", channel_offset);
//enable interrupt
work_register = RegsP->BBCFG[channel_offset];
work_register &= ~TX_SERVICE_MSK;
work_register &= BBCFG_RESERVED_MSK; // output 0 in reserved register
// Convert the transmit fifo service parameter to the value.
switch (mslCfgP->tx_fifo_service)
{
case FIFO_SERVICE_POLL:
DM_CwDbgPrintf(DM_CW_MSL_1, "TX FIFO_SERVICE_POLL");
ctxP->tx_fifoservice[channel_offset] = TXSERVICE_NONE;
break;
case FIFO_SERVICE_INT:
DM_CwDbgPrintf(DM_CW_MSL_1, "TX FIFO_SERVICE_INT");
ctxP->tx_fifoservice[channel_offset] = TXSERVICE_INT;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -