⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xsmsl.c

📁 优龙YLP270开发板 光盘自带的BIOS和实验例程源码 强烈推荐
💻 C
📖 第 1 页 / 共 5 页
字号:
* 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)&current->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 + -