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

📄 mxi.c

📁 dm642网络传输程序
💻 C
📖 第 1 页 / 共 2 页
字号:
    WRITE32( GMAC_CONTROL, 0x0 );

    // Reset the FIFO
    WRITE32( GMAC_AUX2, 0xe800 );
    Delay(2);
    WRITE32( GMAC_AUX2, 0x2800 );

    //
    // Clear all internal memory
    //

    // Set BP = 0x1FF
    WRITE32( GMAC_ISR, 0x01FF0000 );

    // Set TWP
    WRITE32( GMAC_TXRING1, 0x0 );

    // Set TRP
    WRITE32( GMAC_TXRING2, 0x0 );

    j = 0;
    page = 0;
    for( i=0; i<32768; i++ )
    {
        WRITE32( GMAC_TWD, 0 );
        j += 4;
        if( !(j & 0xFF) )
        {
            page += 0x10000;
            page &= 0xfff0000;
            WRITE32( GMAC_TXRING1, page );
        }
    }
}

//--------------------------------------------------------------------
// gmReset()
//
// Reset GMAC, initialize, and prepare to start
//--------------------------------------------------------------------
static void gmReset()
{
    // Hard Reset
    WRITE32( GMAC_RESET_ON, 0 );
    Delay(4);
    WRITE32( GMAC_RESET_OFF, 0 );
    Delay(4);

    // Soft Reset
    WRITE32( GMAC_CONTROL, GM_RESET );
    Delay(2);
    WRITE32( GMAC_CONTROL, 0x0 );

    // Reset the FIFO
    WRITE32( GMAC_AUX2, 0xe800 );
    Delay(2);
    WRITE32( GMAC_AUX2, 0x2800 );

    // Set auto-recover on Rx DMA
    WRITE32( GMAC_AUX3, GM_AUTORCVR );

    // Set RRP and RHBP
    WRITE32( GMAC_RXRING2, 0x01FF0000 );

    // Set RWP
    WRITE32( GMAC_RXRING1, 0x00000000 );

    // Set TLBP and TWP
    WRITE32( GMAC_TXRING1, 0x0 );

    // Set TRP
    WRITE32( GMAC_TXRING2, 0x0 );

    // Enable Autoneg, linktest, 16 bit mode, and TX Fifo count registers
    WRITE32( GMAC_CONFIG, GM_LTE|GM_ANE|GM_PBW|GM_TXFIFOCNTEN );

    // Clear interrupt mask and set BP
    WRITE32( GMAC_ISR, 0x00000000 );

    // Reset the FIFO
    WRITE32( GMAC_AUX2, 0xe800 );
    Delay(2);
    WRITE32( GMAC_AUX2, 0x2800 );

    // Enable interrupts (and set BP)
    WRITE32( GMAC_ISR, 0x00000000|INTMASK );

    // Tansmitter is not free until we start
    pGMI->TxFree = 0;

    // Reset any pending error
    FatalError = 0;
}

//--------------------------------------------------------------------
// gmStart()
//
// Start GMAC Rx and Tx state machines
//--------------------------------------------------------------------
static void gmStart()
{
    UINT32 control;

    // Initialize states
    TxState = STATE_IDLE;
    RxState = STATE_IDLE;
    pGMI->TxFree = 1;

    // Setup Rx Filter Mode
    HwPktSetRx( pGMI );

    // Start receive
    control = READ32( GMAC_CONTROL ) & 0x0000FF00;
    control |= GM_SR;

    // Turn on local loopback if hEther is NULL
    if( !pGMI->hEther )
        control |= GM_LB0;

    WRITE32( GMAC_CONTROL, control );
}

//--------------------------------------------------------------------
// gmStop()
//
// Stop GMAC, abort current Rx and Tx
//--------------------------------------------------------------------
static void gmStop()
{
    uint mask;

    // Disable GP interrupt
    mask = gmDisableIER( HW_IFLAG );

    // Stop anyone from entering HwPktTxNext()
    pGMI->TxFree = 0;

    // Let tasks fall out of TX or RX
    FatalError = 1;
    TSK_sleep( 100 );

    // Stop the device
    WRITE32( GMAC_CONTROL, 0 );
    TSK_sleep( 100 );

    // Reset the part
    gmReset();

    // Flush the Tx Queue
    while( PBMQ_count(&pGMI->PBMQ_tx) )
        PBM_free( PBMQ_deq(&pGMI->PBMQ_tx) );

    // Restore interrupts
    gmEnableIER( mask );
}

//--------------------------------------------------------------------
// gmSendPacket()
//
// This function is called with TxState = STATE_IDLE
// It will start the copy the buffer to GMAC and start the send.
//
// If the packet is not properly aligned, it will align it
//--------------------------------------------------------------------
static void gmSendPacket( PBM_Handle hPkt )
{
    unsigned int i;
    UINT32       *pi;
    UINT8        *buffer;
    int          length;

    // This should never happen, but check for it anyway
    if( FatalError || (READ32(GMAC_CONTROL) & (GM_ST0|GM_ST1)) )
    {
        FatalError = 1;
        TxState = STATE_SEND;
        PBM_free( hPkt );
        return;
    }

    // Get a pointer to where the data starts and its length
    buffer = PBM_getDataBuffer(hPkt) + PBM_getDataOffset(hPkt);
    length = PBM_getValidLen(hPkt);

    // This should never happen either, but check for it anyway
    if( (UINT32)buffer & 0x3 )
    {
        TxPanic++;
        mmCopy( pktPanicBuf, buffer, length );
        pi = (UINT32 *)pktPanicBuf;
    }
    else
        pi = (UINT32 *)buffer;

    // Set the frame size
    i = READ32(GMAC_AUX2)&0xffff | (length << 16);
    WRITE32( GMAC_AUX2, i );

    // Send out all the data
    length = (length+3)>>2;
    while( length-- )
        WRITE32( GMAC_WRTXFIFOD, *pi++ );

    // Send the frame
    i = READ32(GMAC_CONTROL)|GM_ST1;
    WRITE32( GMAC_CONTROL, i );

    TxState = STATE_SEND;

    // We can now free the packet
    PBM_free( hPkt );
}

//--------------------------------------------------------------------
// gmRxPacket()
//
// This function is called with RxState = STATE_DMA
// It will copy packet data from GMAC to the receive buffer.
//
// If there is a problem, the routine returns sets the
// RxState to IDLE and returns 0, else it returns 1.
//--------------------------------------------------------------------
static int gmRxPacket()
{
    register uint data1, data2, data3, data4;
    PBM_Handle    hPkt;
    unsigned int status;
    uint     *pibuf;
    int      length,tlen;

    if( FatalError )
        goto RxExit;

    // Rx a packet
    if( READ32( GMAC_AUX1 ) & GM_DREQB )
    {
        FatalError=1;
        goto RxExit;
    }

    // Read the first 16 bytes
    data1 = READ32( GMAC_RRD );
    data2 = READ32( GMAC_RRD );
    data3 = READ32( GMAC_RRD );
    data4 = READ32( GMAC_RRD );

    // Decode length, nextpage, and status
    length   = (data1 >> 12) & 0x0FFF;
    status   = (data1 >> 24) & 0x0FF;

    // Try to recover on startup error
    if( !length || length > 1518 )
    {
        FatalError=1;
        goto RxExit;
    }

    if( !(status & 0x80) )
    {
        RxGood++;
        // Try and get a buffer. If we can't, toss the packet.
        // Max packet size is unusual: ((((1518-12)-1)/16)+1)*16+12
        // and then we add on the prepad (this is because the
        // Macronix transfers data in 16 byte bursts and that the
        // first burst has only 12 bytes of data). The above
        // comes out to 1532, plus the prepad.
        hPkt = PBM_alloc( 1532 + PKT_PREPAD );
    }
    else
    {
        RxBad++;
        hPkt = 0;
    }

    // Pull the packet out - good or bad
    tlen  = length - 12;
    if( !hPkt )
    {
        // Get the rest of the packet
        while( tlen > 0 )
        {
            data2 = 0;
            while( READ32( GMAC_AUX1 ) & GM_DREQB )
                if( ++data2 == 1000 )
                {
                    FatalError=1;
                    goto RxExit;
                }
            data1 = READ32( GMAC_RRD );
            data2 = READ32( GMAC_RRD );
            data3 = READ32( GMAC_RRD );
            data4 = READ32( GMAC_RRD );
            tlen -= 16;
        }
    }
    else
    {
        // Fill in the packet size, offset and Ether handle
        PBM_setValidLen( hPkt, length );
        PBM_setDataOffset( hPkt, PKT_PREPAD );
        PBM_setIFRx( hPkt, pGMI->hEther );

        // Get a pointer to our buffer - add on PREPAD
        pibuf = (uint *)(PBM_getDataBuffer(hPkt)+PKT_PREPAD);

        // Copy the data we already have
        *pibuf++ = data2;
        *pibuf++ = data3;
        *pibuf++ = data4;

        // Get the rest of the packet
        while( tlen > 0 )
        {
            data1 = 0;
            while( READ32( GMAC_AUX1 ) & GM_DREQB )
                if( ++data1 == 1000 )
                {
                    PBM_free( hPkt );
                    FatalError=1;
                    goto RxExit;
                }
            data1 = READ32( GMAC_RRD );
            data2 = READ32( GMAC_RRD );
            data3 = READ32( GMAC_RRD );
            data4 = READ32( GMAC_RRD );
            *pibuf++ = data1;
            *pibuf++ = data2;
            *pibuf++ = data3;
            *pibuf++ = data4;
            tlen -= 16;
        }

        PBMQ_enq( &PBMQ_rx, hPkt );

        RxState = STATE_IDLE;
        return(1);
    }

RxExit:
    RxState = STATE_IDLE;
    return(0);
}

//--------------------------------------------------------------------
// gmIsr()
//
// General purpose ISR function. Here we will signal the
// scheduler that a packet is available on GMAC, or if the only
// message it a TX completion, we'll start the next send.
//--------------------------------------------------------------------
static void gmIsr()
{
    uint flags,NeedEvent = 0;
    uint data1,data2;
    PDINFO *pi;

    // Normally we would have to associate a PDINFO structure
    // with the device that fired this interrupt. Here though,
    // we only support one device, so we just set it to our global.
    pi = pGMI;

    do
    {
        // Read the interrupt flags and ACK
        flags = READ32( GMAC_ISR ) & 0xFF00;

        // Check for new Rx packet
        while( !FatalError && RxState == STATE_IDLE )
        {
            data1 = READ32(GMAC_RXRING1) >> 16;
            data2 = READ32(GMAC_RXRING2) & 0xFFFF;
            if( data1 == data2 )
                break;

            RxState = STATE_DMA;
            NeedEvent |= gmRxPacket();
        }

        // Check for Tx Complete
        if( TxState==STATE_SEND && !(READ32(GMAC_CONTROL)&(GM_ST0|GM_ST1)) )
        {
            TxState = STATE_IDLE;
            if( PBMQ_count(&pi->PBMQ_tx) )
                HwPktTxNext( pi );
            else
                pi->TxFree = 1;
        }

        WRITE32( GMAC_ISR, ( 0x00000000 | flags | INTMASK ) );
    } while( flags );

        // Notify we have a packet
    if( NeedEvent )
    {
        FlashActiveLED = 1;
        STKEVENT_signal( pi->hEvent, STKEVENT_ETHERNET, 1 );
    }
}

⌨️ 快捷键说明

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