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

📄 dm9ks_ucos.c

📁 硬件设计LPC2138+DM9000AE
💻 C
📖 第 1 页 / 共 2 页
字号:




#include "dm9ks.h"
#include "netif.h"
#include "eth.h"
#include "dm9ks_ucos.h"
//#include "define.h"

#define	DM9000AE_INT_HI		/* interrupt polarity high active */
#define LEDMODE1		
#define DM9008AE
#define DM9KS_BYTE_MODE		2
#define DM9KS_WORD_MODE		0
#define DM9KS_DWORD_MODE    1
#define NUM_MAX_NETBUF      32

#define TRUE			1
#define FALSE			0

typedef unsigned char u8;
typedef unsigned long u32;

#define DM9KS_ID		0x90000A46
#define DM9010_ID		0x90100A46
/*-------register name-----------------------*/
#define DM9KS_NCR		0x00	/* Network control Reg.*/
#define DM9KS_NSR		0x01	/* Network Status Reg.*/
#define DM9KS_TCR		0x02	/* TX control Reg.*/
#define DM9KS_TSRI		0x03
#define DM9KS_TSRII		0x04
#define DM9KS_RXCR		0x05	/* RX control Reg.*/
#define DM9KS_RSR		0x06
#define DM9KS_ROCR		0x07
#define DM9KS_BPTR		0x08
#define DM9KS_FCTR		0x09
#define DM9KS_FCR		0x0a
#define DM9KS_EPCR		0x0b
#define DM9KS_EPAR		0x0c
#define DM9KS_EPDRL		0x0d
#define DM9KS_EPDRH		0x0e
#define DM9KS_WCR		0x0f
#define DM9KS_GPCR		0x1e
#define DM9KS_GPR		0x1f	/* General purpose register */
#define DM9KS_TRPAL		0x22
#define DM9KS_TRPAH		0x23
#define DM9KS_RWPAL		0x24
#define DM9KS_RWPAH		0x25
#define DM9KS_VID_L		0x28
#define DM9KS_VID_H		0x29
#define DM9KS_PID_L		0x2A
#define DM9KS_PID_H		0x2B
#define DM9KS_CHIPR		0x2C
#define DM9KS_TCR2		0x2d
#define DM9KS_OCR		0x2E
#define DM9KS_SMCR		0x2f 	/* Special Mode Control Reg.*/
#define DM9KS_ETXCSR	0x30	/* Early Transmit control/status Reg.*/
#define	DM9KS_TCCR		0x31	/* Checksum cntrol Reg. */
#define DM9KS_RCSR		0x32	/* Receive Checksum status Reg.*/
#define DM9KS_MPAR		0x33
#define DM9KS_LEDCR		0x34
#define DM9KS_BUSCR		0x38
#define DM9KS_INTCR		0x39
#define DM9KS_SCCR		0x50
#define DM9KS_RSCCR		0x51
#define DM9KS_MRCMDX	0xf0
#define DM9KS_MRCMDX1	0xf1
#define DM9KS_MRCMD		0xf2
#define DM9KS_MDRAL		0xf4
#define DM9KS_MDRAH		0xf5
#define DM9KS_MWCMDX	0xf6
#define DM9KS_MWCMD		0xf8
#define DM9KS_MWRL		0xfa
#define DM9KS_MWRH		0xfb
#define DM9KS_TXPLL		0xfc
#define DM9KS_TXPLH		0xfd
#define DM9KS_ISR		0xfe
#define DM9KS_IMR		0xff
/*---------------------------------------------*/
#define DM9KS_REG05		0x30	/* SKIP_CRC/SKIP_LONG */ 
#define DM9KS_REGFF		0x83	/* IMR */
#define DM9KS_DISINTR		0x80

#define DM9KS_PHY		0x40	/* PHY address 0x01 */
#define DM9KS_PKT_RDY		0x01	/* Packet ready to receive */

#define DM9KS_RX_INTR		0x01
#define DM9KS_TX_INTR		0x02
#define DM9KS_LINK_INTR		0x20
#define iobase	0x01200000
#define iodata	0x01200008

extern int OK;
extern int ERR;
extern int Recv;
extern int DEBUG_OUT();
extern int netbuf_alloc();


extern struct NETBUF netbuf[NUM_MAX_NETBUF];
extern struct DM_NETIF netif;


void delay_1us (u32 dly)
{
  u32 i;
  for(;dly>0;dly--)
     for(i=0;i<50000;i++); 
}
/* Global variable declaration ----------------------------- */
/*static int dmfe_debug = 0;*/
//static struct net_device * dmfe_dev = NULL;

/* For module input parameter */
static int media_mode = DM9KS_AUTO;

/* function declaration ------------------------------------- */
int dmfe_open(void);
//void dmfe_tx_done(unsigned long);
void dmfe_packet_receive(void);
int dmfe_stop(void);

//void dmfe_timer(unsigned long);
void dmfe_init_dm9000(void);
//unsigned long cal_CRC(unsigned char *, unsigned int, u8);
u8 ior(u8, u32);
void iow(u8, u8);
u16 phy_read(u8);
void phy_write(u8, u16);
u16 read_srom_word(u8);
void dm9000_hash_table(void);
//static void dmfe_timeout(struct net_device *);
//static void dmfe_reset(struct net_device *);

#if defined(CHECKSUM)
static u8 check_rx_ready(u8);
#endif


static int queue_pkt_len;

//DECLARE_TASKLET(dmfe_tx_tasklet,dmfe_tx_done,0);

/* DM9000 network baord routine ---------------------------- */

/*
  Open the interface.
  The interface is opened whenever "ifconfig" actives it.
*/


void delay_1ms(u32 no)
{
u32 i;

	for(i=0;i<1000;i++)
	{
		delay_1us(1000);
	}
}

#define udelay delay_1us


////////////////////////////////////////////////////////////////////////////////////////////////////////////////	

void outb(u8 reg, u32 addr){

	*(volatile u8 *)addr = reg;
}

void outw(u16 reg, u32 addr){ 

	*(volatile u16 *)addr = reg;
}

void outl(u32 reg, u32 addr){ 

	*(volatile u32 *)addr = reg;
}
/**/


u8 inb(u32 addr){

	return (u8)(*(volatile u8 *)addr);
}

u16 inw(u32 addr){

	return (u16)(*(volatile u16 *)addr);
}

u32 inl(u32 addr){

	return (u32)(*(volatile u32 *)addr);
}/**/

////////////////////////////////////////////////////////////////////////////////////////////////////////////////


	
int dmfe_open(void)
{
u32 id_val;

	netif.io_addr = iobase;
	netif.io_data = iodata;
	
	outb(DM9KS_VID_L, netif.io_addr);
	id_val = inb(netif.io_data);
	outb(DM9KS_VID_H, netif.io_addr);
	id_val |= inb(netif.io_data) << 8;
	outb(DM9KS_PID_L, netif.io_addr);
	id_val |= inb(netif.io_data) << 16;
	outb(DM9KS_PID_H, netif.io_addr);
	id_val |= inb(netif.io_data) << 24;
	
	DEBUG_OUT("  <DM9KS> I/O: 0x%x, VID: 0x%x \r\n\r\n",netif.io_addr, id_val);
	
	if (id_val == DM9KS_ID || id_val == DM9010_ID) 
	{
	
		/* Initilize DM9000A board */
		dmfe_init_dm9000();
 
		/* Init driver variable */
		netif.reset_counter 	= 0;
		netif.reset_tx_timeout 	= 0;
		
		if (phy_read(0) & 0x2000)
			netif.Speed = 100;
		else 
			netif.Speed = 10;
				
		return OK;
	}else{
		DEBUG_OUT("\r\n************ERROR! NO Davicom NIC!\r\n");	
		return ERR;
	}
}

/* Set PHY operationg mode
*/
void set_PHY_mode()
{

	u16 phy_reg0 = 0x1200;		/* Auto-negotiation & Restart Auto-negotiation */
	u16 phy_reg4 = 0x01e1;		/* Default flow control disable*/

	if ( !(netif.op_mode & DM9KS_AUTO) ) // op_mode didn't auto sense */
	{ 
		switch(netif.op_mode) {
			case DM9KS_10MHD:
					phy_reg4 = 0x21;	phy_reg0 = 0x1000;
				break;
			case DM9KS_10MFD:
					phy_reg4 = 0x41;	phy_reg0 = 0x1100;
				break;
			case DM9KS_100MHD:
					phy_reg4 = 0x81;	phy_reg0 = 0x3000;
				break;
			case DM9KS_100MFD:
					phy_reg4 = 0x101;	phy_reg0 = 0x3100;
				break;
			default: 
				break;
		} // end of switch
	
	} // end of if
	

	phy_write(0, phy_reg0);
	phy_write(4, phy_reg4);	
}

/* 
	Initilize dm9000 board
*/
void dmfe_init_dm9000(void)
{
//	DEBUG_OUT("dmfe_init_dm9000() --->");
	
	iow(DM9KS_GPR, 1); 	/* Power-Down PHY */
	udelay(2000);
	
	/* set the internal PHY power-on, GPIOs normal, and wait 2ms */
	iow( DM9KS_GPR, 0);	/* GPR (reg_1Fh)bit GPIO0=0 pre-activate PHY */
	udelay(2000);		/* wait 2ms for PHY power-on ready */

	/* do a software reset and wait 20us */
	iow( DM9KS_NCR, 3);
	udelay(20);		/* wait 20us at least for software reset ok */
	iow( DM9KS_NCR, 3);	/* NCR (reg_00h) bit[0] RST=1 & Loopback=1, reset on. Added by SPenser */
	udelay(20);		/* wait 20us at least for software reset ok */

	/* I/O mode */
	netif.io_mode = ior( DM9KS_ISR, netif.io_addr) >> 6; /* ISR bit7:6 keeps I/O mode */

	DEBUG_OUT("\r\n  io_mode = 0x%x \r\n",netif.io_mode);
	/* Set PHY */
	
	netif.op_mode = media_mode;
	set_PHY_mode();

	/* Program operating register */
	iow(DM9KS_NCR, 0);
	iow(DM9KS_TCR, 0);		/* TX Polling clear */
	
#if defined(LEDMODE1)
	iow(DM9KS_TCR2, 0x80);	/* LED mode */
#endif

	iow(DM9KS_BPTR, 0x3f);	/* Less 3kb, 600us */
	iow(DM9KS_SMCR, 0);		/* Special Mode */
	iow(DM9KS_NSR, 0x2c);	/* clear TX status */

#if defined(DM9000AE_INT_HI)			/* interrupt high active */
	iow(DM9KS_INTCR, 0x00);
#else
	iow(DM9KS_INTCR, 0x01);
#endif
	
	iow(DM9KS_ISR, 0x0f); 	/* Clear interrupt status */
	
	/* Added by jackal at 03/29/2004 */
#if defined(CHECKSUM)
	iow( DM9KS_TCCR, 0x07);	/* TX UDP/TCP/IP checksum enable */
	iow( DM9KS_RCSR, 0x02);	/* Receive checksum enable */
#endif

#if defined(ETRANS)
	iow(netif, DM9KS_ETXCSR, 0x83);
#endif

	/* Set address filter table */
	dm9000_hash_table();

	/* Activate DM9000A/DM9010 */
	iow(DM9KS_RXCR, DM9KS_REG05 | 1);	/* RX enable */
	iow(DM9KS_IMR, DM9KS_REGFF); 	// Enable TX/RX interrupt mask
 
 
	/* Init Driver variable */
	netif.tx_pkt_cnt = 0;
	
	netif.tx_packets = 0;
	netif.tx_bytes = 0;
	netif.rx_fifo_errors = 0;
	netif.rx_crc_errors = 0;
	netif.rx_length_errors = 0;
	netif.rx_packets = 0;
	netif.rx_bytes = 0;
	
	netif.reset_counter = 0;
	netif.reset_tx_timeout = 0;
	
	netif.ip_crc_err = 0;
	netif.tcp_crc_err = 0;
	netif.udp_crc_err = 0;
	netif.num = 0;
	
//	netif_carrier_on(dev);
//	spin_lock_init(&netif.lock);

}

/*
  Hardware start transmission.
  Send a packet to media from the upper layer.
*/
//static int dmfe_start_xmit(struct sk_buff *skb, struct net_device *dev)
int dmfe_start_xmit(char * pdata, u16 len)
{
	
	char * data_ptr;
	int i, tmplen;
	
	if(netif.Speed == 10)
		{if (netif.tx_pkt_cnt >= 1) return ERR;}
	else
		{if (netif.tx_pkt_cnt >= 2) return ERR;}

	/* Disable all interrupt */
	iow( DM9KS_IMR, DM9KS_DISINTR);

	/* Move data to TX SRAM */
	data_ptr = (char *)pdata;
	
	outb(DM9KS_MWCMD, netif.io_addr); /* Write data into SRAM trigger */
	
	switch(netif.io_mode)
	{
		case DM9KS_BYTE_MODE:
			for (i = 0; i < len; i++)
				outb((data_ptr[i] & 0xff), netif.io_data);
			break;
		case DM9KS_WORD_MODE:
			tmplen = (len + 1) / 2;
			for (i = 0; i < tmplen; i++)
				outw(((u16 *)data_ptr)[i], netif.io_data);
         		break;
         	case DM9KS_DWORD_MODE:
         		tmplen = (len + 3) / 4;			
			for (i = 0; i< tmplen; i++)
				outl(((u32 *)data_ptr)[i], netif.io_data);
			break;
	}
	
	if(netif.tx_pkt_cnt==0)
	{
	
		/* Set TX length to reg. 0xfc & 0xfd */
		iow( DM9KS_TXPLL, (len & 0xff));
		iow( DM9KS_TXPLH, (len >> 8) & 0xff);
	
#if !defined(ETRANS)
		/* Issue TX polling command */
		iow( DM9KS_TCR, 0x1); /* Cleared after TX complete*/
#endif

		netif.tx_packets++;
		netif.tx_bytes+=len;

	}else{
		/* Second packet */
		queue_pkt_len = len;
	}
	
	/* packet counting */
	netif.tx_pkt_cnt++;
	

⌨️ 快捷键说明

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