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

📄 mxp.c

📁 dm642网络传输程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//--------------------------------------------------------------------------
// IP Stack
//--------------------------------------------------------------------------
// mxp.c
//
// Macronix 98728 Packet Driver - Polling Version
//
// Author: Michael A. Denio
// Copyright 2000, 2003 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <std.h>
#include <sys.h>
#include <sem.h>
#include <stkmain.h>
#include "llpacket.h"
#include "mx.h"

//
// We use the following direct access to registers
//
extern cregister volatile uint ICR;

//
// Declare our local functions
//
static void gmInitialize();
static void gmReset();
static void gmStart();
static void gmStop();
static void gmSendPacket( PBM_Handle hPkt );
static int  gmRxPacket();

//
// Current TX and RX state
//
#define STATE_IDLE     0
#define STATE_DMA      1
#define STATE_SEND     2
static volatile uint   TxState;
static volatile uint   RxState;

// Local instance information pointer for our single device instance
static PDINFO *pGMI = 0;

// Simple Tx and Rx statistics
uint RxGood = 0, RxBad = 0, TxPanic = 0;
uint FatalError = 0, FatalCount = 0;
uint FlashActiveLED = 0;

//
// Some quick equates
//
#define INTMASK 0                       // GMAC interrupts we care about

//
// Panic Buffer
//
#pragma DATA_ALIGN(pktPanicBuf, 128);
#pragma DATA_SECTION(pktPanicBuf, "PACKETMEM");
UINT8   pktPanicBuf[1536];

//--------------------------------------------------------------------
// Delay()
//
// Simple delay function
//--------------------------------------------------------------------
static void Delay(unsigned int t)
{
    volatile unsigned int i;
    while( t-- )
        for( i=0; i<(1600*HW_CLOCKRATE); i++);
}

//--------------------------------------------------------------------
// HwPktInit()
//
// Initialize Device environment and return instance count
//--------------------------------------------------------------------
uint HwPktInit()
{
    //
    // Note: This code supports only a single instance of the device
    //       Otherwise, we would do device detection here.
    //
    return(1);
}

//--------------------------------------------------------------------
// HwPktShutdown()
//
// Shutdown Device Environment
//--------------------------------------------------------------------
void HwPktShutdown()
{
}

//--------------------------------------------------------------------
// HwPktOpen()
//
// Open Device Instance
//--------------------------------------------------------------------
uint HwPktOpen( PDINFO *pi )
{
    // We only have one device, so store off the PDINFO pointer as
    // global to this module. Otherwise; we'd pick an unclaimed device
    // and associate it with the PDINFO.

    // IF pGMI is aleady set, this is a restart.
    if( !pGMI )
    {
        //
        // Now initialize the Macronix device
        //
        pGMI = pi;
        gmInitialize();
    }

    // Use the new PDINFO
    pGMI = pi;

    // Reset
    gmReset();

    // Read our MAC address
    *(UINT32 *)pi->bMacAddr = READ32( GMAC_ADDR1 );
    *(UINT16 *)(pi->bMacAddr+4) = (UINT16)(READ32( GMAC_ADDR2 ));

    // Start
    gmStart();

    return(1);
}

//--------------------------------------------------------------------
// HwPktClose()
//
// Close Device Instance
//--------------------------------------------------------------------
void HwPktClose( PDINFO *pi )
{
    (void)pi;
    // Normally we'd shut off the part, but here we'll only
    // stop it. This is because it can't handle a soft reset.
    gmStop();
}

//--------------------------------------------------------------------
// gmHashIndex()
//
// Calculate the Hash table index for one 6 byte address
//--------------------------------------------------------------------
#define POLY32 0x04c11db7
static unsigned int gmHashIndex( UINT8 *Address )
{
    unsigned int    Crc = 0xffffffff;
    unsigned int    Msb;
    unsigned char   Byte;
    int             ByteLen, Bit;

    for( ByteLen=0; ByteLen<6; ByteLen++ )
    {
        Byte = *Address++;
        for (Bit=0; Bit<8 ; Bit++)
        {
            Msb = Crc >> 31;
            Crc <<= 1;
            if( (Msb ^ (Byte>>Bit)) & 1 )
                Crc ^= POLY32;
        }
    }
    return( Crc>>26 );
}

//--------------------------------------------------------------------
// HwPktSetRx()
//
// Update Rx Mode (Rx filter and multicast hash table)
//--------------------------------------------------------------------
void HwPktSetRx( PDINFO *pi )
{
    UINT32 Addr[3];
    UINT32 control;
    uint   i,idx;

    //
    // Setup Multicast Table
    //

    // Read what we want to preserve
    Addr[0] = READ32( GMAC_ADDR2 );
    Addr[2] = READ32( GMAC_ADDR4 );

    // Clear all bits out of the hash table
    Addr[0] &= 0xFFFF;
    Addr[1] = 0;
    Addr[2] &= 0xFFFF0000;

    for( i=0; i<pi->MCastCnt; i++ )
    {
        idx = gmHashIndex( &(pi->bMCast[6*i]) );

        // Set the bit
        if( idx < 16 )
            Addr[0] |= 1 << ( idx + 16 );
        else if( idx < 48 )
            Addr[1] |= 1 << ( idx - 16 );
        else
            Addr[2] |= 1 << ( idx - 48 );
    }

    // Write the table back out
    WRITE32( GMAC_ADDR2, Addr[0] );
    WRITE32( GMAC_ADDR3, Addr[1] );
    WRITE32( GMAC_ADDR4, Addr[2] );

    //
    // Setup the Rx Filter
    //
    control = READ32( GMAC_CONTROL ) & 0xFFFF00FF;
    switch( pi->Filter )
    {
    case ETH_PKTFLT_NOTHING:
    case ETH_PKTFLT_DIRECT:
        break;

    case ETH_PKTFLT_BROADCAST:
    case ETH_PKTFLT_MULTICAST:
        control |= GM_AB;
        break;

    case ETH_PKTFLT_ALLMULTICAST:
        control |= GM_AB | GM_PM;
        break;

    case ETH_PKTFLT_ALL:
        control |= GM_PR;
        break;
    }

    WRITE32( GMAC_CONTROL, control );
}

//--------------------------------------------------------------------
// HwPktTxNext()
//
// Transmit Next Packet on Tx Queue
//--------------------------------------------------------------------
void HwPktTxNext( PDINFO *pi )
{
    PBM_Handle hPkt;

    // If not idle, ignore this call
    if( TxState != STATE_IDLE )
        return;

    // Make sure we have a packet to send
    if( !(hPkt = PBMQ_deq(&pi->PBMQ_tx)) )
    {
        pi->TxFree = 1;
        return;
    }

    // Mark as "not free"
    pi->TxFree = 0;

    // Send the packet
    gmSendPacket( hPkt );
}

//--------------------------------------------------------------------
// _HwPktPoll()
//
// Poll routine - CALLED OUTSIDE OF KERNEL MODE
//
// This function is called at least every 100ms, faster in a
// polling environment. The fTimerTick flag is set only when
// called on a 100ms event.
//--------------------------------------------------------------------
void _HwPktPoll( PDINFO *pi, uint fTimerTick )
{
    uint data1,data2,NeedEvent = 0;

    if( fTimerTick )
    {
        LED_TOGGLE( USER_LED2 );
        if( FlashActiveLED )
        {
            FlashActiveLED = 0;
            LED_TOGGLE( USER_LED3 );
        }
    }

    // Get into kernel mode to be safe
    llEnter();

    if( FatalError )
    {
        FatalCount++;
        gmStop();
        gmStart();
    }

    // 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;
    }

    // Leave kernel mode
    llExit();

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

}

//--------------------------------------------------------------------
// gmInitialize()
//
// Reset GMAC and clear its external memory
//--------------------------------------------------------------------
static void gmInitialize()
{
    int          i,j;
    unsigned int page;

    // EMIF control
    *HW_CE_REG = HW_CE_VALUE;

⌨️ 快捷键说明

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