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

📄 ethernetif.i

📁 凌阳单片机之以太网通讯模组模组
💻 I
📖 第 1 页 / 共 3 页
字号:



































struct stats_proto {
  u16_t xmit;     
  u16_t rexmit;   
  u16_t recv;     
  


  u16_t drop;     
  u16_t chkerr;   
  u16_t lenerr;   
  u16_t memerr;   
  u16_t rterr;    
  u16_t proterr;  
  u16_t opterr;   
  u16_t err;      
  


};

struct stats_mem {
  mem_size_t avail;
  mem_size_t used;
  mem_size_t max;  
  mem_size_t err;
};

struct stats_pbuf {
  u16_t avail;
  u16_t used;
  u16_t max;  
  u16_t err;
  u16_t alloc_locked;
  u16_t refresh_locked;
};

struct stats_syselem {
  u16_t used;
  u16_t max;
  u16_t err;
};

struct stats_sys {
  struct stats_syselem sem;
  struct stats_syselem mbox;
};

# 115 "..\\unip\\include\\lwip\\stats.h"


struct stats_ {
  


  
  


  
  



  struct stats_proto icmp;
  
  


  
  
  struct stats_proto tcp;
  
  struct stats_pbuf pbuf;
  struct stats_mem mem;
  struct stats_mem memp[MEMP_MAX];
  



};

 
extern  struct stats_ lwip_stats  ;
 

void stats_init(void);









# 65 "..\\unip\\include\\lwipopts.h" 2



# 1 "..\\unip\\include\\netif\\etharp.h" 1
 










































 
struct eth_addr {
  
 u16_t addr[3];
} __attribute__((packed)) ;
 

 
struct eth_hdr {
   struct eth_addr dest  __attribute__((packed)) ;
   struct eth_addr src  __attribute__((packed)) ;
   u16_t type  __attribute__((packed)) ;
} __attribute__((packed)) ;
 

 
 
struct etharp_hdr {
   struct eth_hdr ethhdr  __attribute__((packed)) ;
   u16_t hwtype  __attribute__((packed)) ;
   u16_t proto  __attribute__((packed)) ;
   u16_t _hwlen_protolen  __attribute__((packed)) ;
   u16_t opcode  __attribute__((packed)) ;
   struct eth_addr shwaddr  __attribute__((packed)) ;
   struct ip_addr sipaddr  __attribute__((packed)) ;
   struct eth_addr dhwaddr  __attribute__((packed)) ;
   struct ip_addr dipaddr  __attribute__((packed)) ;
} __attribute__((packed)) ;
 

 
struct ethip_hdr {
   struct eth_hdr eth  __attribute__((packed)) ;
   struct ip_hdr ip  __attribute__((packed)) ;
};









enum etharp_state {
  ETHARP_STATE_EMPTY,
  ETHARP_STATE_PENDING,
  ETHARP_STATE_STABLE
};

struct etharp_entry {
  struct ip_addr ipaddr;
  struct eth_addr ethaddr;
  enum etharp_state state;
 
  struct pbuf *p;
 
  u8_t ctime;
};

void etharp_init(void);
void etharp_tmr(void);
struct pbuf *etharp_ip_input(struct netif *netif, struct pbuf *p);
struct pbuf *etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr,
			   struct pbuf *p);
struct pbuf *etharp_output(struct netif *netif, struct ip_addr *ipaddr,
			   struct pbuf *q);
err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q);
struct eth_addr * etharp_lookup(struct ip_addr *ipaddr);


extern  struct etharp_entry arp_table [] ;
extern  u16_t arp_num  ;



# 68 "..\\unip\\include\\lwipopts.h" 2





# 1 "..\\unip\\include\\unsp\\include\\ethernet.h" 1
 
err_t ethernetif_init(struct netif *netif);
void etharp_timer(void *arg);
# 73 "..\\unip\\include\\lwipopts.h" 2




# 21 "..\\code\\include\\config.h" 2















# 42 "G:/\301\350\321\364\265\245\306\254\273\372/\320\302\275\250\316\304\274\376\274\320/9.\304\243\327\351\327\312\301\317/\322\324\314\253\315\370\315\250\321\266\304\243\327\351/\322\324\314\253\315\370DemoCode/DemoCode/code/ethernetif.c" 2

# 1 "..\\unip\\include\\unsp\\spce061\\Dm9000.h" 1
 
 









 







































 
 
 
 
 
 
 


 



























































# 43 "G:/\301\350\321\364\265\245\306\254\273\372/\320\302\275\250\316\304\274\376\274\320/9.\304\243\327\351\327\312\301\317/\322\324\314\253\315\370\315\250\321\266\304\243\327\351/\322\324\314\253\315\370DemoCode/DemoCode/code/ethernetif.c" 2

# 1 "..\\unip\\include\\unsp\\spce061\\hardware.h" 1



 
 
 






















 
 
 
 
 
 
 
 
 

 







 











 






 

 
 
 
 
 
 
 

















 
 
 
 











 





































 














 





 















 







# 44 "G:/\301\350\321\364\265\245\306\254\273\372/\320\302\275\250\316\304\274\376\274\320/9.\304\243\327\351\327\312\301\317/\322\324\314\253\315\370\315\250\321\266\304\243\327\351/\322\324\314\253\315\370DemoCode/DemoCode/code/ethernetif.c" 2

 






enum DM9K_PHY_mode {
	DM9K_10MHD   = 0, 
	DM9K_100MHD  = 1, 
	DM9K_10MFD   = 4,
	DM9K_100MFD  = 5, 
	DM9K_AUTO    = 8,
    DM9K_DISCONN = 9
};

extern void delay(u16_t);


u16_t inb(int port)
{
	 int iData,i;
	 * ((volatile u16_t *)(0x7005 )) =0x4070;                
	 * ((volatile u16_t *)(0x7002 )) =0x0000;
	 * ((volatile u16_t *)(0x7005 )) =0x0070|port;             
	 * ((volatile u16_t *)(0x7005 )) =0x0020|port;               
	 * ((volatile u16_t *)(0x7002 )) =0x0000;
	 iData=* ((volatile u16_t *)(0x7000 )) ;             
	 * ((volatile u16_t *)(0x7005 )) =0x0070|port;             
	 * ((volatile u16_t *)(0x7005 )) =0x4070|port;                
	 * ((volatile u16_t *)(0x7002 )) =0xffff;
     return(iData & 0x00ff);
}

void outb(int data,int port)
{
	int i;
	 * ((volatile u16_t *)(0x7002 )) =0xffff;	 
	 * ((volatile u16_t *)(0x7000 )) =data;   
	 * ((volatile u16_t *)(0x7005 )) =0x4070|port;                
	 * ((volatile u16_t *)(0x7005 )) =0x0070|port;             
    * ((volatile u16_t *)(0x7005 )) =0x0010|port;               
* ((volatile u16_t *)(0x7005 )) =0x4070;                
}

u16_t inw(int port)
{
	 int iData,i;
	 * ((volatile u16_t *)(0x7005 )) =0x4070;                
	 * ((volatile u16_t *)(0x7002 )) =0x0000;
	 * ((volatile u16_t *)(0x7005 )) =0x0070|port;             
	 	 * ((volatile u16_t *)(0x7005 )) =0x0020|port;               
	 iData=* ((volatile u16_t *)(0x7000 )) ;             
	 * ((volatile u16_t *)(0x7005 )) =0x0070|port;             
	 * ((volatile u16_t *)(0x7005 )) =0x4070|port;                
	 * ((volatile u16_t *)(0x7002 )) =0xffff;	 
	 return(iData);
}

void outw(int data,int port)
{
	 int i;
	 * ((volatile u16_t *)(0x7002 )) =0xffff;	 
	 * ((volatile u16_t *)(0x7000 )) =data;  
	 * ((volatile u16_t *)(0x7005 )) =0x4070|port;                
	 * ((volatile u16_t *)(0x7005 )) =0x0070|port;             
	 * ((volatile u16_t *)(0x7005 )) =0x0010|port;               
	 * ((volatile u16_t *)(0x7005 )) =0x0070|port;             
	 * ((volatile u16_t *)(0x7005 )) =0x4070|port;                
}
void r_pack(unsigned int len,unsigned int *payload)  
{
     unsigned int i,j=0;
	 * ((volatile u16_t *)(0x7005 )) =0x4074;                
	 * ((volatile u16_t *)(0x7002 )) =0x0000;
     for(j=0;j<len;j++)
    { 
	  
	 * ((volatile u16_t *)(0x7005 )) =0x0024;               
	 *(payload++)=* ((volatile u16_t *)(0x7000 )) ;             
	  
	 * ((volatile u16_t *)(0x7005 )) =0x0034;               
      
    }	 
	 * ((volatile u16_t *)(0x7002 )) =0xffff;
}

void drop(unsigned int len)  
{
     unsigned int i,j=0;
	 * ((volatile u16_t *)(0x7005 )) =0x4070;                
	 * ((volatile u16_t *)(0x7002 )) =0x0000;
     for(j=0;j<len;j++)
    { 
	  
     * ((volatile u16_t *)(0x7005 )) =0x0024;               
	 * ((volatile u16_t *)(0x7005 )) =0x0034;             
	  
    }	 
	 * ((volatile u16_t *)(0x7002 )) =0xffff;
}

void s_pack(unsigned int len,unsigned int *payload)
{
	 unsigned int i,j=0;
	 * ((volatile u16_t *)(0x7005 )) =0x4070;                
 	 * ((volatile u16_t *)(0x7002 )) =0xffff;
     for(j=0;j<len;j++)
    {
     * ((volatile u16_t *)(0x7000 )) =*(payload++);             
	 * ((volatile u16_t *)(0x7005 )) =0x4074;                
	  
	   
	 * ((volatile u16_t *)(0x7005 )) =0x0014;               
	  
	  
	 * ((volatile u16_t *)(0x7005 )) =0x4074;                
    }
}

void delay(u16_t delay_time);

static const struct eth_addr ethbroadcast = {{0xffff,0xffff,0xffff}};
 
static void  ethernetif_input(struct netif *netif);
static err_t ethernetif_output(struct netif *netif, struct pbuf *p,struct ip_addr *ipaddr);

typedef struct EtherDev{
    u16_t   base_addr;
    struct eth_addr dev_addr;
	u8_t op_mode;			 
	u8_t io_mode;			 
	u16_t link_mode;	
	 
	 
	 
	u16_t reset_rx_status;		  
	 
	 
	 
	u16_t rx_packets;
	u16_t tx_packets;
	 

} Dm9000_t;



 
static struct EtherDev * dmfe_dev = ((void *)0) ;
 
int dmfe_probe(struct EtherDev *);
static int dmfe_stop(struct EtherDev *);
static void dmfe_init_DM9K(struct EtherDev *);         

volatile static u8_t ior(int);
static void iow(int, u8_t);
volatile static u16_t phy_read( int);
static void phy_write(int, u16_t);
static u16_t read_srom_word(int);







 

 

struct EtherDev *init_etherdev(struct EtherDev *dev, u16_t opt)
{
dev = mem_malloc(sizeof (struct EtherDev));
memset(dev,0,sizeof (struct EtherDev));
return(dev);
}




int dmfe_probe(struct EtherDev *dev)
{
	u32_t id_val;
	u16_t iobase = 0x000 ;
	u16_t i, DM9K_found = 0 ,oft;
	  ;

	 
		outb(0x28 , iobase);
		id_val = inb(iobase + 4);
		outb(0x29 , iobase);
		id_val |= inb(iobase + 4) << 8;
		outb(0x2A , iobase);
		id_val |= (u32_t)inb(iobase + 4) << 16;
		outb(0x2B , iobase);
		id_val |= (u32_t)inb(iobase + 4) << 24;
		if (id_val == 0x90000A46 ) {
			 ;
			DM9K_found = 1 ;
			 
			dev = init_etherdev(dev, 0);
			 
			dmfe_dev    = dev;
			dev->base_addr 		= iobase;
			




            dev->dev_addr.addr[0]=0x6000;
            dev->dev_addr.addr[1]=0x006e;
            dev->dev_addr.addr[2]=0x0090;
            
            for (i = 0, oft = 0x10; i < 6; i++, oft++)
	        iow(oft, getbyte( dev->dev_addr .addr,  i ) );
			 
		}

	return DM9K_found ? 0:-1;
}

 



void low_level_init(struct netif *netif)
{
	struct EtherDev * dev = netif->state;
	dmfe_init_DM9K(dev);
}

 

static void set_PHY_mode(u16_t op_mode)
{
	u16_t phy_reg4 = 0x01e1, phy_reg0=0x1000;
	switch(op_mode) {
			case DM9K_10MHD:  phy_reg4 = 0x21; 
                        	            phy_reg0 = 0x0000; 
					    break;
			case DM9K_10MFD:  phy_reg4 = 0x41; 
                        	            phy_reg0 = 0x1100; 
                                	    break;
			case DM9K_100MHD: phy_reg4 = 0x81; 
					    phy_reg0 = 0x2000; 
				    	    break;
			case DM9K_100MFD: phy_reg4 = 0x101; 
				    	    phy_reg0 =0x3100; 
				   	    break;
		}
		phy_write(4, phy_reg4);	 
		phy_write(0, phy_reg0);	 
	iow( 0x1e, 0x01);			 
	iow( 0x1f, 0x00);			 
}


 




err_t
low_level_output(struct netif *netif, struct pbuf *skb)
{
    struct EtherDev *dev = netif->state;
	u16_t * data_ptr;
	int i, tmplen;
	struct pbuf *q;
	 	
	 
	ior(0x05);
	outb(0xf8, (0x0 ) );
	







	if (dev->io_mode == 0 ) {
		 
  for(q = skb ; q != ((void *)0) ; q = q->next) {
     


   if ((q->len % 2) && (q->next != ((void *)0) ))
   {
    ;
   while(1);
   }
   data_ptr = q->payload;
   tmplen = (q->len + 1) / 2;
   s_pack(tmplen, data_ptr);
  }
       dev->tx_packets++;
		 
		iow( 0xfc, skb->tot_len & 0xff);
		iow( 0xfd, (skb->tot_len >> 8) & 0xff);
		iow( 0x02, 0x01);
        while (!( ior( 0x01) & (4 | 8)));
	return 0 ;
	}
	
}

 

static void dmfe_init_DM9K(struct EtherDev *dev)
{ 	
	 

	iow( 0, 3);
	delay(100);			   
	iow( 0, 0);
	iow( 0, 3);
	delay(100);			   
	iow( 0, 0);
	 
	dev->io_mode = ior( 0xfe) >> 6;  
     ;
	delay(200);			   
	 
	dev->op_mode = DM9K_10MFD;
	set_PHY_mode(dev->op_mode);
	delay(500);
	if (!(ior(0x01 ) &1<<6)) 
	dev->link_mode = DM9K_DISCONN;
	else dev->link_mode = dev->op_mode;
	 
	 	
	 
	iow( 0x00, 0x00 );
	iow( 0x02, 0);		 
	iow( 0x08, 0x3f);		 
	iow( 0x09, 0x38 );	 
	iow( 0x0a, 0x00 );	 
	iow( 0x2f, 0);		 
	iow( 0x01, 0x2c);		 
	iow( 0xfe, 0x0f); 		 
 	 
 	


	 
	iow( 0x05, 0x30  | 1);	 
	iow( 0xff, 0x83 ); 	 
 	 
}

 



static int dmfe_stop(struct EtherDev *dev)
{
	  ;
	 
	phy_write( 0x00, 0x8000);	 
	delay(200);
	iow( 0x1f, 0x01); 		 
	iow( 0xff, 0x80);		 
	iow( 0x05, 0x00);		 

    delay(200);
	 








return 0;
}

 



struct pbuf *
low_level_input(struct netif *netif)
{
	struct EtherDev *dev = netif->state;
	struct pbuf *skb = ((void *)0) ;
	u16_t rxbyte, *rdptr;
	u16_t i, RxStatus, RxLen, GoodPacket, tmplen;
	 
		ior(0xf0);			 
		rxbyte = inb((0x0  + 4) );	 
		 
   		 
		if (rxbyte == 0x01 ) {
			 
			GoodPacket = 1 ;
			outb(0xf2, (0x0 ) );
			






			if (dev->io_mode == 0 ) {
				 
				RxStatus = inw((0x0  + 4) );
				RxLen    = inw((0x0  + 4) );
			} 

			 
			if (RxLen < 0x40) { 
				GoodPacket = 0 ; 
				 
			}
			
			if (RxLen > 1536 ) { 
				 ;
				 
			}
			
			if (RxStatus & 0xbf00) {
				GoodPacket = 0 ;
				if (RxStatus & 0x100) 
					 
					;
				if (RxStatus & 0x200) 
					 
					;
				if (RxStatus & 0x8000) 
					 
					;
			}

			 
		if ( GoodPacket && ((skb = pbuf_alloc(PBUF_LINK,RxLen, PBUF_POOL)) != ((void *)0)  ) ) {
			rdptr = skb->payload;			
			 
			






			if (dev->io_mode == 0 ) {
						 
				tmplen = (RxLen + 1) / 2;
					    r_pack(tmplen, rdptr);
					   
				 
				
			      
				}
					 
					dev->rx_packets++; 
					return(skb);					
				} else {
				    if (skb!= ((void *)0) ) pbuf_free(skb);
					tmplen = (RxLen + 1) / 2;
					drop(tmplen);
					 
					return(((void *)0) );
			}
		}

	return (((void *)0) );
}


 




 


# 605 "G:/\301\350\321\364\265\245\306\254\273\372/\320\302\275\250\316\304\274\376\274\320/9.\304\243\327\351\327\312\301\317/\322\324\314\253\315\370\315\250\321\266\304\243\327\351/\322\324\314\253\315\370DemoCode/DemoCode/code/ethernetif.c"


 


volatile static u8_t ior(int reg)
{
	outb(reg, (0x0 ) );
	return inb((0x0  + 4) );
}

 


static void iow(int reg, u8_t value)
{
	outb(reg, (0x0 ) );
	outb(value, (0x0  + 4) );
}

 


volatile static u16_t phy_read(int reg)
{
	 
	iow(0xc, 0x40  | reg);
	iow(0xb, 0xc); 	 
	delay(100);		 
	while((ior(0x0B ) & 0x01) == 0x01);
	iow( 0xb, 0x0); 	 
	 
	return ( ior(0xe) << 8 ) | ior(0xd);
}

 


static void phy_write(int reg, u16_t value)
{
	 
	iow(0xc, 0x40  | reg);
	 
	iow(0xd, (value & 0xff));
	iow(0xe, ( (value >> 8) & 0xff));
	iow(0xb, 0xa);		 
	delay(200);			 
	while((ior(0x0B ) & 0x01) == 0x01);
	iow(0xb, 0x0);		 
}

 
 







 
static err_t
ethernetif_output(struct netif *netif, struct pbuf *p,
      struct ip_addr *ipaddr)
{
  struct EtherDev *dev;
  struct pbuf *q;
  struct eth_hdr *ethhdr;
  struct eth_addr *dest;
  struct ip_addr *queryaddr;
  err_t err;
  u8_t i;
    ;
  
 dev = netif->state;

   
  if (pbuf_header(p, 14) != 0) {
     

    q = pbuf_alloc(PBUF_LINK, 14, PBUF_RAM);
    if (q == ((void *)0) ) {



      
      return -1 ;
    }
    pbuf_chain(q, p);
    p = q;
  }
   



  queryaddr = ipaddr;
  if ((( ipaddr ) == ((void *)0)  || ( ipaddr )->addr == 0)  ||
     ((((( ipaddr )->addr) & ~((  &(netif->netmask) )->addr)) == (0xffffffff & ~((  &(netif->netmask) )->addr))) || (( ipaddr )->addr == 0xffffffff) || (( ipaddr )->addr == 0x00000000)) ) {
    dest = (struct eth_addr *)&ethbroadcast;
  } else if (((( ipaddr )->addr & ntohl(0xf0000000)) == ntohl(0xe0000000)) ) {
     
     
  } else {

    if (((( ipaddr )->addr & (  &(netif->netmask) )->addr) == ((  &(netif->ip_addr) )->addr & (  &(netif->netmask) )->addr)) ) {
       

      queryaddr = ipaddr;
    } else {
       

      queryaddr = &(netif->gw);
    }
    dest = etharp_lookup(queryaddr);
  }
   

  if (dest == ((void *)0) ) {
    err = etharp_query(netif,  queryaddr, p);
     return err;    
  }
  ethhdr = p->payload;
  for(i = 0; i < 3; i++) {
    ethhdr->dest.addr[i] = dest->addr[i];
    ethhdr->src.addr[i] = dev->dev_addr.addr[i];
  }
ethhdr->type = htons(0x0800 );



   return low_level_output(netif, p);

}

 
static void
ethernetif_input(struct netif *netif)
{
  struct EtherDev *dev;
  struct eth_hdr *ethhdr;
  struct pbuf *p;
  dev = netif->state;
  p = low_level_input(netif);
  if (p != ((void *)0) ) {



    ethhdr = p->payload;    
    switch (htons(ethhdr->type)) {
    case 0x0800 :
      etharp_ip_input(netif, p);
      pbuf_header(p, -14);
      netif->input(p, netif);
      break;
    case 0x0806 :
      p = etharp_arp_input(netif, &(dev->dev_addr), p);
      if (p != ((void *)0) ) {
  low_level_output(netif, p);
  pbuf_free(p);
      }
      break;
    default:
      pbuf_free(p);
      break;
    }
  }
}
 
void
etharp_timer(void *arg)
{
struct EtherDev *dev = arg;
if (!(ior(0x01 ) & 1<<6))
    dev->link_mode = DM9K_DISCONN;
    else dev->link_mode = dev->op_mode;
etharp_tmr();
 ;
}
 
 







 
err_t
ethernetif_init(struct netif *netif)
{
int i;
  if (dmfe_probe(dmfe_dev)!=0) 
  {
  	 ;
  	return -11 ;
}; 	
  netif->state =  dmfe_dev;
  netif->name[0] = 'e' ;
  netif->name[1] = 't' ;
  netif->hwaddr_len = 3;
  netif->output = ethernetif_output;
  netif->linkoutput = low_level_output;
   for (i = 0; i < netif->hwaddr_len; ++i) {
     netif->hwaddr[i] = dmfe_dev->dev_addr.addr[i];
      }
  low_level_init(netif);
  etharp_init();
  return 0 ;
   ;
}
 




 
u8_t CheckNetPack(struct EtherDev *dev)
{
u16_t temp;
  ior(0xF0 );
  switch(ior(0xF0 )) 
    {
      case 0x00 :
        {
          return(0);                              
        }
      case 0x01 : return(1);               
      default   : 
            temp = ior(0xF4) + ior(0xF5)*256;
      		 ;
			dev->reset_rx_status++;
			dmfe_stop(dev);
			delay(200);
		    dmfe_init_DM9K(dev);       
            return(0);
    }
}

void Ethernet_poll(struct netif *netif)
{
    if (((struct EtherDev *)(netif->state))->link_mode == DM9K_DISCONN)
    {
     ;


    return;
    }
    if(CheckNetPack((struct EtherDev *)(netif->state))) 
      ethernetif_input(netif);   
}


⌨️ 快捷键说明

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