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

📄 ne2kif.c

📁 ucos-lwip-c6x
💻 C
📖 第 1 页 / 共 2 页
字号:
	    	
	EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_START);
	
	EN0_RCNTLO = (u8_t) (packetLength & 0xff);
	EN0_RCNTHI = (u8_t) (packetLength >> 8);
	
	EN0_RSARLO = (u8_t) 4; /* 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);
	
	/* We allocate a pbuf chain of pbufs from the pool. */
	p = pbuf_alloc(PBUF_RAW, packetLength+ETH_PAD_SIZE, PBUF_POOL); /* length of buf */
	// change from PBUF_LINK
	
	if(p != NULL) {
		/* We iterate over the pbuf chain until we have read the entire
      		 packet into the pbuf. */
	
		for(q = p; q != NULL; q= q->next){
     		   /* Read enough bytes to fill this pbuf in the chain. The
         	  avaliable data in the pbuf is given by the q->len
         	  variable. */
      	
		  	payload = q->payload;
		  	len = q->len;

		  	if (q == p){ // if first buf...
           		payload += ETH_PAD_SIZE;
		    	len -= ETH_PAD_SIZE;//Pad in Eth_hdr struct 
			}
		
			Count = len;
			buf = payload;
		
			if ( (Count & 0x0001) ) flag1 = 1;
			Count = Count>>1;
			for(loop=0;loop < Count;loop++) {
 	    			rd_tmp = EN_DATA ;
 	    			*buf++ = (u8_t)(rd_tmp & 0x00ff) ;
 	    			*buf++ = (u8_t)(rd_tmp >> 8) ;
 	    	}
 	    	if ( flag1==1 )      *buf++ = *(unsigned char *)(Base_ADDR+0x10) ;
 	    	
 	    	#if LINK_STATS
    			lwip_stats.link.recv++;
			#endif /* LINK_STATS */  
		}//for
		
	} else { // p == NULL
    	/* no more PBUF resource, Discard packet in buffer. */
	     	Count = packetLength;
			if ( (Count & 0x0001) ) flag1 = 1; Count = Count>>1;
			for(loop=0;loop < Count;loop++) rd_tmp = EN_DATA;
 	    	if ( flag1==1 ) rd_tmp = *(unsigned char *)(Base_ADDR+0x10);
 	    	
 	    	#if LINK_STATS
    			lwip_stats.link.memerr++;
    			lwip_stats.link.drop++;
			#endif /* LINK_STATS */      
  	}
  	
  	next_frame = PDHeader[1];
	
	EN0_BOUNDARY = (u8_t) (next_frame-1);
	
	EN0_ISR = (u8_t) ENISR_RDC;
	
	return p;
}


/*
 * ethernetif_output():
 *
 * This function is called by the TCP/IP stack when an IP packet
 * should be sent. It calls the function called low_level_output() to
 * do the actual transmission of the packet.
 *
 */
static err_t 
ne2k_output(struct netif *netif, struct pbuf *p,
		  struct ip_addr *ipaddr)
{
	/* resolve hardware address, then send (or queue) packet */
	return etharp_output(netif, ipaddr, p);
}


/*
 * ethernetif_input():
 *
 * This function should be called when a packet is ready to be read
 * from the interface. It uses the function low_level_input() that
 * should handle the actual reception of bytes from the network
 * interface.
 *
 */
static void 
ne2k_input(struct netif *netif)
{
  struct ne2k_if *ne2k_if;
  struct eth_hdr *ethhdr;
  struct pbuf *p;

  ne2k_if = netif->state;
    
//p = low_level_input(ne2k_if);
  /* move received packet into a new pbuf */
  p = low_level_input(netif);
  /* no packet could be read, silently ignore this */
  if (p == NULL) return;
  /* points to packet payload, which starts with an Ethernet header */
  ethhdr = p->payload;

#if LINK_STATS
  lwip_stats.link.recv++;
#endif /* LINK_STATS */  

  switch(htons(ethhdr->type)) {
  /* IP packet? */
	case ETHTYPE_IP:
    	/* update ARP table */
    	etharp_ip_input(netif, p);
    	/* skip Ethernet header */
    	pbuf_header(p, -(14+ETH_PAD_SIZE));
    	/* pass to network layer */
    	netif->input(p, netif);
    	break;
  case ETHTYPE_ARP:
	    /* pass p to ARP module */
   		etharp_arp_input(netif, ne2k_if->ethaddr, p);
    	break;
  default:
		pbuf_free(p);
		p = NULL;
		break;
  }
}

/*-----------------------------------------------------------------------------------*/
static void
arp_timer(void *arg)
{
  etharp_tmr();
  sys_timeout(ARP_TMR_INTERVAL, (sys_timeout_handler)arp_timer, NULL);
}

/*
 * ethernetif_init():
 *
 * Should be called at the beginning of the program to set up the
 * network interface. It calls the function low_level_init() to do the
 * actual setup of the hardware.
 *
 */
err_t 
ne2k_init(struct netif *netif)
{
  struct ne2k_if *ne2k_if;

  ne2k_if = mem_malloc(sizeof(struct ne2k_if));//MAC Address
  
  if (ne2k_if == NULL)
  {
  		LWIP_DEBUGF(NETIF_DEBUG,("ne2k_init: out of memory!\n"));
  		return ERR_MEM;
  }
  
  netif->state = ne2k_if;
  netif->name[0] = IFNAME0;
  netif->name[1] = IFNAME1;
  netif->output = ne2k_output;
  netif->linkoutput = low_level_output;
  
  ne2k_if->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
  
  low_level_init(netif);
  
  etharp_init();
  
  sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
  
  return ERR_OK;
}


/*-----------------------------------------------------------------------------------*/

void ne2k_rx_err(void)
{
		u8_t  curr;
		EN_CMD = (u8_t) (EN_PAGE1 + EN_NODMA + EN_STOP);
		curr = (u8_t) EN1_CURR;
		EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP);
		EN0_BOUNDARY = (u8_t) curr-1;
}


/*-----------------------------------------------------------------------------------*/

void ne2k_rx(void)
{
		u8_t  curr,bnry;
		EN_CMD = (u8_t) (EN_PAGE1 + EN_NODMA + EN_STOP);
		curr = (u8_t) EN1_CURR;
		EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP);
		bnry = (u8_t) EN0_BOUNDARY + 1;//millin + 1
		
		if (bnry >= RX_STOP_PG)
			bnry = RX_START_PG;
		
		while(curr != bnry){
			ne2k_input(ne2k_if_netif);
			EN_CMD = (u8_t) (EN_PAGE1 + EN_NODMA + EN_STOP);
			curr = (u8_t) EN1_CURR;
			EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP);
			bnry = (u8_t) EN0_BOUNDARY + 1;			//millin +1
			}
}

/* -----------------------------
 *     void ne2k_isr(void)
 *    can be int 4 5 6 or 7 
 * ----------------------------*/
void
ne2k_isr(void)
{
		
	DSP_C6x_Save();

	OSIntEnter();
	
	if (OSIntNesting == 1)
		{
			OSTCBCur->OSTCBStkPtr = (OS_STK *) DSP_C6x_GetCurrentSP();
		}
			
	/* You can enable Interrupt again here, 
		if want to use nested interrupt..... */
	//------------------------------------------------------------

	EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP);
	//outb(CMD_PAGE0 | CMD_NODMA | CMD_STOP,NE_CR);
	
	EN0_IMR = (u8_t) 0x00;//close
	
	// ram overflow interrupt
	if (EN0_ISR & ENISR_OVER) {
		EN0_ISR = (u8_t) ENISR_OVER;		// clear interrupt
	}
	
	// error transfer interrupt ,NIC abort tx due to excessive collisions	
	if (EN0_ISR & ENISR_TX_ERR) {
		EN0_ISR = (u8_t) ENISR_TX_ERR;		// clear interrupt
	 	//temporarily do nothing
	}

	// Rx error , reset BNRY pointer to CURR (use SEND PACKET mode)
	if (EN0_ISR & ENISR_RX_ERR) {
		EN0_ISR = (u8_t) ENISR_RX_ERR;		// clear interrupt
		ne2k_rx_err();
	}

	//got packet with no errors
	if (EN0_ISR & ENISR_RX) {
		EN0_ISR = (u8_t) ENISR_RX;
		ne2k_rx();		
	}
		
	//Transfer complelte, do nothing here
	if (EN0_ISR & ENISR_TX){
		EN0_ISR = (u8_t) ENISR_TX;		// clear interrupt
	}
	
	EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP);
	
	EN0_ISR = (u8_t) 0xff;			// clear ISR	
	
	EN0_IMR = (u8_t) (ENISR_OVER + ENISR_RX + ENISR_RX_ERR);
	//(ENISR_OVER + ENISR_RX + ENISR_TX + ENISR_TX_ERR);
	
	//open nic for next packet
	EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_START);
	
	if (led_stat & 0x04) {LED3_on;}
	else {LED3_off;}
		
	//--------------------------------------------------------
		
	OSIntExit();
	
	DSP_C6x_Resume();
	
	asm ("	nop	5"); //important! 
	// this can avoid a stack error when compile with the optimization!
}

⌨️ 快捷键说明

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