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

📄 ne2kif.c

📁 ucos-lwip-c6x
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*********************************************************************************************************
*                                              lwIP TCP/IP Stack
*                                    	 port for uC/OS-II RTOS on TIC6711 DSK
*
* File : tcp_ip.c
* By   : ZengMing @ DEP,Tsinghua University,Beijing,China
* Reference: YangYe's source code for SkyEye project
*********************************************************************************************************
*/
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include <lwip/stats.h>

#include "netif/etharp.h"

#include "netif/ne2kif.h"

/* Define those to better describe your network interface. */
#define IFNAME0 'e'
#define IFNAME1 't'

#define		DELAY							0x590b2  //0.5s test by ming
#define		DELAY_2S						0xbf000  //2s test 
#define     DELAY_MS						0x38F4   //20ms test 	

struct ne2k_if {
  struct eth_addr *ethaddr; //MAC Address 
};

struct netif *ne2k_if_netif;   

static void low_level_init(struct netif * netif);
static err_t low_level_output(struct netif * netif,struct pbuf *p);
static struct pbuf * low_level_input(struct netif *netif);


/**
 * Initialize the ne2k ethernet chip, resetting the interface and getting the ethernet
 * address.
 */
static void low_level_init(struct netif * netif)
{
	u16_t i;
	
	struct ne2k_if *ne2k_if;
	
	ne2k_if = netif->state;
	// the meaning of "netif->state" can be defined in drivers, here for MAC address!
	
	netif->hwaddr_len=6;
	netif->mtu = 1500;	
  	netif->flags = NETIF_FLAG_BROADCAST;
  		
	// ---------- start -------------
	
    i = EN_RESET;//this instruction let NE2K chip soft reset

    for (i=0;i<DELAY_MS;i++); //wait

    EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP); 
    
    EN0_DCFG = (u8_t) 0x01;

    /* Clear the remote	byte count registers. */
    EN0_RCNTHI = (u8_t) 0x00; 								/* MSB remote byte count reg */
    EN0_RCNTLO = (u8_t) 0x00; 								/* LSB remote byte count reg */

	/* RX configuration reg    Monitor mode (no packet receive) */
	EN0_RXCR = (u8_t) ENRXCR_MON;
	/* TX configuration reg   set internal loopback mode  */
	EN0_TXCR = (u8_t) ENTXCR_LOOP;

    EN0_TPSR = (u8_t) 0x40;					//发送缓冲首地址 大小为6页,刚好是1个最大包
    										//为0x40-0x46 
    
    EN0_STARTPG = (u8_t) 0x46 ;					    /* 接收缓冲 47。Starting page of ring buffer. First page of Rx ring buffer 46h*/
    EN0_BOUNDARY = (u8_t) 0x46 ;						/* Boundary page of ring buffer 0x46*/
    EN0_STOPPG = (u8_t) 0x80 ;    					/* Ending page of ring buffer ,0x80*/

    EN0_ISR = (u8_t) 0xff; 								/* clear the all flag bits in EN0_ISR */
    EN0_IMR = (u8_t) 0x00; 								/* Disable all Interrupt */

    EN_CMD = (u8_t) (EN_PAGE1 + EN_NODMA + EN_STOP);
    EN1_CURR = (u8_t) 0x47; 							
    /* RX_CURR_PG; 47 (keep curr=boundary+1 means no new packet)   */
           
    EN1_PAR0 = (u8_t)0x12;// MAC_addr.addr[0];	//自定义的mac地址
    EN1_PAR1 = (u8_t)0x34;// MAC_addr.addr[1];
    EN1_PAR2 = (u8_t)0x56;// MAC_addr.addr[2];
    EN1_PAR3 = (u8_t)0x78;// MAC_addr.addr[3];
    EN1_PAR4 = (u8_t)0x9a;// MAC_addr.addr[4];
    EN1_PAR5 = (u8_t)0xe0;// MAC_addr.addr[5];
    
  	/* make up an address. */
  	ne2k_if->ethaddr->addr[0] = (u8_t) 0x12;//MAC_addr.addr[0];
  	ne2k_if->ethaddr->addr[1] = (u8_t) 0x34;//MAC_addr.addr[1];
  	ne2k_if->ethaddr->addr[2] = (u8_t) 0x56;//MAC_addr.addr[2];
  	ne2k_if->ethaddr->addr[3] = (u8_t) 0x78;//MAC_addr.addr[3];
  	ne2k_if->ethaddr->addr[4] = (u8_t) 0x9a;//MAC_addr.addr[4];
  	ne2k_if->ethaddr->addr[5] = (u8_t) 0xe0;//MAC_addr.addr[5];
    
    /* Initialize the multicast list to reject-all.  
       If we enable multicast the higher levels can do the filtering. 
       <multicast filter mask array (8 bytes)> */
    EN1_MAR0 = (u8_t) 0x00;  
    EN1_MAR1 = (u8_t) 0x00;
    EN1_MAR2 = (u8_t) 0x00;
    EN1_MAR3 = (u8_t) 0x00;
    EN1_MAR4 = (u8_t) 0x00;
    EN1_MAR5 = (u8_t) 0x00;
    EN1_MAR6 = (u8_t) 0x00;
    EN1_MAR7 = (u8_t) 0x00;
    
    EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP);  	   	/* 00001010B: PS1 PS0 RD2 RD1 RD0 TXP STA STP */
 
    EN0_IMR = (u8_t) (ENISR_OVER + ENISR_RX + ENISR_RX_ERR);
    //(ENISR_OVER + ENISR_RX + ENISR_TX + ENISR_TX_ERR);

    EN0_TXCR = (u8_t) 0xE0;	//ENTXCR_TXCONFIG;			//TCR 				
	EN0_RXCR = (u8_t) 0xCC;	//without Multicast //0xcc 	//RCR
	    
    EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_START);
    
    EN0_ISR = (u8_t) 0xff; // clear the all flag bits in EN0_ISR
  
 	ne2k_if_netif = netif;
}


/*
 * low_level_output():
 *
 * Should do the actual transmission of the packet. The packet is
 * contained in the pbuf that is passed to the function. This pbuf
 * might be chained.
 *
 */
static err_t low_level_output(struct netif * netif, struct pbuf *p)
{
	struct pbuf *q;
	u16_t padLength,packetLength,Count,loop,rd_tmp;
	u8_t *buf,flag1=0 ;

	/*
	 * Set up to transfer the packet contents to the NIC RAM.
	 */
	padLength = 0;
	packetLength = p->tot_len - ETH_PAD_SIZE; //05 01 millin

    if ((packetLength) < 64)
   {
       padLength = 64 - (packetLength);
       packetLength = 64;
   }

	/* Wait for other transmit */
	while ( EN_CMD & EN_TRANS );
	
	/* We should already be in page 0, but to be safe... */
	EN_CMD = (u8_t) (EN_PAGE0 + EN_START + EN_NODMA);

	EN0_IMR = (u8_t) (ENISR_OVER);
	//(ENISR_OVER + ENISR_TX + ENISR_TX_ERR);
	// turn off RX int
	
	EN0_ISR = (u8_t) ENISR_RDC;	// clear the RDC bit
	
	/* Now the normal output. */
	EN0_RCNTLO = (u8_t) (packetLength & 0xff);
	EN0_RCNTHI = (u8_t) ((packetLength >> 8) & 0xff);
	EN0_RSARLO = (u8_t) ((TX_START_PG<<8) & 0xFF);
	EN0_RSARHI = (u8_t) (TX_START_PG & 0xFF);
	
	EN_CMD = (u8_t) (EN_RWRITE + EN_START + EN_PAGE0);
	
	/*
	 * Write packet to ring buffers.
	 */
   for(q = p; q != NULL; q = q->next) {
    /* Send the data from the pbuf to the interface, one pbuf at a
       time. The size of the data in each pbuf is kept in the ->len
       variable. */
    	Count = q->len;
		buf = q->payload;

		if (q == p){
           	buf += ETH_PAD_SIZE;
		    Count -= ETH_PAD_SIZE;//Pad in Eth_hdr struct 
           	  }

		if ( (Count & 0x0001) ) flag1 = 1;
		Count = Count>>1;
		for (loop=0;loop < Count ;loop++){
				rd_tmp = (*buf++) + ((*buf++) << 8 );
				EN_DATA = (u16_t) rd_tmp;
	    	}
		if (flag1 == 1) *(unsigned char *)(Base_ADDR+0x10) = *buf++;
   	}

	while(padLength-- > 0){	
		*(unsigned char *)(Base_ADDR+0x10) = (u8_t)0x00; 	
		// Write padding for undersized packets
	}
    
	
	EN0_ISR = (u8_t) ENISR_RDC;	// clear the RDC bit

	/* Just send it, and does not check */
	EN0_TCNTLO = (u8_t) (packetLength& 0xff);
	EN0_TCNTHI = (u8_t) (packetLength>> 8);
	EN0_TPSR = (u8_t) TX_START_PG;

	EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_TRANS + EN_START);
	
	EN0_IMR = (u8_t) (ENISR_OVER + ENISR_RX + ENISR_RX_ERR);
	//(ENISR_OVER + ENISR_RX + ENISR_TX + ENISR_TX_ERR);
	
	#if LINK_STATS
		lwip_stats.link.xmit++;
	#endif /* LINK_STATS */
		
	return ERR_OK;
}


/*
 * low_level_input():
 *
 * Should allocate a pbuf and transfer the bytes of the incoming
 * packet from the interface into the pbuf.
 *
 */
static struct pbuf * 
low_level_input(struct netif *netif)
{
	struct ne2k_if *ne2k_if = netif->state;
	u16_t  packetLength,len,Count,loop,rd_tmp;
	u8_t PDHeader[4];   // Temp storage for ethernet headers//18
	struct pbuf * p;
	struct pbuf * q;
	u8_t *payload,*buf,flag1=0;
	u8_t curr,this_frame,next_frame;
	
	EN_CMD = (u8_t) (EN_PAGE1 + EN_NODMA + EN_START);
	curr = (u8_t) EN1_CURR;
	EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_START);
	this_frame = (u8_t) EN0_BOUNDARY + 1;//millin + 1
	
	if (this_frame >= RX_STOP_PG)
		this_frame = RX_START_PG;

	EN0_RCNTLO = (u8_t) 4;
	EN0_RCNTHI = (u8_t) 0;
	
	EN0_RSARLO = (u8_t) 0; /* See controller manual , use send packet command */
	EN0_RSARHI = (u8_t) this_frame; /* See controller manual , use send packet command */
	
	EN_CMD = (u8_t) (EN_PAGE0 + EN_RREAD + EN_START);
	
	//get the first 4 bytes from nic 
	Count = 2;  
	buf = PDHeader;
	while(Count--) {
 	    rd_tmp = EN_DATA ;
 	    *buf++ = (u8_t)(rd_tmp & 0x00ff) ;
 	    *buf++ = (u8_t)(rd_tmp >> 8) ;
  	}	
	
	EN0_ISR = (u8_t) ENISR_RDC;	/* clear the RDC bit */
	
	//  Store real length, set len to packet length - header
	packetLength = ((unsigned) PDHeader[2] | (PDHeader[3] << 8 ));
	
	next_frame = (u8_t) (this_frame + 1 + (packetLength >> 8));
	
	packetLength -= 4;
	
	if ((PDHeader[1] != next_frame) 
		&& (PDHeader[1] != next_frame + 1)
		&& (PDHeader[1] != next_frame - (RX_STOP_PG - RX_START_PG))
		&& (PDHeader[1] != next_frame + 1 - (RX_STOP_PG - RX_START_PG)))
		{
			EN0_BOUNDARY = (u8_t) (curr - 1); 
			//puts("Bad frame!\n");
			return NULL;
		}
	
	if (packetLength > MAX_PACKET_SIZE || packetLength < MIN_PACKET_SIZE)
		{
			next_frame = PDHeader[1];
			EN0_BOUNDARY = (u8_t) (next_frame-1);
			//printf("Bogus Packet Size \n");
			return NULL;
		}

⌨️ 快捷键说明

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