📄 xsmsl.c
字号:
LOGERRORX(ctxP->loggedError, ERR_L_MSL, ERR_S_MSL_RECEIVE, 42,
ERR_T_TIMEOUT, 0, 0, 0);
DM_LEAVE(DM_CW_MSL_1);
return (0);
}
} while (status & RXEMPTY);
DM_CwDbgPrintf(DM_CW_MSL_1, "wordaccess: %d", wordaccess);
DM_CwDbgPrintf(DM_CW_MSL_1, "byteaccess: %d", byteaccess);
DM_CwDbgPrintf(DM_CW_MSL_1, "Read FIFO");
// Drain the number of words in FIFO.
while(wordaccess-- > 0)
{
// Prepare for timeout by getting the initial time interval.
start = ostCtxP->getTimer_fnp(ostCtxP);
// Check RXEMPTY before attempting to write to the FIFO
do
{
// Get the channel status.
status = XsMslChannelStatus(ctxP, channel_offset);
// Check RXEMPTY status.
if (status & RXEMPTY)
{
// RX FIFO is empty!
ctxP->rx_empty_count[channel_offset]++;
}
// Check RXWAIT state.
if (status & RXWAIT)
{
// In a RXWAIT!
ctxP->rx_wait_count[channel_offset]++;
}
// Get the current time interval.
if ((ostCtxP->getDelta_fnp(ostCtxP, start)) > timeout)
{
DM_CwDbgPrintf(DM_CW_MSL_1, "Receive timeout!");
// Display the RXEMPTY count.
DM_CwDbgPrintf(DM_CW_MSL_1, "RXEMPTY count: %d",
ctxP->rx_empty_count[channel_offset]);
// Display the RXWAIT count.
DM_CwDbgPrintf(DM_CW_MSL_1, "RXWAIT count: %d",
ctxP->rx_wait_count[channel_offset]);
LOGERRORX(ctxP->loggedError, ERR_L_MSL, ERR_S_MSL_RECEIVE, 44,
ERR_T_TIMEOUT, 0, 0, 0);
DM_LEAVE(DM_CW_MSL_1);
return (0);
}
} while (status & RXEMPTY);
// Get the data.
*buffer32P++ = RegsP->BBFIFO[channel_offset];
}
// Get the pointer to the remaining bytes.
buffer8P = (PUCHAR)buffer32P;
DM_CwDbgPrintf(DM_CW_MSL_1, "buffer8P: 0x%08x", buffer8P);
// Get the remaining bytes.
while(byteaccess-- > 0)
{
// Prepare for timeout by getting the initial time interval.
start = ostCtxP->getTimer_fnp(ostCtxP);
// Check RXEMPTY before attempting to write to the FIFO
do
{
// Get the channel status.
status = XsMslChannelStatus(ctxP, channel_offset);
// Check RXEMPTY status.
if (status & RXEMPTY)
{
// RX FIFO is empty!
ctxP->rx_empty_count[channel_offset]++;
}
// Check RXWAIT state.
if (status & RXWAIT)
{
// In a RXWAIT!
ctxP->rx_wait_count[channel_offset]++;
}
// Get the current time interval.
if ((ostCtxP->getDelta_fnp(ostCtxP, start)) > timeout)
{
DM_CwDbgPrintf(DM_CW_MSL_1, "Receive timeout!");
// Display the RXEMPTY count.
DM_CwDbgPrintf(DM_CW_MSL_1, "RXEMPTY count: %d",
ctxP->rx_empty_count[channel_offset]);
// Display the RXWAIT count.
DM_CwDbgPrintf(DM_CW_MSL_1, "RXWAIT count: %d",
ctxP->rx_wait_count[channel_offset]);
LOGERRORX(ctxP->loggedError, ERR_L_MSL, ERR_S_MSL_RECEIVE, 46,
ERR_T_TIMEOUT, 0, 0, 0);
DM_LEAVE(DM_CW_MSL_1);
return (0);
}
} while (status & RXEMPTY);
// Get the data.
*buffer8P++ = *single_in_fifo;
}
DM_CwDbgPrintf(DM_CW_MSL_1, "buffer8P: 0x%08x", buffer8P);
// Check if the FIFO was empty.
if (ctxP->rx_empty_count[channel_offset])
{
// Display the RXEMPTY count.
DM_CwDbgPrintf(DM_CW_MSL_1, "RXEMPTY count: %d",
ctxP->rx_empty_count[channel_offset]);
}
// Check if we had to wait.
if (ctxP->rx_wait_count[channel_offset])
{
// Display the RXWAIT count.
DM_CwDbgPrintf(DM_CW_MSL_1, "RXWAIT count: %d",
ctxP->rx_wait_count[channel_offset]);
}
DM_CwDbgPrintf(DM_CW_MSL_1, "Read %d bytes", fullness);
DM_LEAVE(DM_CW_MSL_1);
return (fullness);
}
/*
*******************************************************************************
*
* FUNCTION:
* XsMslTransmitPacket
*
* DESCRIPTION:
* Puts LENGTH worth of data from BUFFERP onto channel channel_offset in Polled
* mode. In DMA and interrupt mode, the data is put into the transmit queue.
* The queue's data transmitted by interrupt or dma handler.
*
* INPUT PARAMETERS:
* XsMslContextT ctxP includes RegsP, XsMslChannelStatusFnP
* UINT32 channel_offset transmit channel [1:XSMSL_CHANNEL_NUM]
* PCHAR bufferP pointer to transmit data
* UINT32 length length of data to send (in bytes)
*
* RETURNS:
* Success: 0 (ERR_S_MSL_NONE)
* Failure: NonZero: Timeout- data did not send successfully.
*
* GLOBAL EFFECTS:
* None
*
* ASSUMPTIONS:
* Channel channel_offset has been properly setup to transmit.
* In POLLED mode, length <= FIFO_LEN.
*
* CALLS:
* XsMslChannelStatus, malloc, strncpy, XsDmaWaitUntilStopped
* XsDmaLoadFirstDescriptorAddr
*
* CALLED BY:
* Tests
*
* PROTOTYPE:
* UINT32 XsMslTransmitPacket(XsMslContextT *ctxP, UINT32 channel_offset,
* PCHAR bufferP, UINT32 length);
*
*******************************************************************************
*/
UINT32 XsMslTransmitPacket(XsMslContextT *ctxP, UINT32 channel_offset,
PCHAR bufferP, UINT32 length)
{
volatile XsMslRegsT* RegsP = (XsMslRegsT*) ctxP->RegsP;
XsMslLLElemTPT current;
UINT32 status;
UINT32 i;
DM_FUNC("XsMslTransmitPacket");
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)
{
DM_CwDbgPrintf(DM_CW_MSL_1, "Bad channel number");
LOGERRORX(ctxP->loggedError, ERR_L_MSL, ERR_S_MSL_TRANSMIT,
11, ERR_T_BADRANGE, 0, 0, 0);
DM_LEAVE(DM_CW_MSL_1);
return (ctxP->loggedError);
}
DM_CwDbgPrintf(DM_CW_MSL_1, "tx_fifoservice: %x",
ctxP->tx_fifoservice[channel_offset]);
if (ctxP->tx_fifoservice[channel_offset] == TXSERVICE_NONE)
{
DM_CwDbgPrintf(DM_CW_MSL_1, "Transmit packet polled");
// Write to the transmit FIFO.
status = WriteTxFifo(ctxP, channel_offset, bufferP, length);
if (status)
{
LOGERRORX(ctxP->loggedError, ERR_L_MSL, ERR_S_MSL_TRANSMIT,
47, ERR_T_NO_MEM_AVAIL, 0, 0, 0);
current->next = NULL;
DM_LEAVE(DM_CW_MSL_1);
return (ctxP->loggedError);
}
// Write anything to BBEOM to signify EOM
RegsP->BBEOM[channel_offset] = 0x0;
}
else if (ctxP->tx_fifoservice[channel_offset] == TXSERVICE_INT)// INT case
{
DM_CwDbgPrintf(DM_CW_MSL_1, "Transmit packet interrupt");
if (ctxP->tx_llfirst[channel_offset] != NULL)
{
DM_CwDbgPrintf(DM_CW_MSL_1, "Create transmit chain");
// create a LL Elem at then end of the list
current = ctxP->tx_lllast[channel_offset];
if ((current->next = (XsMslLLElemTPT) malloc(sizeof(XsMslLLElemT))) == NULL)
{ //FATAL ERROR - unable to setup buffer
LOGERRORX(ctxP->loggedError, ERR_L_MSL, ERR_S_MSL_TRANSMIT,
12, ERR_T_NO_MEM_AVAIL, 0, 0, 0);
current->next = NULL;
DM_LEAVE(DM_CW_MSL_1);
return (ctxP->loggedError);
}
current = current->next;
current->length = length;
current->position = 0;
current->next = NULL;
DM_CwDbgPrintf(DM_CW_MSL_1, "Create transmit buffer");
if ((current->buffer = (PCHAR) malloc((length+1)*sizeof(CHAR))) == NULL)
{ //FATAL ERROR - unable to setup buffer
LOGERRORX(ctxP->loggedError, ERR_L_MSL, ERR_S_MSL_TRANSMIT,
13, ERR_T_NO_MEM_AVAIL, 0, 0, 0);
free(current);
ctxP->tx_lllast[channel_offset] = NULL;
DM_LEAVE(DM_CW_MSL_1);
return (ctxP->loggedError);
}
}
else
{
DM_CwDbgPrintf(DM_CW_MSL_1, "Create first element of list");
// list is empty, create first LL Elem
if ((current = (XsMslLLElemTPT) malloc(sizeof(XsMslLLElemT))) == NULL)
{ //FATAL ERROR - unable to setup buffer
LOGERRORX(ctxP->loggedError, ERR_L_MSL, ERR_S_MSL_TRANSMIT,
14, ERR_T_NO_MEM_AVAIL, 0, 0, 0);
DM_LEAVE(DM_CW_MSL_1);
return (ctxP->loggedError);
}
current->length = length;
current->position = 0;
current->next = NULL;
DM_CwDbgPrintf(DM_CW_MSL_1, "Create transmit buffer");
if ((current->buffer = (PCHAR) malloc((length+1)*sizeof(CHAR))) == NULL)
{ //FATAL ERROR - unable to setup buffer
LOGERRORX(ctxP->loggedError, ERR_L_MSL, ERR_S_MSL_TRANSMIT,
15, ERR_T_NO_MEM_AVAIL, 0, 0, 0);
free(current);
DM_LEAVE(DM_CW_MSL_1);
return (ctxP->loggedError);
}
ctxP->tx_llfirst[channel_offset] = current;
ctxP->tx_lllast[channel_offset] = current;
}
DM_CwDbgPrintf(DM_CW_MSL_1, "Copy transmit buffer");
// copy data to last elem in LL
for(i = 0; i < length; ++i)
current->buffer[i] = bufferP[i];
DM_CwDbgPrintf(DM_CW_MSL_1, "Calling XsMslEnableTxService");
if ((RegsP->BBCFG[channel_offset] & TX_SERVICE_MSK) != TXSERVICE_INT)
XsMslEnableTxService(ctxP, channel_offset);
}
else // DMA case
{
DM_CwDbgPrintf(DM_CW_MSL_1, "Transmit packet DMA");
// Setup the memory to memory transfer to copy the user's buffer
// to the transmit descriptor. Replace the source descriptor buffer
// with the user's buffer.
ctxP->tx1_firstDescVtP[channel_offset]->sourceVirtualAddr = bufferP;
ctxP->tx1_firstDescVtP[channel_offset]->sourcePhysicalAddr = (UINT32) bufferP;
// Now replace the target descriptor buffer with the transmit descriptor.
ctxP->tx1_firstDescVtP[channel_offset]->targetVirtualAddr =
ctxP->tx2_firstDescVtP[channel_offset]->sourceVirtualAddr;
ctxP->tx1_firstDescVtP[channel_offset]->targetPhysicalAddr =
ctxP->tx2_firstDescVtP[channel_offset]->sourcePhysicalAddr;
ctxP->tx_interrupt_channel = 1U << channel_offset;
DM_CwDbgPrintf(DM_CW_MSL_1, "XsDmaLoadFirstDescriptorAddr");
// Reload the updated memory to memory descriptor.
XsDmaLoadFirstDescriptorAddr(ctxP->dma_tx_channel1[channel_offset],
ctxP->tx1_firstDescVtP[channel_offset]);
DM_CwDbgPrintf(DM_CW_MSL_1, "Calling XsDmaStart");
// Start the DMA channel to copy the user's data.
status = XsDmaStart(ctxP->dma_tx_channel1[channel_offset]);
if (status != ERR_NONE)
{
LOGERRORX(ctxP->loggedError, ERR_L_MSL, ERR_S_MSL_TRANSMIT,
16, ERR_T_ILLPARAM, 0, 0, 0);
DM_LEAVE(DM_CW_MSL_1);
return (ctxP->loggedError);
}
// Need to finish dma transfer before transmitting the data.
status = XsDmaWaitUntilStopped(ctxP->dma_tx_channel1[channel_offset]);
if(status)
{
LOGERRORX(ctxP->loggedError, ERR_L_MSL, ERR_S_MSL_RECEIVE,
41, ERR_T_TIMEOUT, 0, 0, 0);
DM_LEAVE(DM_CW_MSL_1);
return (ctxP->loggedError);
}
// Enable the MSL channel to send the packet.
DM_CwDbgPrintf(DM_CW_MSL_1, "Calling XsMslEnableTxService");
XsMslEnableTxService(ctxP, channel_offset);
// Wait for the transmit callback to complete.
while (!ctxP->xferTxComplete[channel_offset])
{
DM_WaitUs(4);
}
// Clear the complete flag.
ctxP->xferTxComplete[channel_offset] = FALSE;
}
DM_LEAVE(DM_CW_MSL_1);
return (ERR_S_MSL_NONE);
}
/*
*******************************************************************************
*
* FUNCTION:
* XsMslReceivePacket
*
* DESCRIPTION:
* Gets LENGTH worth of data from channel channel_offset and returns in BUFFERP.
* IN DMA/INT case, if intermediate buffer does not have LENGTH bytes,
* function will return a NULL char and error message.
*
* INPUT PARAMETERS:
* XsMslContextT ctxP
* UINT32 channel_offset receive channel [1:XSMSL_CHANNEL_NUM]
* PCHAR bufferP pointer to buffer
* UINT32 length length of data expected (in bytes)
*
* RETURNS:
* Success: 0 (ERR__S_MSL_NONE)
* Failure: NonZero
* BUFFERP set to NULL.
*
* GLOBAL EFFECTS:
* None
*
* ASSUMPTIONS:
* Channel channel_offset has been properly setup to receive.
* Limit of data transfered in Polled Mode is 1 FIFO_LEN
*
* CALLS:
* XsMslChannelStatus, XsDmaLoadFirstDescriptorAddr, strncpy, free,
* XsDmaWaitUntilStopped
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -