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

📄 ixhssacccodeletchan.c

📁 intel IXP400系列cpu(2.3版)的库文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/** * @file IxHssAccCodeletChan.c * * @date 21 May 2002 * * @brief This file contains the channelised implementation of the HSS * Access Codelet. * *  * @par * IXP400 SW Release version 2.3 *  * -- Copyright Notice -- *  * @par * Copyright (c) 2001-2005, Intel Corporation. * All rights reserved. *  * @par * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. Neither the name of the Intel Corporation nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. *  *  * @par * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *  *  * @par * -- End of Copyright Notice -- * @sa IxHssAccCodelet.h * @sa IxHssAccCodeletChan.h *//* * Put the system defined include files required. *//* * Put the user defined include files required. */#include "IxOsal.h"#include "IxHssAcc.h"#include "IxHssAccCodelet.h"#include "IxHssAccCodeletChan.h"#include "IxHssAccCodeletCom.h"#include "IxHssAccCodeletConfig.h"#if defined(__wince) && defined(IX_USE_SERCONSOLE)#include "IxSerConsole.h"#define printf ixSerPrintf#endif/* * #defines and macros used in this file. */#define MESSAGE_Q_SIZE \    (IX_HSSACC_CODELET_CHAN_RX_BUFSIZE_PERCHAN / \     IX_HSSACC_CODELET_CHAN_BYTES_PER_TS_TRIG)#define MEMSET_AND_FLUSH(s, c, n) \do { \    ixOsalMemSet (s, c, n); \    IX_OSAL_CACHE_FLUSH (s, n); \} while (0)/* * Typedefs whose scope is limited to this file. */typedef struct{    unsigned rxOffset;    unsigned txOffset;    unsigned numHssErrs;} CallbackParams;typedef enum{    RxCallback} MessageType;typedef struct{    MessageType type;    CallbackParams params;} Message;typedef struct{    /** are we receiving non-idle data? */    BOOL receivingNonIdleData;    /** channelised TX sample data - source of data for TX */    UINT8 txSampleData;    /** channelised RX sample data - to verify against TX data */    UINT8 rxSampleData;} ChannelInfo;/** channelised RX buffers */typedef UINT8 (*RxBuffers)    [IX_HSSACC_CODELET_CHAN_NUM_CHANS]    [IX_HSSACC_CODELET_CHAN_RX_BUFSIZE_PERCHAN];/** channelised TX buffers */typedef UINT8 (*TxBuffers)    [IX_HSSACC_CODELET_CHAN_NUM_CHANS]    [IX_HSSACC_CODELET_CHAN_TX_LATENCY_FACTOR]    [IX_HSSACC_CODELET_CHAN_BYTES_PER_SAMPLE];/** channelised TX pointer lists */typedef UINT8 *(*TxPointers)    [IX_HSSACC_CODELET_CHAN_TX_LATENCY_FACTOR]    [IX_HSSACC_CODELET_CHAN_NUM_CHANS];typedef struct{    IxHssAccHssPort hssPortId;    IxOsalThread threadId;    IxOsalSemaphore messageSem;    Message messageQ[MESSAGE_Q_SIZE];    unsigned qHead;    unsigned qTail;    /** the last offset we TX'ed from */    int lastTxOffset;    /** the last offset we RX'ed to */    int lastRxOffset;    /** the next offset we will RX to */    int nextRxOffset;    RxBuffers rxBuffers;    TxBuffers txBuffers;    TxPointers txPointers;    /** set if we have a full set of samples Rx'ed */    BOOL readyToLoopback;    /** for recording channelised rx callback parameters */    ChannelInfo channelInfo[IX_HSSACC_CODELET_CHAN_NUM_CHANS];} ClientInfo;/* * Variable declarations global to this file only.  Externs are followed by * static variables. */static ClientInfo clientInfo    [IX_HSSACC_HSS_PORT_MAX];static BOOL verify = TRUE;/* * Extern function prototypes. *//* * Static function prototypes. */PRIVATE voidixHssAccCodeletChannelisedDataSampleCreate (    IxHssAccHssPort hssPortId,    unsigned channelIndex,    UINT8 *sample);PRIVATE voidixHssAccCodeletChannelisedDataSampleTransmit (    IxHssAccHssPort hssPortId,    unsigned channelIndex,    UINT8 *sample);PRIVATE voidixHssAccCodeletChannelisedDataTransmit (    IxHssAccHssPort hssPortId,    unsigned txOffset);PRIVATE voidixHssAccCodeletChannelisedDataSampleVerify (    IxHssAccHssPort hssPortId,    unsigned channelIndex,    UINT8 *sample);PRIVATE voidixHssAccCodeletChannelisedDataSampleReceive (    IxHssAccHssPort hssPortId,    unsigned channelIndex,    UINT8 *sample);PRIVATE voidixHssAccCodeletChannelisedDataReceive (    IxHssAccHssPort hssPortId,    unsigned rxOffset);PRIVATE voidixHssAccCodeletChanRxCallback (    IxHssAccHssPort hssPortId,    unsigned rxOffset,    unsigned txOffset,    unsigned numHssErrs);PRIVATE voidixHssAccCodeletChanRxCallbackProcess (    IxHssAccHssPort hssPortId,    unsigned rxOffset,    unsigned txOffset,    unsigned numHssErrs);PRIVATE IX_STATUSixHssAccCodeletChanThreadMain (    void* arg,    void** ptrRetObj);/** * @fn void ixHssAccCodeletChannelisedDataSampleCreate (           IxHssAccHssPort hssPortId,           unsigned channelIndex,           UINT8 *sample) * * @param IxHssAccHssPort hssPortId (in) - the HSS port ID (0 or 1). * @param unsigned channelIndex (in) - the channel (0-31) to create the * data sample for. * @param UINT8 *sample (out) - a pointer to a data sample of size * CHAN_BYTES_PER_SAMPLE. * * This function creates a data sample for the specified port/channel.  The * sample is filled with an incrementing byte value.  The byte value begins * as the channel number and increases with each invocation: * * <TABLE> * <TR><TD>         <TD>1st Value<TD>2nd Value<TD>3rd Value<TD>...</TR> * <TR><TD>Channel 0<TD>     0x01<TD>     0x02<TD>     0x03<TD>...</TR> * <TR><TD>Channel 1<TD>     0x02<TD>     0x03<TD>     0x04<TD>...</TR> * <TR><TD>Channel 2<TD>     0x03<TD>     0x04<TD>     0x05<TD>...</TR> * <TR><TD>      ...<TD>      ...<TD>      ...<TD>      ...<TD>...</TR> * </TABLE> */PRIVATEvoidixHssAccCodeletChannelisedDataSampleCreate (    IxHssAccHssPort hssPortId,    unsigned channelIndex,    UINT8 *sample){    unsigned byteIndex;    ClientInfo *pClientInfo = &clientInfo[hssPortId];    ChannelInfo *pChannelInfo = &pClientInfo->channelInfo[channelIndex];    /* if the codelet is acting as data source/sink */    if (!ixHssAccCodeletCodeletLoopbackGet ())    {        /* for each byte in the data sample */        for (byteIndex = 0;             byteIndex < IX_HSSACC_CODELET_CHAN_BYTES_PER_SAMPLE;             byteIndex++)        {            /* get/update the value to transmit */            sample[byteIndex] = pChannelInfo->txSampleData++;        }    }    else /* codelet is performing loopback, but nothing to loopback */    {        /* transmit an idle pattern */        /* to allow for caching, we request a cache flush after memset */        MEMSET_AND_FLUSH (            sample, IX_HSSACC_CODELET_CHAN_IDLE_PATTERN,            IX_HSSACC_CODELET_CHAN_BYTES_PER_SAMPLE);    }}/** * @fn void ixHssAccCodeletChannelisedDataSampleTransmit (           IxHssAccHssPort hssPortId,           unsigned channelIndex,           UINT8 *sample) * * @param IxHssAccHssPort hssPortId (in) - the HSS port ID (0 or 1). * @param unsigned channelIndex (in) - the channel (0-31) to transmit the * data sample on. * @param UINT8 *sample (in) - a pointer to a data sample of size * CHAN_BYTES_PER_SAMPLE. * * This function transmits a data sample on the specified port/channel.  It * maintains the current TX offset for each channel and stores the sample * pointer in the appropriate pointer list.  This function also updates TX * statistics. */PRIVATEvoidixHssAccCodeletChannelisedDataSampleTransmit (    IxHssAccHssPort hssPortId,    unsigned channelIndex,    UINT8 *sample){    ClientInfo *pClientInfo = &clientInfo[hssPortId];    UINT8 *temp = NULL;    /* to allow for caching, we request a cache flush before tx */    IX_OSAL_CACHE_FLUSH (        sample, IX_HSSACC_CODELET_CHAN_BYTES_PER_SAMPLE);    /* update the pointer in the pointer list to point to the sample */    /* endianess conversion on txPointers */    temp = (UINT8 *) IX_OSAL_MMU_VIRT_TO_PHYS((UINT32)sample);    (*pClientInfo->txPointers)[pClientInfo->lastTxOffset][channelIndex] =        (UINT8 *) IX_OSAL_SWAP_BE_SHARED_LONG((UINT32) temp);    IX_OSAL_CACHE_FLUSH (	&(*pClientInfo->txPointers)[pClientInfo->lastTxOffset][channelIndex],	sizeof((*pClientInfo->txPointers)[pClientInfo->lastTxOffset][channelIndex]));    /* update TX stats */    stats[hssPortId].chan.txSamples++;    stats[hssPortId].chan.txBytes +=        IX_HSSACC_CODELET_CHAN_BYTES_PER_SAMPLE;}/** * @fn void ixHssAccCodeletChannelisedDataTransmit (           IxHssAccHssPort hssPortId,           unsigned txOffset) * * @param IxHssAccHssPort hssPortId (in) - the HSS port ID (0 or 1). * @param unsigned txOffset (in) - an offset indicating from where within * the txPtrList the NPE is currently transmitting from or will transmit * from next. * * This function examines the txOffset parameter to determine if data needs * to be transmitted to the NPE or not.  If data needs to be transmitted * then data samples are created if necessary and transmitted for each * channel. */PRIVATEvoidixHssAccCodeletChannelisedDataTransmit (    IxHssAccHssPort hssPortId,    unsigned txOffset){    unsigned channelIndex;    UINT8 *txSample;    UINT8 *rxSample;    ClientInfo *pClientInfo = &clientInfo[hssPortId];    /* the NPE tells us where it is currently transmitting from or will */    /* transmit from next.  We want to update the txPtrList once we know */    /* the NPE has completed transmitted it.  We can only be sure that */    /* the NPE has completed transmitted the txPtrList corresponding to */    /* (txOffset - 2), as the NPE may still be transmitting from */    /* (txOffset - 1). */    /* if we last transmitted to 2 slots prior to txOffset then we do */    /* nothing, otherwise we transmit data.  In this way we will keep */    /* updating the tx data as soon as we know the NPE has finished */    /* transmitting it. */    if ((pClientInfo->lastTxOffset + 2) %        (UINT32) IX_HSSACC_CODELET_CHAN_TX_LATENCY_FACTOR == txOffset)    {        return;    }    /* increment our TX offset to remember where we last transmitted to */    pClientInfo->lastTxOffset++;    pClientInfo->lastTxOffset %= IX_HSSACC_CODELET_CHAN_TX_LATENCY_FACTOR;    /* for each channel */    for (channelIndex = 0;          channelIndex < IX_HSSACC_CODELET_CHAN_NUM_CHANS;         channelIndex++)    {        /* get the pointer to the data sample for this offset/channel */        txSample =            (*pClientInfo->txBuffers)                  [channelIndex][pClientInfo->lastTxOffset];        /* codelet will loop back last data samples received */        if (ixHssAccCodeletCodeletLoopbackGet () &&            pClientInfo->readyToLoopback)        {            /* get pointer to the data sample for this offset/channel */            rxSample =                &(*pClientInfo->rxBuffers)                    [channelIndex][pClientInfo->lastRxOffset];            /* loopback rx data to tx data */            /* note: important to copy data here, if we add rx sample */            /* pointer to the tx pointer list then we are relying on the */            /* rx sample not being overwritten before sample is tx'ed */            /* - not safe when rx and tx latencies differ */            ixOsalMemCopy (                txSample, rxSample,                IX_HSSACC_CODELET_CHAN_BYTES_PER_SAMPLE);        }        else  /* we create new data to transmit */        {            /* fill in the data sample */            ixHssAccCodeletChannelisedDataSampleCreate (                hssPortId, channelIndex, txSample);        }        /* transmit the data sample */        ixHssAccCodeletChannelisedDataSampleTransmit (            hssPortId, channelIndex, txSample);    } /* for (channelIndex ... */}/** * @fn void ixHssAccCodeletChannelisedDataSampleVerify (           IxHssAccHssPort hssPortId,           unsigned channelIndex,           UINT8 *sample) * * @param IxHssAccHssPort hssPortId (in) - the HSS port ID (0 or 1). * @param unsigned channelIndex (in) - the channel (0-31) to verify the * data sample for. * @param UINT8 *sample (in) - a pointer to a data sample of size * CHAN_BYTES_PER_SAMPLE. * * This function verifies the contents of a data sample for the specified * port/channel.  On transmit the sample is filled with an incrementing * byte value.  The byte value begins as the channel number and increases * with each invocation: *  * <TABLE> * <TR><TD>         <TD>1st Value<TD>2nd Value<TD>3rd Value<TD>...</TR> * <TR><TD>Channel 0<TD>     0x01<TD>     0x02<TD>     0x03<TD>...</TR> * <TR><TD>Channel 1<TD>     0x02<TD>     0x03<TD>     0x04<TD>...</TR> * <TR><TD>Channel 2<TD>     0x03<TD>     0x04<TD>     0x05<TD>...</TR> * <TR><TD>      ...<TD>      ...<TD>      ...<TD>      ...<TD>...</TR> * </TABLE> */PRIVATEvoidixHssAccCodeletChannelisedDataSampleVerify (    IxHssAccHssPort hssPortId,    unsigned channelIndex,    UINT8 *sample){    unsigned byteIndex;    UINT8 expectedValue;    ClientInfo *pClientInfo = &clientInfo[hssPortId];    ChannelInfo *pChannelInfo = &pClientInfo->channelInfo[channelIndex];    IxHssAccTdmSlotUsage tsUsage =        ixHssAccCodeletChannelisedTimeslotGet (channelIndex);    /* if the timeslot is assigned to 56K voice then bit 7 is unused */    UINT32 mask = (tsUsage == IX_HSSACC_TDMMAP_VOICE56K ? 0x7F : 0xFF);    /* for each byte in the data sample */    for (byteIndex = 0;         byteIndex < IX_HSSACC_CODELET_CHAN_BYTES_PER_SAMPLE;         byteIndex++)    {        /* if we haven't started receiving non-idle data yet */        if (!pChannelInfo->receivingNonIdleData)        {            /* check to see if we're receiving the idle pattern */            if ((sample[byteIndex] & mask) ==                (IX_HSSACC_CODELET_CHAN_IDLE_PATTERN & mask))            {                stats[hssPortId].chan.rxIdles++;                continue;            }            /* not receiving idle pattern, i.e. receiving non-idle data */            pChannelInfo->receivingNonIdleData = TRUE;        }        /* get/update the value we are expecting to receive */        expectedValue = pChannelInfo->rxSampleData++;        /* verify that the data is as expected */        if ((sample[byteIndex] & mask) != (expectedValue & mask))        {            stats[hssPortId].chan.rxVerifyFails++;        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -