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

📄 emac_local_loopback_example.c

📁 dsp tms320c6486的csl例程
💻 C
📖 第 1 页 / 共 2 页
字号:
        printf("\nMake sure to use a loopback connector if not\n");
        printf("using local loopback (#define LOCAL_LOOPBACK 1)\n");
    }

    exit (0);
}


/*
 * =============================================================================
 *   @func   HwRxInt
 *
 *   @desc
 *      Interrupt service routine called as a result of the EMAC hardware Rx
 *      interrupt.
 *
 *   @arg
 *      None
 *      
 *   @eg
 *      HwRxInt(); // Refer description
 * =============================================================================
 */
void interrupt HwRxInt(void)
{
    Uint32 i;

    if (hEMAC)
    {
        i = EMAC_RxServiceCheck(hEMAC, 0);
        if (i) 
        {
            return;
         	// printf("EMAC_RxServiceCheck() returned error %08x\n",i);
        }
    }
    return;
}


/*
 * =============================================================================
 *   @func   HwTxInt
 *
 *   @desc
 *      Interrupt service routine called as a result of the EMAC hardware Tx
 *      interrupt.
 *
 *   @arg
 *      None
 *      
 *   @eg
 *      HwTxInt(); // Refer description
 * =============================================================================
 */
void interrupt HwTxInt(void)
{
    Uint32 i;

    if (hEMAC) 
    {
        i = EMAC_TxServiceCheck(hEMAC, 0);
        if (i) 
        {
            return;
         	// printf("EMAC_TxServiceCheck() returned error %08x\n",i);
        }
    }
    return;
}


/*
 * =============================================================================
 *   @func   TimerTick
 *
 *   @desc
 *      Timer tick service routine - called from 100mS PRD
 *
 *   @arg
 *      None
 *      
 *   @eg
 *      TimerTick(); // Refer description
 * =============================================================================
 */
void interrupt TimerTick(void)
{
   /* Keep track of time for our local timeout loops */
    LocalTicks++;

    /* Poll the EMAC */
    if (hEMAC) 
    {
        OUREMAC_enter();
        EMAC_timerTick(hEMAC, 0);
        OUREMAC_exit();
    }
}
/*
 * =============================================================================
 *   @func   GetPacket - Get empty packet for RX.
 *
 *   @desc
 *      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.
 *
 *   @arg
 *      hApplication    Handle to the application
 *      
 *   @eg
 *      Handle  hApp;
 *      ... // Initialize and get a value to handle- done elsewhere.
 *      GetPacket(hApp); // Refer description
 *      ...
 * =============================================================================
 */
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 ) {
        //printf("GetPacket(): Bad App Handle!\n");
        return(0);
    }

    /* Pop a packet off our local free queue */
    pPkt = App_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 );
}
/*
 * =============================================================================
 *   @func   FreePacket
 *
 *   @desc
 *      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).
 *
 *   @arg
 *      hApplication    handle to the application
 *      pPKT            poiner to the EMAC packet
 *      
 *   @eg
 *      Handle   hApp;
 *      EMAC_Pkt *emacPkt;
 *      ...
 *      FreePacket(hApp, emacPkt); // Refer description
 *      ...
 * =============================================================================
 */
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 ) {
        return;
    }
    App_pqPush( &FreeQueue, pPKT );
}

/*
 * 
 *
 */
/*
 * =============================================================================
 *   @func   RxPacket - Reveived packet from the Network.
 *
 *   @desc
 *      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.
 *
 *   @arg
 *      hApplication    handle to the application
 *      pPKT            poiner to the EMAC packet
 *      
 *   @eg
 *      Handle   hApp;
 *      EMAC_Pkt *emacPkt;
 *      ...
 *      RxPacket(hApp, emacPkt); // Refer description
 *      ...
 * =============================================================================
 */
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 ) {
        return(0);
    }

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

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

/*
 * =============================================================================
 *   @func   StatusUpdate
 *
 *   @desc
 *      The EMAC or MDIO status has changed 
 *
 *   @arg
 *      hApplication    handle to the application
 *      
 *   @eg
 *      Handle   hApp;
 *      ...
 *      StatusUpdate(hApp); // Refer description
 *      ...
 * =============================================================================
 */
static void StatusUpdate( Handle hApplication )
{

    /* Verify our handle came back OK. We don't use it in this example */
    if( (Uint32)hApplication != 0x12345678 ) {
        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 and print it out. Note we
     * don't start sending packets until we have a good link.
     *
     */
    EMAC_getStatus( hEMAC, &status, 0);

    LinkStatus = status.MdioLinkStatus;

    /* if( !LinkStatus )
        printf("Link Status: %s\n",LinkStr[LinkStatus]);
    else if( LinkStatus <= 4 )
        printf("Link 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);
    */
}

/*
 * =============================================================================
 *   @func   StatisticsUpdate
 *
 *   @desc
 *      The EMAC statistics are in danger of overflow
 *
 *   @arg
 *      hApplication    handle to the application
 *      
 *   @eg
 *      Handle   hApp;
 *      ...
 *      StatisticsUpdate(hApp); // Refer description
 *      ...
 * =============================================================================
 */
static void StatisticsUpdate( Handle hApplication )
{
    /* Verify our handle came back OK. We don't use it in this example */
    if( (Uint32)hApplication != 0x12345678 ) {
        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.
     */
}

/*
 * =============================================================================
 *   @func   verify_packet()
 *
 *   @desc
 *      Perform a sanity check validation on the packet
 *
 *   @arg
 *      pPkt    EMAC packet
 *      size    size to validate
 *      
 *   @eg
 *      EMAC_Pkt    *pkt;
 *      Uint32      size;
 *      ... ; // variables to get value elsewhere.
 *      verify_packet(pkt, size);
 *      ...
 * =============================================================================
 */
static int verify_packet( EMAC_Pkt *pPkt, Uint32 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) ) {
            printf("Verify: Bad data at %d (%d)(%d)\n",i,*pBuf,i&0xff);
            return(0);
        }

    return(1);
}

/* ============================================================================
 *  @func App_pqPop()
 *
 *  @desc
 *      Pop a desc buffer off a queue
 *
 *   @arg
 *      pq    Application packet
 *      
 *   @eg
 *      APP_PKTQ    *pq;
 *      ... ; // variables to get value elsewhere.
 *      App_pqPop(pq);
 *      ...
 * ============================================================================
 */
static EMAC_Pkt *App_pqPop( APP_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 );
}

/* ============================================================================
 *  @func App_pqPush()
 *
 *  @desc
 *      Push a desc buffer onto a queue
 *
 *   @arg
 *      pq      Application packet
 *      pPktHdr pointer to EMAC pakcet header
 *      
 *   @eg
 *      APP_PKTQ    *pq;
 *      EMAC_Pkt    *pPktHdr;
 *      ... ; // variables to get value elsewhere.
 *      App_pqPush(pq, pPktHdr);
 *      ...
 * ============================================================================
 */
static void App_pqPush( APP_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 + -