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

📄 c6455.c

📁 TI公司的NSP
💻 C
📖 第 1 页 / 共 3 页
字号:
    EMAC_REGS->RXMBPENABLE = 0;
    EMAC_REGS->MACHASH1 = 0;
    EMAC_REGS->MACHASH2 = 0;

    /* Clear Unicast RX on channel 0-7 */
    EMAC_REGS->RXUNICASTCLEAR = 0xFF;

    /* Set the pass RX CRC mode */
    CSL_FINST(EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXPASSCRC, INCLUDE );

    /* Set MAC loopback if requested */
    //  CSL_FINST(EMAC_REGS->MACCONTROL, EMAC_MACCONTROL_LOOPBACK, ENABLE );

    /*
    // Enable TX and RX channel interrupts (set mask bits)
    // Enable Host interrupts
    */
    EMAC_REGS->RXINTMASKCLEAR = 0xFF;
    EMAC_REGS->TXINTMASKCLEAR = 0xFF;
    EMAC_REGS->RXINTMASKSET = 0x1;
    EMAC_REGS->TXINTMASKSET = 0x1;
    EMAC_REGS->MACINTMASKSET =  CSL_FMK( EMAC_MACINTMASKSET_HOSTMASK, 1 ) |
                                CSL_FMK( EMAC_MACINTMASKSET_STATMASK, 1 ) ;

    /*
    // Setup Receive Buffers
    */

    /* Pointer to first descriptor to use on RX */
    pDesc = (EMAC_Desc *)_EMAC_DSC_BASE_ADDR;

    /* Number of descriptors for RX channel */
    utemp1 = EMAC_MAX_RX;

    /* Init Rx channel */
    mmZeroInit( &chRx, sizeof(EMAC_DescCh) );
    chRx.DescMax    = utemp1;
    chRx.pDescFirst = pDesc;
    chRx.pDescLast  = pDesc + (utemp1 - 1);
    chRx.pDescRead  = pDesc;
    chRx.pDescWrite = pDesc;

    /* Fill the descriptor table */
    emacEnqueueRx(0);

    /*
    // If we didn't get the number of descriptor buffers that we
    // wanted to, abort now.
    */
    if( chRx.DescCount < utemp1 )
    {
        /* Free all RX descriptors */
        while( hPkt = PBMQ_deq( &chRx.DescQueue ) )
            PBM_free(hPkt);

        /* Close the MDIO Module */
        MDIO_close( hMDIO );

        /* Return the error condition */
        return( 0 );
    }

    /*
    // Setup Transmit Buffers
    */

    /* Pointer to first descriptor to use on TX */
    pDesc += utemp1;

    /* Number of descriptors (max) for TX channel */
    utemp1 = (_EDMA_DSC_ENTRY_COUNT-utemp1);

    /* Init TX channel */
    mmZeroInit( &chTx, sizeof(EMAC_DescCh) );
    chTx.DescMax    = utemp1;
    chTx.pDescFirst = pDesc;
    chTx.pDescLast  = pDesc + (utemp1 - 1);
    chTx.pDescRead  = pDesc;
    chTx.pDescWrite = pDesc;


    /*
    // Enable RX, TX, and MII
    //
    // Note in full duplex mode we also need to set the FULLDUPLEX
    // bit in MACCRONTROL. However, we don't know what to set until
    // we have a link. Also, we must be able to dynamically change
    // this bit if the cable is unplugged and re-linked with a different
    // duplex.
    */
    CSL_FINST( EMAC_REGS->TXCONTROL, EMAC_TXCONTROL_TXEN, ENABLE );
    CSL_FINST( EMAC_REGS->RXCONTROL, EMAC_RXCONTROL_RXEN, ENABLE );
    EMAC_REGS->MACCONTROL = CSL_FMKT( EMAC_MACCONTROL_RXOWNERSHIP, ONE )                |
                                                CSL_FMKT( EMAC_MACCONTROL_RXOFFLENBLOCK, BLOCK )        |
                                                CSL_FMKT( EMAC_MACCONTROL_GMIIEN, ENABLE );

    /* Startup RX */
    EMAC_REGS->RX0HDP = (Uint32)chRx.pDescRead ;

    /* Enable global interrupt in wrapper */
    CSL_FINST( ECTL_REGS->EWCTL, ECTL_EWCTL_INTEN, ENABLE );

    return(1);
}

/*--------------------------------------------------------------------*\
* emacDequeueTx()
*
* Dequeue all completed TX packets and return buffers to application
\*--------------------------------------------------------------------*/
static void emacDequeueTx( EMAC_Desc *pDescAck )
{
    PBM_Handle  hPkt;
    Uint32      PktFlgLen;
    register uint  i,j = (uint)chTx.pDescRead;

    /* Get the status of the ACK descriptor */
    PktFlgLen = pDescAck->PktFlgLen;

    /* Calc the new "Read" descriptor */
    if( pDescAck == chTx.pDescLast )
        chTx.pDescRead = chTx.pDescFirst;
    else
        chTx.pDescRead = pDescAck+1;

    i = (uint)chTx.pDescRead;

    /* Turn i into a descriptor count */
    if( j < i )
        i = (i-j)/sizeof(EMAC_Desc);
    else
        i = chTx.DescMax - ((j-i)/sizeof(EMAC_Desc));

    chTx.DescCount -= i;

    /* Pop & Free Buffers 'till the last Descriptor */
    while( i-- )
    {
        // Recover the packet and free it
        hPkt = PBMQ_deq( &chTx.DescQueue );
        if( hPkt )
            PBM_free( hPkt );
    }

    // If the transmitter stopped and we have more descriptors, then restart
    if( (PktFlgLen & EMAC_DSC_FLAG_EOQ) && chTx.DescCount )
        EMAC_REGS->TX0HDP = (Uint32)chTx.pDescRead;
}


/*--------------------------------------------------------------------*\
* emacEnqueueRx()
*
* Fill any empty RX descriptors with new buffers from the application
\*--------------------------------------------------------------------*/
static void emacEnqueueRx( uint fRestart )
{
    PBM_Handle  hPkt;
    EMAC_Desc   *pDesc;
    uint        CountOrg;
    UINT8       *buffer;

    // Keep the old count around
    CountOrg = chRx.DescCount;

    // Fill RX Packets Until Full
    while( chRx.DescCount < chRx.DescMax )
    {
        // Try and get a buffer.
        hPkt = PBM_alloc( 1518 + PKT_PREPAD );

        if( !hPkt )
            break;

        PBM_setDataOffset( hPkt, PKT_PREPAD );
        buffer = PBM_getDataBuffer(hPkt) + PKT_PREPAD;

        // Clean the cache for external addesses
        if( (UINT32)buffer & EXTMEM )
            OEMCacheClean( (void *)buffer, 1518 );

        // Fill in the descriptor for this buffer
        pDesc = chRx.pDescWrite;

        // Move the write pointer and bump count
        if( chRx.pDescWrite == chRx.pDescLast )
            chRx.pDescWrite = chRx.pDescFirst;
        else
            chRx.pDescWrite++;
        chRx.DescCount++;

        // Fill in the descriptor
        pDesc->pNext     = 0;
        pDesc->pBuffer   = buffer;
        pDesc->BufOffLen = 1518;
        pDesc->PktFlgLen = EMAC_DSC_FLAG_OWNER;

        // Enqueue this packet onto the desc queue
        PBMQ_enq( &chRx.DescQueue, hPkt );

        // Synch the cache
        if( (UINT32)buffer & EXTMEM )
            OEMCacheCleanSynch();

        // Make the previous buffer point to us
        if( pDesc == chRx.pDescFirst )
             chRx.pDescLast->pNext = pDesc;
        else
            (pDesc-1)->pNext = pDesc;
    }

    /* Restart RX if we had ran out of descriptors and got some here */
    if( fRestart && !CountOrg && chRx.DescCount )
        EMAC_REGS->RX0HDP = (Uint32)chRx.pDescRead;
}


/*--------------------------------------------------------------------*\
* emacDequeueRx()
*
* Dequeue all completed RX packets and give buffers to application
\*--------------------------------------------------------------------*/
static void emacDequeueRx( EMAC_Desc *pDescAck )
{
    PBM_Handle  hPkt;
    uint        tmp;
    Uint32      PktFlgLen;
    uint        NeedService = 0;
    EMAC_Desc   *pDescNewRxFirst,*pDescNewRxLast=0,*pTemp;
    UINT8       *buffer;

    /* Remember the first new descriptor slot */
    pDescNewRxFirst = chRx.pDescWrite;

    /*
    // Pop & Free Buffers 'till the last Descriptor
    // One thing we know for sure is that all the decriptors from
    // the read pointer to pDescAsk are linked to each other via
    // their pNext field.
    */
    for( tmp=1; tmp; )
    {
        /* Get the status of this descriptor */
        PktFlgLen = chRx.pDescRead->PktFlgLen;

        // Recover the packet and pass it on
        hPkt = PBMQ_deq( &chRx.DescQueue );
        if( hPkt )
        {
            // Enqueue the packet and signal the stack
#ifndef _INCLUDE_NIMU_CODE
            PBM_setIFRx( hPkt, pPDI->hEther );
            PBM_setValidLen(hPkt,(PktFlgLen & 0xFFFF));
            PBMQ_enq( &PBMQ_rx, hPkt );
#else
            /* Remove the 4 byte CRC at the end of the packet and account for it. */
            PktFlgLen = (PktFlgLen & 0xFFFF) - 4; 
            PBM_setValidLen (hPkt,PktFlgLen);
            PBMQ_enq( &pPDI->PBMQ_rx, hPkt );
#endif
            NeedService = 1;
        }

        /* See if this was the last buffer */
        if( chRx.pDescRead == pDescAck )
            tmp = 0;

        /* Move the read pointer and decrement count */
        if( chRx.pDescRead == chRx.pDescLast )
            chRx.pDescRead = chRx.pDescFirst;
        else
            chRx.pDescRead++;
        chRx.DescCount--;

        // Try and get a buffer.
        hPkt = PBM_alloc( 1518 + PKT_PREPAD );

        if( hPkt )
        {
            PBM_setDataOffset( hPkt, PKT_PREPAD );
            buffer = PBM_getDataBuffer(hPkt) + PKT_PREPAD;

            // Clean the cache for external addresses
            if( (UINT32)buffer & EXTMEM )
                OEMCacheClean( (void *)buffer, 1518 );

            // Fill in the descriptor for this buffer
            pDescNewRxLast = chRx.pDescWrite;

            // Move the write pointer and bump count
            if( chRx.pDescWrite == chRx.pDescLast )
                chRx.pDescWrite = chRx.pDescFirst;
            else
                chRx.pDescWrite++;
            chRx.DescCount++;

            // Fill in the descriptor
            pDescNewRxLast->pBuffer   = buffer;

            // Enqueue this packet onto the desc queue
            PBMQ_enq( &chRx.DescQueue, hPkt );
        }
    }

    /*
    // If we added descriptors, make the pNext of the last NULL, and
    // make the previous descriptor point to the new list we added.
    */
    if( pDescNewRxLast )
    {
        pDescNewRxLast->pNext = 0;

        // Synch the cache
        if( (UINT32)buffer & EXTMEM )
            OEMCacheCleanSynch();

        /* Make the previous buffer point to us */
        if( pDescNewRxFirst == chRx.pDescFirst )
            pTemp = chRx.pDescLast;
        else
            pTemp = pDescNewRxFirst-1;

        /*
        // If these pointers wrapped, the RX engine is stopped
        // Otherwise; tack the new list to the old
        */
        if( pTemp != pDescNewRxLast )
            pTemp->pNext = pDescNewRxFirst;
    }

    /* If the receiver stopped and we have more descriptors, then restart */
    if( (PktFlgLen & EMAC_DSC_FLAG_EOQ) && chRx.DescCount )
        EMAC_REGS->RX0HDP = (Uint32)chRx.pDescRead ;

    // Signal the stack if needed
    if( NeedService )
    {
        FlashActiveLED = 1;
        STKEVENT_signal( pPDI->hEvent, STKEVENT_ETHERNET, 1 );
    }
}




⌨️ 快捷键说明

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