📄 xsmsl.c
字号:
ctxP->handler_installed = 0;
DM_LEAVE(DM_CW_MSL_1);
}
/*
*******************************************************************************
*
* FUNCTION:
* WriteMslConfigReg
*
* DESCRIPTION:
* Write the channel configuration register.
*
* INPUT PARAMETERS:
* XsMslContext* ctxP
* UINT32 channel_offset transmit channel [1:XSMSL_CHANNEL_NUM]
* XsMslConfigChannelT channelType 1 = Tx channel, 2 = Rx channel, 3 = both
* BOOL setChannel TRUE = set channel, FALSE = clear channel
* BOOL enableTxChannel TRUE = enable tx channel, FALSE = disable
* BOOL enableRxChannel TRUE = enable rx channel, FALSE = disable
*
* RETURNS:
* SUCCESS: ERR_S_MSL_NONE
* FAILURE: Non-Zero
*
* GLOBAL EFFECTS:
* NONE
*
* ASSUMPTIONS:
* None.
*
* CALLS:
* None.
*
* CALLED BY:
* Tests
*
* static
* PROTOTYPE:
* UINT32 WriteMslConfigReg(XsMslContextT *ctxP, UINT32 channel_offset);
*
*******************************************************************************
*/
static
UINT32 WriteMslConfigReg(XsMslContextT *ctxP, UINT32 channel_offset)
{
UINT32 work_register = 0;
volatile XsMslRegsT* RegsP = (XsMslRegsT*) ctxP->RegsP;
DM_FUNC("WriteMslConfigReg");
DM_ENTER(DM_CW_MSL_1);
DM_CwDbgPrintf(DM_CW_MSL_1, "WriteMslConfigReg:");
DM_CwDbgPrintf(DM_CW_MSL_1, "channel_offset: %d", channel_offset);
// Check state of transmit FIFO service.
if (ctxP->tx_fifoservice[channel_offset] == TXSERVICE_NONE)
{
// Enable channel if polled mode.
work_register |= TXENABLE;
}
// Set transmit parameters.
work_register |= ctxP->tx_threshold[channel_offset];
work_register |= ctxP->tx_flowcontrol[channel_offset];
work_register |= ctxP->tx_blocksize[channel_offset];
// Set receive parameters.
work_register |= RXENABLE;
work_register |= ctxP->rx_fifoservice[channel_offset];
work_register |= ctxP->rx_threshold[channel_offset];
work_register |= ctxP->rx_flowcontrol[channel_offset];
DM_CwDbgPrintf(DM_CW_MSL_1, "Writing MSL configuration register at: 0x%08x:0x%08x",
&RegsP->BBCFG[channel_offset], work_register);
// Update configuration channel.
RegsP->BBCFG[channel_offset] = work_register;
DM_CwDbgPrintf(DM_CW_MSL_1, "Reading MSL configuration register at: 0x%08x:0x%08x",
&RegsP->BBCFG[channel_offset], RegsP->BBCFG[channel_offset]);
DM_LEAVE(DM_CW_MSL_1);
return (ERR_S_MSL_NONE);
}
/*
*******************************************************************************
*
* FUNCTION:
* WriteTxFifo
*
* DESCRIPTION:
* Write the data to the transmit FIFO.
*
* 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
* Failure: NonZero: error.
*
* GLOBAL EFFECTS:
* None.
*
* ASSUMPTIONS:
* None.
*
* CALLS:
* DM_DwDbgPrintf, XsMslChannelStatus
*
* CALLED BY:
* XsMslTransmitPacket, XsMslBgInterruptTransmitPacket.
*
* PROTOTYPE:
* static
* UINT32 WriteTxFifo(XsMslContextT *ctxP, UINT32 channel_offset,
* PCHAR bufferP, UINT32 length);
*
*******************************************************************************
*/
static
UINT32 WriteTxFifo(XsMslContextT *ctxP, UINT32 channel_offset,
PCHAR bufferP, UINT32 length)
{
UINT32 start, timebase = ostCtxP->getTimebase_fnp(ostCtxP);
UINT32 timeout = MSL_TIMEOUT_S * timebase;
volatile XsMslRegsT* RegsP = (XsMslRegsT*) ctxP->RegsP;
PCHAR single_out_fifo = (PCHAR) &(RegsP->BBFIFO[channel_offset]);
PUINT32 buffer32P = (PUINT32)bufferP;
PUINT8 buffer8P;
UINT32 wordaccess, byteaccess;
UINT32 status;
UINT32 i;
DM_FUNC("WriteTxFifo");
DM_ENTER(DM_CW_MSL_1);
DM_CwDbgPrintf(DM_CW_MSL_1, "buffer32P: 0x%08x", buffer32P);
// Determine length of transfer.
wordaccess = length>>2;
byteaccess = length%4;
DM_CwDbgPrintf(DM_CW_MSL_1, "wordaccess: %d", wordaccess);
DM_CwDbgPrintf(DM_CW_MSL_1, "byteaccess: %d", byteaccess);
// Prepare for timeout by getting the initial time interval.
start = ostCtxP->getTimer_fnp(ostCtxP);
//Wait for FIFO to empty
do
{
// Get channel status.
status = XsMslChannelStatus(ctxP, channel_offset);
// Check Tx not empty.
if (!(status & TXEMPTY))
{
// TX not empty!
ctxP->tx_not_empty_count[channel_offset]++;
}
// Get the current time interval.
if ((ostCtxP->getDelta_fnp(ostCtxP, start)) > timeout)
{
DM_CwDbgPrintf(DM_CW_MSL_1, "Transmit timeout!");
LOGERRORX(ctxP->loggedError, ERR_L_MSL, ERR_S_MSL_TRANSMIT, 37,
ERR_T_TIMEOUT, 0, 0, 0);
DM_LEAVE(DM_CW_MSL_1);
return (ctxP->loggedError);
}
} while (!(status & TXEMPTY));
// Check for TX not empty.
if (ctxP->tx_not_empty_count[channel_offset])
{
// Display the TXWAIT count.
DM_CwDbgPrintf(DM_CW_MSL_1, "TX not empty count: %d",
ctxP->tx_not_empty_count[channel_offset]);
}
// Send the even number of long words.
for(i=0;i<wordaccess;i++)
{
// Prepare for timeout by getting the initial time interval.
start = ostCtxP->getTimer_fnp(ostCtxP);
// Check TXFULL before attempting to write to the FIFO
do
{
// Get the channel status.
status = XsMslChannelStatus(ctxP, channel_offset);
// Check TXFULL status.
if (status & TXFULL)
{
// TX FIFO is full!
ctxP->tx_full_count[channel_offset]++;
}
// Check TXWAIT state.
if (status & TXWAIT)
{
// In a TXWAIT!
ctxP->tx_wait_count[channel_offset]++;
}
// Get the current time interval.
if ((ostCtxP->getDelta_fnp(ostCtxP, start)) > timeout)
{
DM_CwDbgPrintf(DM_CW_MSL_1, "Transmit timeout!");
// Display the TXFULL count.
DM_CwDbgPrintf(DM_CW_MSL_1, "TXFULL count: %d",
ctxP->tx_full_count[channel_offset]);
// Display the TXWAIT count.
DM_CwDbgPrintf(DM_CW_MSL_1, "TXWAIT count: %d",
ctxP->tx_wait_count[channel_offset]);
LOGERRORX(ctxP->loggedError, ERR_L_MSL, ERR_S_MSL_TRANSMIT, 39,
ERR_T_TIMEOUT, 0, 0, 0);
DM_LEAVE(DM_CW_MSL_1);
return (ctxP->loggedError);
}
} while (status & TXFULL);
// Write to the FIFO
RegsP->BBFIFO[channel_offset] = *buffer32P++;
}
// Get the pointer to the remaining bytes.
buffer8P = (PUINT8)buffer32P;
DM_CwDbgPrintf(DM_CW_MSL_1, "buffer8P: 0x%08x", buffer8P);
// Send the odd number of bytes.
for(i=0; i < byteaccess; i++)
{
// Prepare for timeout by getting the initial time interval.
start = ostCtxP->getTimer_fnp(ostCtxP);
// Check TXFULL before attempting to write to the FIFO
do
{
// Get the channel status.
status = XsMslChannelStatus(ctxP, channel_offset);
// Check TXFULL status.
if (status & TXFULL)
{
// TX FIFO is full!
ctxP->tx_full_count[channel_offset]++;
}
// Check TXWAIT state.
if (status & TXWAIT)
{
// In a TXWAIT!
ctxP->tx_wait_count[channel_offset]++;
}
// Get the current time interval.
if ((ostCtxP->getDelta_fnp(ostCtxP, start)) > timeout)
{
DM_CwDbgPrintf(DM_CW_MSL_1, "Transmit timeout!");
// Display the TXFULL count.
DM_CwDbgPrintf(DM_CW_MSL_1, "TXFULL count: %d",
ctxP->tx_full_count[channel_offset]);
// Display the TXWAIT count.
DM_CwDbgPrintf(DM_CW_MSL_1, "TXWAIT count: %d",
ctxP->tx_wait_count[channel_offset]);
LOGERRORX(ctxP->loggedError, ERR_L_MSL, ERR_S_MSL_TRANSMIT, 41,
ERR_T_TIMEOUT, 0, 0, 0);
DM_LEAVE(DM_CW_MSL_1);
return (ctxP->loggedError);
}
} while (status & TXFULL);
// Write to the FIFO
*single_out_fifo = *buffer8P++;
}
DM_CwDbgPrintf(DM_CW_MSL_1, "buffer8P: 0x%08x", buffer8P);
// Check if the FIFO was full.
if (ctxP->tx_full_count[channel_offset])
{
// Display the TXFULL count.
DM_CwDbgPrintf(DM_CW_MSL_1, "TXFULL count: %d",
ctxP->tx_full_count[channel_offset]);
}
// Check if we had to wait.
if (ctxP->tx_wait_count[channel_offset])
{
// Display the TXWAIT count.
DM_CwDbgPrintf(DM_CW_MSL_1, "TXWAIT count: %d",
ctxP->tx_wait_count[channel_offset]);
}
DM_CwDbgPrintf(DM_CW_MSL_1, "Wrote %d bytes", length);
DM_LEAVE(DM_CW_MSL_1);
return (0);
}
/*
*******************************************************************************
*
* FUNCTION:
* ReadRxFifo
*
* DESCRIPTION:
* Read the data from the receive FIFO.
*
* 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:
* Number of bytes read from the FIFO.
*
* GLOBAL EFFECTS:
* None.
*
* ASSUMPTIONS:
* None.
*
* CALLS:
* getTimebase, XsMslChannelStatus, getDelta, DM_CwDbgPrintf.
*
* CALLED BY:
* XsMslReceivePacket, XsMslBgInterruptReceivePacket.
*
* PROTOTYPE:
* static
* UINT32 ReadRxFifo(XsMslContextT *ctxP, UINT32 channel_offset,
* PCHAR bufferP, UINT32 length)
*
*******************************************************************************
*/
static
UINT32 ReadRxFifo(XsMslContextT *ctxP, UINT32 channel_offset,
PCHAR bufferP, UINT32 length)
{
UINT32 start, timebase = ostCtxP->getTimebase_fnp(ostCtxP);
UINT32 timeout = MSL_TIMEOUT_S * timebase;
volatile XsMslRegsT* RegsP = (XsMslRegsT*) ctxP->RegsP;
PVUCHAR single_in_fifo = (PVUCHAR) &(RegsP->BBFIFO[channel_offset]);
PUINT32 buffer32P = (PUINT32) bufferP;
PUCHAR buffer8P = (PUCHAR) bufferP;
UINT32 byteaccess, wordaccess;
UINT32 fullness;
UINT32 status;
DM_FUNC("ReadRxFifo");
DM_ENTER(DM_CW_MSL_1);
// Prepare for timeout by getting the initial time interval.
start = ostCtxP->getTimer_fnp(ostCtxP);
// read data from receive fifo 1 word at a time
do
{
// Get status.
status = XsMslChannelStatus(ctxP, channel_offset);
// Check for data in the FIFO
if (!(status & RXEMPTY))
{
if(status & RXFULL)
{
// Calculate maximum number of bytes in FIFO.
fullness = FIFO_LEN;
wordaccess = fullness>>2;
byteaccess = 0;
break;
}
else
{
// Calculate number of bytes in FIFO.
fullness = (status & RXFULLNESS_MASK) >> RXFULLNESS_SHIFT;
// Determine the number of word and bytes in FIFO.
wordaccess = fullness>>2;
byteaccess = fullness%4;
break;
}
}
// Get the current time interval.
if ((ostCtxP->getDelta_fnp(ostCtxP, start)) > timeout)
{
DM_CwDbgPrintf(DM_CW_MSL_1, "Receive timeout!");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -