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

📄 lan91c111.c

📁 CS8900测试文件(整个工程) 环境:VDSP4.0
💻 C
📖 第 1 页 / 共 4 页
字号:
/*********************************************************************************

Copyright(c) 2004 Analog Devices, Inc. All Rights Reserved. 

This software is proprietary and confidential.  By using this software you agree
to the terms of the associated Analog Devices License Agreement.  



*********************************************************************************/

// USE_16BIT has to be defined since the transmitable data will start on a half word boundary

#define USE_16_BIT 

#ifdef __ADSPBF535__
#include <cdefbf535.h>
#endif /* __ADSPBF535__ */

#ifdef __ADSPBF533__
#include <cdefbf533.h>
#endif  /* __ADSPBF533__ */

#include <string.h>
#include <sys/exception.h>
#include <services/services.h>
#include <drivers/adi_dev.h>
#include <services/adi_dcb.h>
#include <services/adi_dma.h>
#include <services/adi_int.h>
#include <services/adi_ebiu.h>
#include "lan91c111.h"
#include "io_sprt.h"
#include "cs8900a.h"
#include <ADI_ETHER_USBLAN.h>
#include "stdio.h"
#include "vdk.h"

// Acknowledge the LAN interrupt by clearing associated PF 
//
#define ACK_LAN_INT(pf) ((*pFIO_FLAG_C = pf))
#define MAX_RCVE_FRAME 1560

static void *CriticalHandle;

#define ENTER_CRITICAL_REGION() (CriticalHandle=adi_int_EnterCriticalRegion(dev->CriticalData))
#define EXIT_CRTICIAL_REGION()  (adi_int_ExitCriticalRegion(CriticalHandle)) 

#define LAN91C111_LOG_NET_ERRORS 1

/* The transmission attempt failed due to lack of memory - so queue and retry next time */
#define LAN91C111_TX_RETRY     1
/* The transmission attempt is an unrecoverable error - free the packet, drop it */
#define LAN91C111_TX_ERROR     2
/* The transmission attempt completed successfully */
#define LAN91C111_TX_SUCCESS   3

/* global static data */
static ADI_ETHER_LAN91C111_DATA EtherDev={0};

/* function prototypes */
int StartMac(ADI_ETHER_LAN91C111_DATA *dev);
int SetDevicePFConfig (ADI_ETHER_LAN91C111_DATA *dev);
int QueueNewRcvFrames (ADI_ETHER_LAN91C111_DATA *dev,ADI_ETHER_BUFFER *bufs);
int QueueNewXmtFrames (ADI_ETHER_LAN91C111_DATA *dev,ADI_ETHER_BUFFER *bufs);
ADI_ETHER_LAN91C111_DATA *dev_g;
int ping=0;
#include <cycle_count_bf.h>





//#define _ADI_DEBUG_LWIP
#define  net_device _ADI_ETHER_LAN91C111_DATA
#ifdef _ADI_DEBUG_LWIP
#define ADI_G(x) (printf x)
#else
#define ADI_G(x)
#endif
//#include "..\..\cs8900a.h"
//#include "drivers\lan91c111\lan91c111.h"

#define  net_device _ADI_ETHER_LAN91C111_DATA
#include <cplbtab.h> 

#define BASE 0x20300000

#define CS89X0_ALLOC_IDLE 0
#define CS89X0_ALLOC_SUCE 1
#define CS89X0_ALLOC_WAIT 2

inline int readreg(struct net_device *dev, int portno);
inline void writereg(struct net_device *dev, int portno, int value) ;
inline int readword(struct net_device *dev, int portno);
inline void writeword(struct net_device *dev, int portno, int value);
inline void writeblock(struct net_device *dev, char *pData, int Length);
inline void readblock(struct net_device *dev, char *pData, int Length);

inline short inw(int addr);

int net_open(struct net_device *dev);
void cs8900a_probe(struct net_device *dev);

extern ADI_ETHER_BUFFER *rcv_list,*xmt_list;

static void ker_msec(void)
{
	unsigned long long int cur,nd;
	
	_GET_CYCLE_COUNT(cur);
	
	nd = cur + (__PROCESSOR_SPEED__/1000);
	while (cur < nd) {
		_GET_CYCLE_COUNT(cur);
	}
	
}

static int smsc_sleep(unsigned int msec)
{
	while (msec != 0) {
		ker_msec();
		msec--;
	}
	return 0;
}

#pragma optimize_off
/****************************************************************************
 *  Read register from EEPROM
 ****************************************************************************/
static int eeprom_read_reg(int reg_no)
{
	int timeout;
	
	// select bank 2
	_outpw(BSR_REG, 2);
	_outpw(PTR_REG,reg_no);

	// select bank 1
   _outpw(BSR_REG, 1); 
   _outpw(CTL_REG,_inpw(CTL_REG) | CTL_EEPROM_SELECT | CTL_RELOAD);
  
   timeout = 100;
   while((_inpw(CTL_REG) & CTL_RELOAD) && --timeout)
   {
	   int t=10000;
	   while(t>0)
		   t--;
   }
   // error in reading from eeprom
   if(timeout == 0)
	   return -1;

   return(_inpw(GP_REG));
}

/****************************************************************************
 *  Write register to EEPROM
 ****************************************************************************/
static int eeprom_write_reg(int reg_no, int val)
{
	int timeout;
	// select bank 2
	_outpw(BSR_REG, 2);
	_outpw(PTR_REG,reg_no);

	// select bank 1
   _outpw(BSR_REG, 1); 
   _outpw(GP_REG, val); 
   _outpw(CTL_REG,_inpw(CTL_REG) | CTL_EEPROM_SELECT | CTL_STORE);

   timeout = 100;
   while((_inpw(CTL_REG) & CTL_STORE) && --timeout)
   {
	   int t=10000;
	   while(t>0)
		   t--;
   }
   // error in reading from eeprom
   if(timeout == 0)
	   return -1;
   return 1;
}

/******************************************************************************
 * Set MAC address in the SMSC  
 *****************************************************************************/
static void set_mac_in_SMSC(const char* mac_addr)
{
   unsigned short page;
   short wtmp;

   // save old page
   page = _inpw(BSR_REG);

   // select bank 1
   _outpw(BSR_REG, 1); 
   
   // Set EEPROM Store
   _outpw(CTL_REG,CTL_EEPROM_SELECT | CTL_STORE);
       
    wtmp = (((mac_addr[1])<<8)|(mac_addr[0]));
    _outpw(ADDR0_REG, wtmp);
    wtmp = (((mac_addr[3])<<8)|(mac_addr[2]));
    _outpw(ADDR1_REG, wtmp);
    wtmp = (((mac_addr[5])<<8)|(mac_addr[4]));
    _outpw(ADDR2_REG, wtmp); 
        
   // restore bank
   _outpw(BSR_REG, page);
    
   return;
}

/******************************************************************************
 * Get MAC address From the SMSC  
 *****************************************************************************/
static void get_mac_frm_SMSC(char* mac_addr)
{
	volatile unsigned short addr;
	volatile unsigned short page;
	page = _inpw(BSR_REG);

	_outpw(BSR_REG, 1);
	addr = _inpw(ADDR0_REG); // get MAC addr
	mac_addr[0] = addr & 0xFF;
	mac_addr[1] = addr >> 8;

	addr = _inpw(ADDR1_REG); // get MAC addr
	mac_addr[2] = addr & 0xFF;
	mac_addr[3] = addr >> 8;

	addr = _inpw(ADDR2_REG); // get MAC addr
	mac_addr[4] = addr & 0xFF;
	mac_addr[5] = addr >> 8;
	_outpw(BSR_REG, page);
	return;
}

/******************************************************************************
 * Get MAC address From the EEPROM  
 *****************************************************************************/
static void set_mac_in_EEPROM(const char* mac_addr)
{
   unsigned short page;
   short wtmp;

   // save old page
   page = _inpw(BSR_REG);

    wtmp = (((mac_addr[1])<<8)|(mac_addr[0]));
	eeprom_write_reg(0x20,wtmp);
    wtmp = (((mac_addr[3])<<8)|(mac_addr[2]));
    eeprom_write_reg(0x21, wtmp);
    wtmp = (((mac_addr[5])<<8)|(mac_addr[4]));
    eeprom_write_reg(0x22, wtmp);
        
   // restore bank
   _outpw(BSR_REG, page);
    
   return;
}
/******************************************************************************
 * Get MAC address From the EEPROM  
 *****************************************************************************/
static void get_mac_frm_EEPROM(char* mac_addr)
{
	volatile unsigned short addr,i,val,j=0;
	volatile unsigned short page;
	page = _inpw(BSR_REG);

	// eeprom offset 20 has mac addr
	for(i=0x20;i<0x23;i++)
	{
		val = eeprom_read_reg(i);
		mac_addr[j++] = val & 0xff;
		mac_addr[j++] = val >> 8;
	}
	
	_outpw(BSR_REG, page);
	return;
}
/******************************************************************************
 *  Change the current IRQ mask
 *****************************************************************************/
static void LAN91C111_enable_int (unsigned char IRQ)
{
   volatile unsigned short page;

   // save old page
   page = _inpw(BSR_REG);
   // switch to bank 2
   _outpw(BSR_REG, 2);
   // update current mask
   _outp(IM_REG, _inp(IM_REG) | IRQ);
   // restore bank
   _outpw(BSR_REG, page);
   return;
}

/******************************************************************************
 *  Change the current IRQ mask
 *****************************************************************************/
static void LAN91C111_disable_int (unsigned char IRQ)
{
   volatile unsigned short page;
   volatile unsigned char mask;

   // save old page
   page = _inpw(BSR_REG);
   // switch to bank 2
   _outpw(BSR_REG, 2);
   // write new mask
   _outp(IM_REG, _inp(IM_REG) & ~IRQ);
   // restore bank
   _outpw(BSR_REG, page);
   return;
}

/******************************************************************************
 * Writes a word through the MII interface to the PHY
 *****************************************************************************/

static void LAN91C111_write_phy_register(unsigned char phyreg, unsigned short phydata)
{
   volatile int i;
   volatile unsigned short oldBank, wmask, mii_reg;
   volatile unsigned char bits[65], bmask;
   volatile int  clk_idx = 0;

   // Prepare bit stream for PHY
   // 32 consecutive ones on MDO to establish sync
   for (i = 0; i < 32; ++i)
      bits[clk_idx++] = MII_MDOE | MII_MDO;

   // Start code <01>
   bits[clk_idx++] = MII_MDOE;
   bits[clk_idx++] = MII_MDOE | MII_MDO;
   // Write command <01>
   bits[clk_idx++] = MII_MDOE;
   bits[clk_idx++] = MII_MDOE | MII_MDO;

   // Output the PHY address, msb first, internal PHY = 0
   bits[clk_idx++] = MII_MDOE;
   bits[clk_idx++] = MII_MDOE;
   bits[clk_idx++] = MII_MDOE;
   bits[clk_idx++] = MII_MDOE;
   bits[clk_idx++] = MII_MDOE;

   // Output the phy register number, msb first
   bmask = 0x10;
   for (i = 0; i < 5; ++i)
   {
      if (phyreg & bmask)
         bits[clk_idx++] = MII_MDOE | MII_MDO;
      else
         bits[clk_idx++] = MII_MDOE;
      // Shift to next lowest bit
      bmask >>= 1;
   }

   // Tristate and turnaround (2 bit times) <10>
   bits[clk_idx++] = MII_MDOE | MII_MDO;;
   bits[clk_idx++] = 0;

   // Write out 16 bits of data, msb first
   wmask = 0x8000;
   for (i = 0; i < 16; ++i)
   {
      if (phydata & wmask)
         bits[clk_idx++] = MII_MDOE | MII_MDO;
      else
         bits[clk_idx++] = MII_MDOE;
      // Shift to next lowest bit
      wmask >>= 1;
   }

   // Final clock bit (tristate)
   bits[clk_idx++] = 0;

   // Save the current bank
   oldBank = _inpw(BSR_REG);
   // Select bank 3
   _outpw(BSR_REG, 3);

   // Get the current MII register value
   mii_reg = _inpw(MII_REG);

   // Turn off all MII Interface bits
   mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO);

   // Clock all cycles
   for (i = 0; i < sizeof bits; ++i)
   {
      // Clock Low - output data
      _outpw(MII_REG, mii_reg | bits[i] );
      // Clock Hi - input data
      _outpw(MII_REG, mii_reg | bits[i] | MII_MCLK);
   }

   // Return to idle state
   // Set clock to low, data to low, and output tristated
   _outpw(MII_REG, mii_reg);

   // Restore original bank select
   _outpw(BSR_REG, oldBank );
   return;
}

/******************************************************************************
 * Reads a word through the MII interface off the PHY
 *****************************************************************************/
static unsigned short LAN91C111_read_phy_register(unsigned char phyreg)
{
   volatile unsigned char bits[64];
   volatile unsigned char bmask;
   volatile unsigned short oldBank, mii_reg, phydata, wmask;
   volatile int i, clk_idx = 0;
   volatile int input_idx;

   // Prepare bit stream for PHY
   // 32 consecutive ones on MDO to establish sync
   for (i = 0; i < 32; ++i)
      bits[clk_idx++] = MII_MDOE | MII_MDO;

   // Start code <01>
   bits[clk_idx++] = MII_MDOE;
   bits[clk_idx++] = MII_MDOE | MII_MDO;
   // Read command <10>
   bits[clk_idx++] = MII_MDOE | MII_MDO;
   bits[clk_idx++] = MII_MDOE;
   // internal PHY address = <00000>
   bits[clk_idx++] = MII_MDOE;
   bits[clk_idx++] = MII_MDOE;
   bits[clk_idx++] = MII_MDOE;
   bits[clk_idx++] = MII_MDOE;
   bits[clk_idx++] = MII_MDOE;

   // Output the phy register number, msb first
   bmask = 0x10;
   for (i = 0; i < 5; ++i)
   {
      if (phyreg & bmask)
         bits[clk_idx++] = MII_MDOE | MII_MDO;
      else
         bits[clk_idx++] = MII_MDOE;
      // Shift to next lowest bit
      bmask >>= 1;
   }

   // Tristate and turnaround (2 bit times)
   bits[clk_idx++] = 0;

   // Input starts at this bit time
   input_idx = clk_idx;

   // Will input 16 bits
   for (i = 0; i < 16; ++i)
      bits[clk_idx++] = 0;

   // Final clock bit
   bits[clk_idx++] = 0;

   // Save the current bank
   oldBank = _inpw(BSR_REG);
   // Select bank 3
   _outpw(BSR_REG, 3);

   // Get the current MII register value
   mii_reg = _inpw(MII_REG);

   // Turn off all MII Interface bits
   mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO);

   // Clock all 64 cycles
   for (i = 0; i < clk_idx /*sizeof bits*/; ++i)
   {

⌨️ 快捷键说明

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