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

📄 mxi.c

📁 dm642网络传输程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//--------------------------------------------------------------------------
// IP Stack
//--------------------------------------------------------------------------
// mxi.c
//
// Macronix 98728 Packet Driver - ISR Version
//
// Author: Michael A. Denio
// Copyright 2000, 2003 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <std.h>
#include <sys.h>
#include <sem.h>
#include <hwi.h>
#include <c62.h>
#include <stkmain.h>
#include <csl.h>
#include <csl_cache.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();
static void gmIsr();

//
// 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 (GM_RIM|GM_TIM)         // GMAC interrupts we care about

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

//--------------------------------------------------------------------
// imanSetExtPolarity()
//
// This function is used to set the interrupt detection
// polarity for the interrupts gernerated by GMAC
//--------------------------------------------------------------------
static void imanSetExtPolarity( int extintno, int polarity )
{
    if( polarity==EXTINT_POLARITY_LOWHIGH )
        *(volatile unsigned int*)0x19c0008 &= ~(1<<(extintno-4));
    else if( polarity==EXTINT_POLARITY_HIGHLOW )
        *(volatile unsigned int*)0x19c0008 |= (1<<(extintno-4));
}

//--------------------------------------------------------------------
// 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 )
{
    HWI_Attrs hwiattr;

    // 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();

        // Configure the interrupt

        // Set interrupt polarity for GP interrupt
        imanSetExtPolarity(HW_IVAL,MX_EXTINT_POLARITY);

        // Hook GP INT - Disable GP int inside ISR
        hwiattr.intrMask = HW_IFLAG;
        hwiattr.ccMask   = 1;
        hwiattr.arg      = 0;
        HWI_dispatchPlug( HW_IVAL, (Fxn)gmIsr, -1, &hwiattr );
        CACHE_invalidate( CACHE_L1PALL, 0, 0 );

        // Enable out general purpose interrupt
        C62_enableIER( HW_IFLAG );
    }

    // 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 mask,flags,data1,data2;

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

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

    // We can't have our polling interfere with the ISR
    // Disable GP interrupt
    mask = gmDisableIER( HW_IFLAG );

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

    // Ack any pending interrupt
    flags = READ32( GMAC_ISR ) & 0xFF00;
    if( flags )
    {
        ICR = HW_IFLAG;
        WRITE32( GMAC_ISR, ( 0x00000000 | flags | INTMASK ) );
    }

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

    gmEnableIER( mask );

    // Leave kernel mode
    llExit();
}

//--------------------------------------------------------------------
// 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;
    Delay(4);

    // Hard Reset
    WRITE32( GMAC_RESET_ON, 0 );
    Delay(4);
    WRITE32( GMAC_RESET_OFF, 0 );
    Delay(4);

    // Soft Reset
    WRITE32( GMAC_CONTROL, GM_RESET );
    Delay(3);

⌨️ 快捷键说明

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