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

📄 loopback_main-multicast.c

📁 ti的TMS320C64XEMAC应用源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
                OUREMAC_enter();
                	i = EMAC_sendPacket( hEMAC, pPkt );
                OUREMAC_exit();
                if(i)
                {
                    printf("EMAC_sendPacket() returned error %08x\n",i);
                    break;
                }

                /* Bump the TX count */
                TxCount++;
            }
        }

        /*
        // See if we received a packet
        */
        if( pPkt = pqPop( &RxQueue ) )
        {
            /* Validate this packet */
            if( !verify_packet( pPkt, RxCount + 60 ) )
            {
                printf("ERROR: Verify failure on packet %d\n",RxCount);
                break;
            }

            /* Free the packet */
            pqPush( &FreeQueue, pPkt );

            /* Bump the RX count */
            RxCount++;
        }
    }

    printf("Sent %d of %d packets, received %d packets\n",
            TxCount, TestCount, RxCount);

    /*
    // Close EMAC
    */
close_emac:

    /* Since we're done, we leave the interrupt disabled */
    C64_disableIER( EMAC_INT_FLAG );

    printf("Calling EMAC_close()\n");
    i = EMAC_close( hEMAC );
    hEMAC = 0;
    if(i)
    {
        printf("Returned error %08x\n",i);
        goto exit;
    }

exit:
    if( TxCount == TestCount && RxCount == TestCount )
        printf("\nTest Passed\n");
    else
    {
        printf("\nTest Failed.\n");
        printf("\nMake sure to use a loopback connector if not\n");
        printf("using local loopback (#define LOCAL_LOOPBACK 1).\n");
    }

    for(;;);
}


/*
// HwInt
//
// Interrupt service routine called as a result of
// the EMAC hardware interrupt.
*/
void HwInt(void)
{
    Uint32 i;

    /*
    // Since our ISR is left masked by the INT dispacher, and ISR has
    // a higher priority than any task, we can simply call the sevice
    // function without re-entrancy concerns.
    */
    if( hEMAC )
    {
        i = EMAC_serviceCheck( hEMAC );
        if( i ) {
	        LOG_printf(&logTrace, "EMAC_serviceCheck() returned error %08x\n", i);
			return;
		}
    }

    return;
}


/*
// TimerTick
//
// Timer tick service routine - called from 100mS PRD
*/
void TimerTick(void)
{
   /* Keep track of time for our local timeout loops */
    LocalTicks++;

    /* Poll the EMAC */
    if( hEMAC )
    {
        OUREMAC_enter();
        EMAC_timerTick( hEMAC );
        OUREMAC_exit();
    }
}


/*
// GetPacket - Get empty packet for RX.
//
// This function is called from the EMAC module to get an
// empty packet buffer. We need to return a packet buffer to the
// EMAC or return NULL if there are no buffers available.
*/
static EMAC_Pkt *GetPacket( Handle hApplication )
{
    EMAC_Pkt *pPkt;

    /* Verify our handle came back OK. We don't use it in this example */
    if( (Uint32)hApplication != 0x12345678 )
    {
        LOG_printf(&logTrace, "GetPacket: Bad App Handle!");
        return(0);
    }

    /* Pop a packet off our local free queue */
    pPkt = pqPop(&FreeQueue);

    if( pPkt )
    {
        /*
        // Here we tell the EMAC what offset to use by setting
        // the DataOffset field in the packet.
        */
        pPkt->DataOffset = 0;

        /*
        // IMPORTANT: If our data packet were in EXTERNAL memory,
        // we would have to invalidated it from the CACHE before
        // returning it to the EMAC module!!!
        //
        // We should probably do the clean operation right here.
        // However, we are most likely inside an ISR right now.
        // It may be better to invalidate the buffer before it
        // is pushed on the FreeQueue.
        */
    }

    return( pPkt );
}


/*
// FreePacket - Free packet that originated from TX or GetPacket().
//
// This function is called from the EMAC module to free a
// packet buffer after a TX operation (or RX in the case of
// a RX shutdown).
//
*/
static void FreePacket( Handle hApplication, EMAC_Pkt *pPKT )
{
    /* Verify our handle came back OK. We don't use it in this example */
    if( (Uint32)hApplication != 0x12345678 )
    {
		LOG_printf(&logTrace, "FreePacket(): Bad App Handle!");
        return;
    }

    pqPush( &FreeQueue, pPKT );
}


/*
// RxPacket - Reveived packet from the Network.
//
// This function is called by the EMAC to indicate a receive. Here
// we just push the packet onto our receive queue.
//
// This function returns a free packet to replace the RX packet on
// the EMAC queue. If there are no free packets available, we
// return NULL.
*/
static EMAC_Pkt *RxPacket( Handle hApplication, EMAC_Pkt *pPKT )
{
    /* Verify our handle came back OK. We don't use it in this example */
    if( (Uint32)hApplication != 0x12345678 )
    {
        LOG_printf(&logTrace, "RxPacket: Bad App Handle!");
        return(0);
    }

    /* Push this packet onto our local receive queue */
    pqPush( &RxQueue, pPKT );

    /* We must return a free packet to replace the one we were given */
    return( GetPacket(hApplication) );
}

/*
// StatusUpdate - The EMAC or MDIO status has changed
*/
static void StatusUpdate( Handle hApplication )
{
    uint        retval;

    /* Verify our handle came back OK. We don't use it in this example */
    if( (Uint32)hApplication != 0x12345678 )
    {
        LOG_printf(&logTrace, "StatusUpdate: Bad App Handle!");
        return;
    }

    /*
    // The status update function is called for a variety of
    // reasons, including LINK change events and EMAC errors.
    // We'll get the current status here. Note we
    // do not start sending packets until we have a good link.
    //
    // NOTE: We call back into the EMAC without any reentrancy
    //       concerns. This because we are a callback function
    //       that was called from EMAC. Thus the reentrancy
    //       protection is still active!
    */
    retval = EMAC_getStatus( hEMAC, &status );
    LOG_printf(&logTrace, "EMAC_getPacket returned %d", retval);
    LinkStatus = status.MdioLinkStatus;

	if( !LinkStatus )
        LOG_printf(&logTrace, "Link Status: %s\n",LinkStr[LinkStatus]);
    else if( LinkStatus <= 4 )
        LOG_printf(&logTrace, "Link Status  : %s on PHY number %d",
               LinkStr[LinkStatus],status.PhyDev);

    LOG_printf(&logTrace, "Packets Held : %d-RX  %d-TX",
           status.RxPktHeld, status.TxPktHeld);

	if( status.FatalError )
        LOG_printf(&logTrace, "Fatal Error: %d", status.FatalError);
}


/*
// StatisticsUpdate - The EMAC statistics are in danger of overflow
*/
static void StatisticsUpdate( Handle hApplication )
{
    /* Verify our handle came back OK. We don't use it in this example */
    if( (Uint32)hApplication != 0x12345678 )
    {
        LOG_printf(&logTrace, "StatisticsUpdate: Bad App Handle!");
        return;
    }

    /*
    // Here we could call the EMAC_getStatistics() function and pass
    // them to whoever wants them. This example app doesn't have
    // anything to do with them so we do nothing.
    */
}


/*
// verify_packet()
//
// Perform a sanity check validation on the packet
*/
static int verify_packet( EMAC_Pkt *pPkt, uint size )
{
    int i;
    Uint8 *pBuf;

    if( (pPkt->Flags & (EMAC_PKT_FLAGS_SOP | EMAC_PKT_FLAGS_EOP)) !=
        (EMAC_PKT_FLAGS_SOP | EMAC_PKT_FLAGS_EOP) )
    {
        printf("Verify: Bad Flags %08x\n",pPkt->Flags);
        return(0);
    }

    if( pPkt->ValidLen != size )
    {
        printf("Verify: Bad ValidLen %d %d\n",pPkt->ValidLen,size);
        return(0);
    }

    if( pPkt->DataOffset != 0 )
    {
        printf("Verify: Bad DataOffset %d\n",pPkt->DataOffset);
        return(0);
    }


    if( pPkt->PktChannel != 0 )
    {
        printf("Verify: Bad Channel %d\n",pPkt->PktChannel);
        return(0);
    }

    if( pPkt->PktLength != size )
    {
        printf("Verify: Bad PktLength %d\n",pPkt->PktLength);
        return(0);
    }

    if( pPkt->PktFrags != 1 )
    {
        printf("Verify: Bad Frag Count %d\n",pPkt->PktFrags);
        return(0);
    }

    pBuf = pPkt->pDataBuffer+pPkt->DataOffset;
    for( i=0; i<size; i++, pBuf++ )
        if( (*pBuf != (i&0xFF)) && (i >= 6) )
        {
            printf("Verify: Bad data at %d (%d)(%d)\n",i,*pBuf,i&0xff);
            return(0);
        }

    return(1);
}

/*--------------------------------------------------------------------*\
* pqPop()
*
* Pop a desc buffer off a queue
\*--------------------------------------------------------------------*/
static EMAC_Pkt *pqPop( PKTQ *pq )
{
    EMAC_Pkt *pPktHdr;

    OUREMAC_enter();

    pPktHdr = pq->pHead;

    if( pPktHdr )
    {
        pq->pHead = pPktHdr->pNext;
        pq->Count--;
        pPktHdr->pPrev = pPktHdr->pNext = 0;
    }

    OUREMAC_exit();

    return( pPktHdr );
}

/*--------------------------------------------------------------------*\
* pqPush()
*
* Push a desc buffer onto a queue
\*--------------------------------------------------------------------*/
static void pqPush( PKTQ *pq, EMAC_Pkt *pPktHdr )
{
	OUREMAC_enter();

    pPktHdr->pNext = 0;

    if( !pq->pHead )
    {
        // Queue is empty - Initialize it with this one packet
        pq->pHead = pPktHdr;
        pq->pTail = pPktHdr;
    }
    else
    {
        // Queue is not empty - Push onto END
        pq->pTail->pNext = pPktHdr;
        pq->pTail        = pPktHdr;
    }
    pq->Count++;

	OUREMAC_exit();

}

⌨️ 快捷键说明

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