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

📄 loopback_main-multicast.c

📁 ti的TMS320C64XEMAC应用源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ***********************************************************
* THIS PROGRAM IS PROVIDED "AS IS". TI MAKES NO WARRANTIES OR
* REPRESENTATIONS, EITHER EXPRESS, IMPLIED OR STATUTORY,
* INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR
* COMPLETENESS OF RESPONSES, RESULTS AND LACK OF NEGLIGENCE.
* TI DISCLAIMS ANY WARRANTY OF TITLE, QUIET ENJOYMENT, QUIET
* POSSESSION, AND NON-INFRINGEMENT OF ANY THIRD PARTY
* INTELLECTUAL PROPERTY RIGHTS WITH REGARD TO THE PROGRAM OR
* YOUR USE OF THE PROGRAM.
*
* IN NO EVENT SHALL TI BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* CONSEQUENTIAL OR INDIRECT DAMAGES, HOWEVER CAUSED, ON ANY
* THEORY OF LIABILITY AND WHETHER OR NOT TI HAS BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGES, ARISING IN ANY WAY OUT
* OF THIS AGREEMENT, THE PROGRAM, OR YOUR USE OF THE PROGRAM.
* EXCLUDED DAMAGES INCLUDE, BUT ARE NOT LIMITED TO, COST OF
* REMOVAL OR REINSTALLATION, COMPUTER TIME, LABOR COSTS, LOSS
* OF GOODWILL, LOSS OF PROFITS, LOSS OF SAVINGS, OR LOSS OF
* USE OR INTERRUPTION OF BUSINESS. IN NO EVENT WILL TI'S
* AGGREGATE LIABILITY UNDER THIS AGREEMENT OR ARISING OUT OF
* YOUR USE OF THE PROGRAM EXCEED FIVE HUNDRED DOLLARS
* (U.S.$500).
*
* Unless otherwise stated, the Program written and copyrighted
* by Texas Instruments is distributed as "freeware".  You may,
* only under TI's copyright in the Program, use and modify the
* Program without any charge or restriction.  You may
* distribute to third parties, provided that you transfer a
* copy of this license to the third party and the third party
* agrees to these terms by its first use of the Program. You
* must reproduce the copyright notice and any other legend of
* ownership on each copy or partial copy, of the Program.
*
* You acknowledge and agree that the Program contains
* copyrighted material, trade secrets and other TI proprietary
* information and is protected by copyright laws,
* international copyright treaties, and trade secret laws, as
* well as other intellectual property laws.  To protect TI's
* rights in the Program, you agree not to decompile, reverse
* engineer, disassemble or otherwise translate any object code
* versions of the Program to a human-readable form.  You agree
* that in no event will you alter, remove or destroy any
* copyright notice included in the Program.  TI reserves all
* rights not specifically granted under this license. Except
* as specifically provided herein, nothing in this agreement
* shall be construed as conferring by implication, estoppel,
* or otherwise, upon you, any license or other right under any
* TI patents, copyrights or trade secrets.
*
* You may not use the Program in non-TI devices.
* ********************************************************* */


//--------------------------------------------------------------------------
// EMAC Demo Software
//--------------------------------------------------------------------------
// loopback_main-multicast.c
//
// This is a simple loop test. In order for this test to pass out of
// loopback mode, a loopback connector must be inserted into the RJ-45.
// When PHY loopback is used, the loopback connector is not required.
//
//--------------------------------------------------------------------------
#include <stdio.h>
#include <std.h>
#include <log.h>
#include <c6455_emac.h>
#include <c6455_mdio.h>

/*
// NOTE: This test requires a loopback connector if both
//       loopback modes are set to zero.
//
// LOCAL_LOOPBACK performs loopback in the MAC, however
// since this test also checks for a LINK on the physical
// PHY, a network connection is required for this mode.
//
// PHY_LOOPBACK puts the PHY in loopback mode. Most of the
// PHY devices tested report "link" in PHY loopback mode
// (whether a cable is plugged in or not), however some
// older PHY devices still require a network connect to
// report "link".
//
// When neither loopback mode is enabled, a loopback cable
// must be plugged into the RJ-45 for the test to pass.
*/

#define LOCAL_LOOPBACK  0		// Loopback internal to the EMAC
#define PHY_LOOPBACK    0		// Loopback at the PHY device

/*
// We'll use INT5 for the EMAC - this is an arbitrary choice
*/
#define EMAC_INT_VAL    5
#define EMAC_INT_FLAG   (1<<EMAC_INT_VAL)

#define MAXPACKETSIZE   1514
#define BUFFSIZE        ((MAXPACKETSIZE+127)&~0x7F)
/*
// Raw Data Buffers
//
// This test uses internal memory, so we could just use 1518 as our
// buffer size. However, if the buffers were in cacheable external
// memory, we'd have to make sure each was cache aligned, and
// thus use a size of at least 1536 because a buffer must fill an
// the entire cache line.
*/
#define PKT_MAX 32
#pragma DATA_SECTION(packet_header, "L2_DATA");
EMAC_Pkt packet_header[PKT_MAX];
#pragma DATA_SECTION(packet_buffer, "L2_DATA");
Uint8 packet_buffer[PKT_MAX][BUFFSIZE];
#pragma DATA_SECTION(packet_sourcedata, "L2_DATA");
Uint8 packet_sourcedata[BUFFSIZE];

Uint8 dstaddr[4][6] = { { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 },		/* multicast */
                        { 0x01, 0x00, 0x00, 0x00, 0x00, 0x01 },		/* multicast not in set */
                        { 0x25, 0x11, 0x33, 0x77, 0xff, 0x00 },		/* multicast */
                        { 0x25, 0x11, 0x33, 0x77, 0xff, 0x80 } };	/* multicast not in set */

Uint8 mcastlist[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
                      0x25, 0x11, 0x33, 0x77, 0xff, 0x00 };

/*
// ================================================================
//
// Packet Queue
//
// This simple queue object is just for our example packet
// queue. It is not requried for using EMAC/MDIO
//
*/
typedef struct _pktq {
  uint              Count;      /* Number of packets in queue */
  EMAC_Pkt          *pHead;     /* Pointer to first packet    */
  EMAC_Pkt          *pTail;     /* Pointer to last packet     */
} PKTQ;

/*
// Queue Helper Functions
*/
static EMAC_Pkt *pqPop( PKTQ *pq );
static void pqPush( PKTQ *pq, EMAC_Pkt *pPktHdr );

/*
// Declare our packet queues
*/
PKTQ     FreeQueue;             /* Free packets for RX or TX */
PKTQ     RxQueue;               /* Received packets */

/*
// ================================================================
*/

/*
// Declare some local status variables
*/
Handle          hEMAC = 0;       /* Handle to our EMAC instance */
volatile uint   LinkStatus = 0;  /* Our current link status */
volatile uint   LocalTicks = 0;  /* Current time in 100ms ticks */

/*
// Non-Reentrancy
//
// We are not allowed to re-enter EMAC functions. We protect
// against other tasks via SWI_disable/SWI_enable(), and from the EMAC
// HW interrupt by masking it.
//
// Different software environments may have different methods
// for reentrance protection.
//
// We combine the semaphore and the INT masking to make two
// macros OUREMAC_enter() and OUREMAC_exit().
//
*/
static	int             intmask   = 0;   /* Saved interrupt status */
#define OUREMAC_enter() SWI_disable(); intmask = C64_disableIER( EMAC_INT_FLAG )
#define OUREMAC_exit()  C64_enableIER( intmask ); SWI_enable();

//External references
extern LOG_Obj logTrace;

/*
// Declare some local functions
*/
static EMAC_Pkt *GetPacket(Handle hApplication);
static void     FreePacket(Handle hApplication, EMAC_Pkt *pPKT);
static EMAC_Pkt *RxPacket( Handle hApplication, EMAC_Pkt *pPKT);
static void     StatusUpdate(Handle hApplication);
static void     StatisticsUpdate(Handle hApplication);
static int      verify_packet( EMAC_Pkt *pPkt, uint size );
Uint32 interface;

static EMAC_Status status;
static char *LinkStr[] = {	"No Link",
							"10Mb/s Half Duplex",
							"10Mb/s Full Duplex",
							"100Mb/s Half Duplex",
							"100Mb/s Full Duplex",
							"1000Mb/s Full Duplex" };

//---------------------------------------------------------------------
// Main Entry Point
//---------------------------------------------------------------------
int main()
{
}

//---------------------------------------------------------------------
// Main Test Entry Point
//---------------------------------------------------------------------
int TestMain()
{
    EMAC_Config ecfg;
    Uint32      i,size;
    Uint32      TxCount=0, RxCount=0, TestCount=(MAXPACKETSIZE-60)+1;
    EMAC_Pkt    *pPkt;

    /*
    // Basic Test Initialization
    */

    printf("EMAC Loopback Test - multicast packets \n");

    /* Init packet data array */
    for( i=0; i<6; i++ )
        packet_sourcedata[i] = dstaddr[2][i];

    for( i=6; i<MAXPACKETSIZE; i++ )
        packet_sourcedata[i] = i;

    /* Initialize our buffer pool */
    memset( &FreeQueue, 0, sizeof(PKTQ) );
    memset( &RxQueue, 0, sizeof(PKTQ) );
    for( i=0; i<PKT_MAX; i++ )
    {
        /*
        // Init the buffer headers. Note that the buffer pointer
        // and buffer length are fixed and do not change
        */
        memset( &packet_header[i], 0, sizeof(EMAC_Pkt) );
        packet_header[i].pDataBuffer = packet_buffer[i];
        packet_header[i].BufferLen   = MAXPACKETSIZE+4;
        pqPush( &FreeQueue, &packet_header[i] );
    }

    /*
    // Initialize Configuration and Open EMAC
    */

	interface = CSL_FEXT(DEV_REGS->DEVSTAT, DEV_DEVSTAT_MACSEL);

    /* Setup the EMAC configuration */
#if LOCAL_LOOPBACK
    ecfg.ModeFlags      = EMAC_CONFIG_MODEFLG_MACLOOPBACK;
#else
    ecfg.ModeFlags      = 0;
#endif

#if PHY_LOOPBACK
	if (( interface == CSL_DEV_DEVSTAT_MACSEL_MII ) || ( interface == CSL_DEV_DEVSTAT_MACSEL_RMII ))
	    ecfg.MdioModeFlags  = MDIO_MODEFLG_FD100 | MDIO_MODEFLG_LOOPBACK;
	if (( interface == CSL_DEV_DEVSTAT_MACSEL_RGMII ) || (interface == CSL_DEV_DEVSTAT_MACSEL_GMII ))
		ecfg.MdioModeFlags  = MDIO_MODEFLG_FD1000 | MDIO_MODEFLG_LOOPBACK;
#else
	if (( interface == CSL_DEV_DEVSTAT_MACSEL_MII ) || ( interface == CSL_DEV_DEVSTAT_MACSEL_RMII ))
    	ecfg.MdioModeFlags  =  MDIO_MODEFLG_AUTONEG;
	if (( interface == CSL_DEV_DEVSTAT_MACSEL_RGMII ) || (interface == CSL_DEV_DEVSTAT_MACSEL_GMII ))
		ecfg.MdioModeFlags  = MDIO_MODEFLG_FD1000 | MDIO_MODEFLG_EXTLOOPBACK;
#endif
    ecfg.TxChannels     = 1;
    ecfg.RxMaxPktPool   = 8;
    ecfg.pfcbGetPacket  = &GetPacket;
    ecfg.pfcbFreePacket = &FreePacket;
    ecfg.pfcbRxPacket   = &RxPacket;
    ecfg.pfcbStatus     = &StatusUpdate;
    ecfg.pfcbStatistics = &StatisticsUpdate;

    /*
    // For this test we'll set our EMAC address to be 00:01:02:03:04:05
    // If this were a real driver, we'd have to read the EMAC
    // address from where it is stored in hardware (board dependent)
    */
    for( i=0; i<6; i++ )
        ecfg.MacAddr[i] = i;

    /* Open EMAC instance */
    printf("Calling EMAC_open().\n");
    i = EMAC_open( 1, (Handle)0x12345678, &ecfg, &hEMAC );
    if(i)
    {
        printf("Returned error %08x\n",i);
        goto exit;
    }

    /* Enable EMAC Interrupt */
    C64_enableIER( EMAC_INT_FLAG );

    /* Set the receive filter */
    /* Use our re-entrancy gate to call EMAC functions */
    printf("Calling EMAC_setReceiveFilter()\n");
    OUREMAC_enter();
		EMAC_setMulticast( hEMAC, 2, mcastlist );
    	i = EMAC_setReceiveFilter( hEMAC, EMAC_RXFILTER_MULTICAST );
    OUREMAC_exit();
    if(i)
    {
        printf("Returned error %08x\n",i);
        goto close_emac;
    }

    /*
    // Wait for the device to link
    //
    // The device can not send or receive packets until it is
    // linked.
    //
    */
    printf("Waiting for link...\n");
    LocalTicks = 0;
    while( !LinkStatus && LocalTicks < 100 );

    if( !LinkStatus ) {
        printf("\nWARNING: No device LINK.\n");
		goto close_emac;
	}

	/* Print link status */
    if( LinkStatus <= 5 )
        printf("\nLink Status  : %s on PHY number %d\n",
               LinkStr[LinkStatus],status.PhyDev);

    printf("Packets Held : %d-RX  %d-TX\n",
           status.RxPktHeld, status.TxPktHeld);

    if( status.FatalError )
        printf("Fatal Error  : %d\n",status.FatalError);


    /* Start the test */
    printf("\nStarting packet test...\n");

    LocalTicks = 0;
    while( RxCount<TestCount )
    {
        /* Check for timeout */
        if( LocalTicks > 50 )
        {
            printf("ERROR: Timeout waiting for TX/RX\n");
            break;
        }

        /* See if we should send a packet */
        if( TxCount<TestCount && TxCount<(RxCount+8) )
        {
            /*
            // Send a packet
            */

            /* First get a packet buffer from our private queue */
            pPkt = pqPop( &FreeQueue );
            if( pPkt )
            {
                /* Fill buffer with a pattern, using "count+60" for size */
                size = TxCount + 60;
                memcpy( pPkt->pDataBuffer, packet_sourcedata, size);

                /* Send the packet */
                pPkt->Flags      = EMAC_PKT_FLAGS_SOP | EMAC_PKT_FLAGS_EOP;
                pPkt->ValidLen   = size;
                pPkt->DataOffset = 0;
                pPkt->PktChannel = 0;
                pPkt->PktLength  = size;
                pPkt->PktFrags   = 1;

                /*
                // IMPORTANT: If our data packet were in EXTERNAL memory,
                // we would have to clean it from the CACHE before submitting
                // it to the EMAC module!!!
                //
                // We should probably do the clean operation right here.
                */

                /* Use our re-entrancy gate to call EMAC functions */

⌨️ 快捷键说明

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