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

📄 mxf.c

📁 dm642网络传输程序
💻 C
📖 第 1 页 / 共 3 页
字号:
//--------------------------------------------------------------------------
// IP Stack
//--------------------------------------------------------------------------
// mxf.c
//
// Macronix 98728 Packet Driver - Full Duplex EDMA Version
// *** CSL Compatible 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_edma.h>
#include <csl_cache.h>
#include "llpacket.h"
#include "mx.h"

//
// Static slots to hold our EDMA handle, event value, and
// TX and RX option register settings.
//
static EDMA_Handle hEDMA_tx;
static EDMA_Handle hEDMA_rx;
static EDMA_Handle hEDMA_rxControl;
static EDMA_Handle hEDMA_rld;
#if EDMA_FS_TP1
static EDMA_Handle hEDMA_tp1;
#endif
static int         EdmaTxEvent;
static int         EdmaRxEvent;
static UINT32      EdmaOptRx;
static UINT32      EdmaRldAddr;     // 16 LSB's of reload addr

//
// 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();
static void gmIsrEDMATx(int arg);
static void gmIsrEDMARx(int arg);

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

//
// Static data needed in EDMA ISR
//
static UINT32     DMAData1,DMAData2,DMAData3;
static PBM_Handle hDMARxPkt = 0;
static PBM_Handle hDMATxPkt = 0;

// 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;
static 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;
    int         tmp;
    UINT32      EdmaOptTx;
#if EDMA_FS_TP1
    UINT32      EdmaOptTp;
#endif

    // 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 )
    {
        //
        // In order to remain compatible with CSL, we will allocate
        // our DMA channels and completion events.
        //

        //
        // First, we must be able to get EDMA channels 4 and 5. Since
        // our hardware uses EXTINT4 and EXTINT5, these channels should
        // not be required by any other device.
        //
        hEDMA_tx = EDMA_open( EDMA_TXCHANNEL, EDMA_OPEN_RESET );
        if( hEDMA_tx == EDMA_HINV )
            return(0);
#if EDMA_FS_INT
        hEDMA_rx = EDMA_open( EDMA_RXCHANNEL, EDMA_OPEN_RESET );
        if( hEDMA_rx == EDMA_HINV )
            return(0);
        // Framesync Drives RXCHANNEL
        hEDMA_rxControl = hEDMA_rx;
#endif
        //
        // When using TP1, we need our RX channel, plus the TP channel
        // to control the clock count
        //
#if EDMA_FS_TP1
        hEDMA_rx = EDMA_open( EDMA_RXCHANNEL, EDMA_OPEN_RESET );
        if( hEDMA_rx == EDMA_HINV )
            return(0);
        hEDMA_tp1 = EDMA_open( EDMA_TPCHANNEL, EDMA_OPEN_RESET );
        if( hEDMA_tp1 == EDMA_HINV )
            return(0);
        // Framesync Drives TPCHANNEL
        hEDMA_rxControl = hEDMA_tp1;
#endif

        //
        // Next, we need a single EDMA reload area. Allocate it now.
        // We'll get one off the bottom so we won't conflict with any
        // code that just assumes it can use the top entries.
        //
        tmp = EDMA_TABLE_CNT-1;
        do
        {
            hEDMA_rld = EDMA_allocTable( tmp );
            tmp--;
        } while( hEDMA_rld == EDMA_HINV && tmp >= 0 );
        if( hEDMA_rld == EDMA_HINV )
            return(0);
        EdmaRldAddr = EDMA_getTableAddress( hEDMA_rld ) & 0xffff;

        //
        // Finally, allocate some completion events. We'll try for
        // events corresponding to our channela
        //
        if( (EdmaTxEvent = EDMA_intAlloc(EDMA_TXCHANNEL)) < 0 )
            EdmaTxEvent = EDMA_intAlloc(-1);
#if EDMA_FS_INT
        if( (EdmaRxEvent = EDMA_intAlloc(EDMA_RXCHANNEL)) < 0 )
            EdmaRxEvent = EDMA_intAlloc(-1);
#endif
        //
        // When using TP1, we must have TCC8, and we'll ask for TP channel
        //
#if EDMA_FS_TP1
        if( (EdmaRxEvent = EDMA_intAlloc(EDMA_TPCHANNEL)) < 0 )
            EdmaRxEvent = EDMA_intAlloc(-1);
        if( (tmp = EDMA_intAlloc(EDMA_RXCHANNEL)) < 0 )
            return(0);
#endif

        if( EdmaTxEvent<0 || EdmaRxEvent<0 )
            return(0);

        //
        // Now initialize the Macronix device
        //
        pGMI = pi;
        gmInitialize();

        // Configure the interrupts

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

#if EDMA_FS_INT
        // Set EDMA RX interrupt polarity to falling edge
        imanSetExtPolarity(HW_FSIVAL,MX_EXTINT_POLARITY);
#endif

#if (!C64_SUPPORT)
        EdmaOptTx = EDMA_OPT_RMK( EDMA_OPT_PRI_LOW,
                                  EDMA_OPT_ESIZE_32BIT,
                                  EDMA_OPT_2DS_NO,
                                  EDMA_OPT_SUM_INC,
                                  EDMA_OPT_2DD_NO,
                                  EDMA_OPT_DUM_NONE,
                                  EDMA_OPT_TCINT_YES,
                                  EdmaTxEvent,
                                  EDMA_OPT_LINK_NO,
                                  EDMA_OPT_FS_YES );

        EdmaOptRx = EDMA_OPT_RMK( EDMA_OPT_PRI_HIGH,
                                  EDMA_OPT_ESIZE_32BIT,
                                  EDMA_OPT_2DS_NO,
                                  EDMA_OPT_SUM_NONE,
                                  EDMA_OPT_2DD_NO,
                                  EDMA_OPT_DUM_INC,
                                  EDMA_OPT_TCINT_YES,
                                  EdmaRxEvent,
                                  EDMA_OPT_LINK_YES,
                                  EDMA_OPT_FS_YES );

#if EDMA_FS_TP1
        EdmaOptTp = EDMA_OPT_RMK( EDMA_OPT_PRI_HIGH,
                                  EDMA_OPT_ESIZE_32BIT,
                                  EDMA_OPT_2DS_NO,
                                  EDMA_OPT_SUM_NONE,
                                  EDMA_OPT_2DD_NO,
                                  EDMA_OPT_DUM_NONE,
                                  EDMA_OPT_TCINT_YES,
                                  EDMA_RXCHANNEL,
                                  EDMA_OPT_LINK_NO,
                                  EDMA_OPT_FS_YES );
#endif
#endif

#if (C64_SUPPORT)
        EdmaOptTx = EDMA_OPT_RMK( EDMA_OPT_PRI_LOW,
                                  EDMA_OPT_ESIZE_32BIT,
                                  EDMA_OPT_2DS_NO,
                                  EDMA_OPT_SUM_INC,
                                  EDMA_OPT_2DD_NO,
                                  EDMA_OPT_DUM_NONE,
                                  EDMA_OPT_TCINT_YES,
                                  (EdmaTxEvent&0xf),
                                  (EdmaTxEvent>>4),
                                  EDMA_OPT_ATCINT_NO,
                                  0,
                                  EDMA_OPT_PDTS_DISABLE,
                                  EDMA_OPT_PDTD_DISABLE,
                                  EDMA_OPT_LINK_NO,
                                  EDMA_OPT_FS_YES );

        EdmaOptRx = EDMA_OPT_RMK( EDMA_OPT_PRI_HIGH,
                                  EDMA_OPT_ESIZE_32BIT,
                                  EDMA_OPT_2DS_NO,
                                  EDMA_OPT_SUM_NONE,
                                  EDMA_OPT_2DD_NO,
                                  EDMA_OPT_DUM_INC,
                                  EDMA_OPT_TCINT_YES,
                                  (EdmaRxEvent&0xf),
                                  (EdmaRxEvent>>4),
                                  EDMA_OPT_ATCINT_NO,
                                  0,
                                  EDMA_OPT_PDTS_DISABLE,
                                  EDMA_OPT_PDTD_DISABLE,
                                  EDMA_OPT_LINK_YES,
                                  EDMA_OPT_FS_YES );

#if EDMA_FS_TP1
        EdmaOptTp = EDMA_OPT_RMK( EDMA_OPT_PRI_HIGH,
                                  EDMA_OPT_ESIZE_32BIT,
                                  EDMA_OPT_2DS_NO,
                                  EDMA_OPT_SUM_NONE,
                                  EDMA_OPT_2DD_NO,
                                  EDMA_OPT_DUM_NONE,
                                  EDMA_OPT_TCINT_YES,
                                  (EDMA_RXCHANNEL&0xf),
                                  (EDMA_RXCHANNEL>>4),
                                  EDMA_OPT_ATCINT_NO,
                                  0,
                                  EDMA_OPT_PDTS_DISABLE,
                                  EDMA_OPT_PDTD_DISABLE,
                                  EDMA_OPT_LINK_NO,
                                  EDMA_OPT_FS_YES );
#endif
#endif


        //
        // When using TP1, setup the clock configuration and
        // the clock EMDA.
        //
#if EDMA_FS_TP1
        // Setup the clock with a period of 2
        *(unsigned int*)_TIMER_CTL1_ADDR = 0x0;    // Disable clock
        *(unsigned int*)_TIMER_CNT1_ADDR = 0x0;    // Set count to zero
        *(unsigned int*)_TIMER_PRD1_ADDR = 0x2;    // Set period to 2

        // Clock Events EMDA and resets count to 1 on interrupt

        // Src = Address of CNT reg which will always be "1"
        // Dst = Clock count register
        EDMA_RSETH(hEDMA_tp1,OPT,EdmaOptTp);
        EDMA_RSETH(hEDMA_tp1,SRC,EDMA_ADDRH(hEDMA_tp1,CNT));
        EDMA_RSETH(hEDMA_tp1,CNT,1);
        EDMA_RSETH(hEDMA_tp1,DST,_TIMER_CNT1_ADDR);
        EDMA_RSETH(hEDMA_tp1,IDX,0);
        EDMA_RSETH(hEDMA_tp1,RLD,0);

        EDMA_clearChannel(hEDMA_rx);
        EDMA_enableChaining(hEDMA_rx);
#endif

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

        // Disable EDMA channels from event triggering
        EDMA_disableChannel(hEDMA_tx);
        EDMA_disableChannel(hEDMA_rxControl);

        // Setup some Tx EDMA fields
        EDMA_RSETH(hEDMA_tx,OPT,EdmaOptTx);
        EDMA_RSETH(hEDMA_tx,DST,GMAC_WRTXFIFOD);
        EDMA_RSETH(hEDMA_tx,IDX,0);
        EDMA_RSETH(hEDMA_tx,RLD,0);

        // Clear our interrupts
        EDMA_intClear( EdmaTxEvent );
        EDMA_intClear( EdmaRxEvent );

        // Hook our event interrupts
        EDMA_intHook( EdmaTxEvent, gmIsrEDMATx );
        EDMA_intHook( EdmaRxEvent, gmIsrEDMARx );

        // Enable our interrupts
        EDMA_intEnable( EdmaTxEvent );
        EDMA_intEnable( EdmaRxEvent );

        // Setup Dead-Man Link in DMA Space
        EDMA_RSETH(hEDMA_rld,OPT,0);

⌨️ 快捷键说明

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