/**
 * Fetches a pending packet from the RAM buffer of the ENC28J60.
 *
 * The packet is written into the given buffer and the size of the packet
 * (ethernet header plus payload, exclusive the CRC) is returned.
 *
 * Zero is returned in the following cases:
 * - There is no packet pending.
 * - The packet is too large to completely fit into the buffer.
 * - Some error occured.
 *
 * \param[out] buffer The pointer to the buffer which receives the packet.
 * \param[in] buffer_len The length of the buffer.
 * \returns The packet size in bytes on success, \c 0 in the cases noted above.
 */
uint16_t enc28j60_receive_packet(uint8_t* buffer, uint16_t buffer_len)
{
    if(!enc28j60_read(EPKTCNT))
        return 0;

    /* set read pointer */
    enc28j60_write(ERDPTL, packet_ptr & 0xff);
    enc28j60_write(ERDPTH, packet_ptr >> 8);

    /* read pointer to next packet */
    packet_ptr = ((uint16_t) enc28j60_read_buffer_byte()) |
                 ((uint16_t) enc28j60_read_buffer_byte()) << 8;

    /* read packet length */
    uint16_t packet_len = ((uint16_t) enc28j60_read_buffer_byte()) |
                          ((uint16_t) enc28j60_read_buffer_byte()) << 8;
    packet_len -= 4; /* ignore CRC */

    /* read receive status */
    enc28j60_read_buffer_byte();
    enc28j60_read_buffer_byte();

    /* read packet */
    if(packet_len <= buffer_len)
        enc28j60_read_buffer(buffer, packet_len);

    /* free packet memory */
    /* DS80349C.errata #14 */
    uint16_t packet_ptr_errata = packet_ptr - 1;
    if(packet_ptr_errata < RX_START || packet_ptr_errata > RX_END)
        packet_ptr_errata = RX_END;
    enc28j60_write(ERXRDPTL, packet_ptr_errata & 0xff);
    enc28j60_write(ERXRDPTH, packet_ptr_errata >> 8);

    /* decrement packet counter */
    enc28j60_set_bits(ECON2, (1 << ECON2_PKTDEC));

    if(packet_len <= buffer_len)
        return packet_len;
    else
        return 0;
}
示例#2
0
文件: dbg.c 项目: lijie169/stm32-tcp
void shell_eth(void)
{
	uint8_t addr  = 0 ;
	uint8_t tarip[] = {192,168,1,100};
	uint8_t mode = atoi(cmd_pointer[1]);
	uint16_t value = 0xffff;
	addr = atoi(cmd_pointer[2]);
	
	if(ETH_READ == mode)
	{
		value = enc28j60_read(addr);
		printf("read eth address = 0x%x(%u),value = 0x%x(%u)\n",addr,addr,value,value);
	}
	else if(ETH_WRITE == mode)
	{
		value = atoi(cmd_pointer[3]);
		enc28j60_write(addr,value);
		//value = enc28j60_readphy(addr);
		printf("wtite mi/eth address = 0x%x(%u),value = 0x%x(%u)\n",addr,addr,value,value);
	}
	else if(PHY_WRITE == mode)
	{
		//arp_request(tarip);
		value = atoi(cmd_pointer[3]);
		enc28j60_writephy(addr,value);
		//value = enc28j60_readphy(addr);
		printf("wtite phy address = 0x%x(%u),value = 0x%x(%u)\n",addr,addr,value,value);
		//printf("unimplement\n");
	}
	else if(PHY_READ == mode)
	{
		value = enc28j60_readphy(addr);
		printf("read phy address = 0x%x(%u),value = 0x%x(%u)\n",addr,addr,value,value);
	}
	else 
	{
		printf("unimplement\n");
	}
}
void uip_task(void *p)
{
	int i;
  	struct timer periodic_timer, arp_timer;

  	enc28j60_open();	

  	timer_set(&periodic_timer, CLOCK_SECOND / 2);
  	timer_set(&arp_timer, CLOCK_SECOND * 10);  
  	
  	
  	while(1) 
  	{
  		socket_process_pending_lists_();
  		
    	uip_len = enc28j60_read();
    	
    	if(uip_len > 0) 
    	{
      		if(BUF->type == htons(UIP_ETHTYPE_IP)) 
      		{
        		uip_input();
        		/* If the above function invocation resulted in data that
           		should be sent out on the network, the global variable
           		uip_len is set to a value > 0. */
        		if(uip_len > 0) 
        		{
          			uip_arp_out();
          			enc28j60_write();
        		}
      		} 
      		else if(BUF->type == htons(UIP_ETHTYPE_ARP)) 
      		{
        		uip_arp_arpin();
        		/* If the above function invocation resulted in data that
           		should be sent out on the network, the global variable
           		uip_len is set to a value > 0. */
        		if(uip_len > 0) 
        		{
          			enc28j60_write();
        		}
      		}

		} 
		
		if(timer_expired(&periodic_timer)) 
		{
      		timer_reset(&periodic_timer);
      		for(i = 0; i < UIP_CONNS; i++) 
      		{
        		uip_periodic(i);
        		/* If the above function invocation resulted in data that
           		should be sent out on the network, the global variable
           		uip_len is set to a value > 0. */
        		if(uip_len > 0) 
        		{
          			uip_arp_out();
          			enc28j60_write();
        		}
      		}

#if UIP_UDP
      		for(i = 0; i < UIP_UDP_CONNS; i++) 
      		{
        		uip_udp_periodic(i);
        		/* If the above function invocation resulted in data that
           		should be sent out on the network, the global variable
           		uip_len is set to a value > 0. */
        		if(uip_len > 0) 
        		{
          			uip_arp_out();
          			enc28j60_write();
        		}
        	}
#endif /* UIP_UDP */           
      		/* Call the ARP timer function every 10 seconds. */
      		if(timer_expired(&arp_timer)) 
      		{
      			timer_reset(&arp_timer);
      			uip_arp_timer();
      		}
    	}
    	
    	//yield so that other tasks can do something
    	sys_msleep(UIP_TASK_YIELD_TIME_MS);
	}
  	
}
示例#4
0
/**
 * Reset and initialize the ENC28J60 and starts packet transmission/reception.
 *
 * \param[in] mac A pointer to a 6-byte buffer containing the MAC address.
 * \returns \c true on success, \c false on failure.
 */
bool enc28j60_init(const uint8_t* mac)
{
#if 0
	/* init i/o */
	enc28j60_io_init();
#endif
	/* reset device */
	enc28j60_reset();

	/* configure rx/tx buffers */
	enc28j60_write(ERXSTL, RX_START & 0xff);
	enc28j60_write(ERXSTH, RX_START >> 8);
	enc28j60_write(ERXNDL, RX_END & 0xff);
	enc28j60_write(ERXNDH, RX_END >> 8);

	enc28j60_write(ERXWRPTL, RX_START & 0xff);
	enc28j60_write(ERXWRPTH, RX_START >> 8);
	enc28j60_write(ERXRDPTL, RX_START & 0xff);
	enc28j60_write(ERXRDPTH, RX_START >> 8);

	/* configure frame filters */
	enc28j60_write(ERXFCON, (1 << ERXFCON_UCEN)  | /* accept unicast packets */
	                    (1 << ERXFCON_CRCEN) | /* accept packets with valid CRC only */
	                    (0 << ERXFCON_PMEN)  | /* no pattern matching */
	                    (0 << ERXFCON_MPEN)  | /* ignore magic packets */
	                    (0 << ERXFCON_HTEN)  | /* disable hash table filter */
	                    (0 << ERXFCON_MCEN)  | /* ignore multicast packets */
	                    (1 << ERXFCON_BCEN)  | /* accept broadcast packets */
	                    (0 << ERXFCON_ANDOR)   /* packets must meet at least one criteria */
	          );

	/* configure MAC */
	enc28j60_clear_bits(MACON2, (1 << MACON2_MARST));
	enc28j60_write(MACON1, (0 << MACON1_LOOPBK) |
#if ENC28J60_FULL_DUPLEX 
	                   (1 << MACON1_TXPAUS) |
	                   (1 << MACON1_RXPAUS) |
#else
	                   (0 << MACON1_TXPAUS) |
	                   (0 << MACON1_RXPAUS) |
#endif
	                   (0 << MACON1_PASSALL) |
	                   (1 << MACON1_MARXEN)
	          );
	enc28j60_write(MACON3, (1 << MACON3_PADCFG2) |
	                   (1 << MACON3_PADCFG1) |
	                   (1 << MACON3_PADCFG0) |
	                   (1 << MACON3_TXCRCEN) |
	                   (0 << MACON3_PHDRLEN) |
	                   (0 << MACON3_HFRMEN) |
	                   (1 << MACON3_FRMLNEN) |
#if ENC28J60_FULL_DUPLEX 
	                   (1 << MACON3_FULDPX)
#else
	                   (0 << MACON3_FULDPX)
#endif
	          );
	enc28j60_write(MAMXFLL, 0xee);
	enc28j60_write(MAMXFLH, 0x05);
#if ENC28J60_FULL_DUPLEX 
	enc28j60_write(MABBIPG, 0x15);
#else
	enc28j60_write(MABBIPG, 0x12);
#endif
	enc28j60_write(MAIPGL, 0x12);
#if !ENC28J60_FULL_DUPLEX 
	enc28j60_write(MAIPGH, 0x0c);
#endif
	enc28j60_write(MAADR0, mac[5]);
	enc28j60_write(MAADR1, mac[4]);
	enc28j60_write(MAADR2, mac[3]);
	enc28j60_write(MAADR3, mac[2]);
	enc28j60_write(MAADR4, mac[1]);
	enc28j60_write(MAADR5, mac[0]);

	if(enc28j60_read(MAADR5)== mac[0]){
		ENC28J60_INIT_DEBUG(("MAADR5 = 0x%x\n", enc28j60_read(MAADR5)));
		ENC28J60_INIT_DEBUG(("MAADR4 = 0x%x\n", enc28j60_read(MAADR4)));
		ENC28J60_INIT_DEBUG(("MAADR3 = 0x%x\n", enc28j60_read(MAADR3)));
		ENC28J60_INIT_DEBUG(("MAADR2 = 0x%x\n", enc28j60_read(MAADR2)));
		ENC28J60_INIT_DEBUG(("MAADR1 = 0x%x\n", enc28j60_read(MAADR1)));
		ENC28J60_INIT_DEBUG(("MAADR0 = 0x%x\n", enc28j60_read(MAADR0)));
	}

	/*
	 * configure PHY
	 */

	/* leda -- green led, ledb -- orange led */
#if 0
	enc28j60_write_phy(PHLCON, (1 << PHLCON_LACFG3) |
	                       (1 << PHLCON_LACFG2) |
	                       (0 << PHLCON_LACFG1) |
	                       (1 << PHLCON_LACFG0) |
	                       (0 << PHLCON_LBCFG3) |
	                       (1 << PHLCON_LBCFG2) |
	                       (0 << PHLCON_LBCFG1) |
	                       (1 << PHLCON_LBCFG0) |
	                       (0 << PHLCON_LFRQ1) |
	                       (0 << PHLCON_LFRQ0) |
	                       (1 << PHLCON_STRCH)
	              );
#else
	enc28j60_write_phy(PHLCON, (0 << PHLCON_LACFG3) |
	                       (1 << PHLCON_LACFG2) |
	                       (0 << PHLCON_LACFG1) |
	                       (0 << PHLCON_LACFG0) |
	                       (0 << PHLCON_LBCFG3) |
	                       (1 << PHLCON_LBCFG2) |
	                       (1 << PHLCON_LBCFG1) |
	                       (1 << PHLCON_LBCFG0) |
	                       (0 << PHLCON_LFRQ1) |
	                       (0 << PHLCON_LFRQ0) |
	                       (1 << PHLCON_STRCH)
	              );

#endif
	enc28j60_write_phy(PHCON1, (0 << PHCON1_PRST) |
	                       (0 << PHCON1_PLOOPBK) |
	                       (0 << PHCON1_PPWRSV) |
#if ENC28J60_FULL_DUPLEX 
	                       (1 << PHCON1_PDPXMD)
#else
	                       (0 << PHCON1_PDPXMD)
#endif
	              );
	enc28j60_write_phy(PHCON2, (0 << PHCON2_FRCLNK) |
	                       (0 << PHCON2_TXDIS) |
	                       (0 << PHCON2_JABBER) |
	                       (1 << PHCON2_HDLDIS)
	              );

	/* start receiving packets */
	enc28j60_set_bits(ECON2, (1 << ECON2_AUTOINC));
#if 0
	enc28j60_set_bits(ECON1, (1 << ECON1_RXEN));

	ENC28J60_INIT_DEBUG(("line:%d, EIE = 0x%x\n", __LINE__, enc28j60_read(EIE)));

	/* enable interrupt, David  */
	enc28j60_set_bits(EIE, (1 << EIE_INTIE) | (1<<EIE_PKTIE) | (1<<EIE_TXIE));

	ENC28J60_INIT_DEBUG(("line:%d, EIE = 0x%x\n", __LINE__, enc28j60_read(EIE)));
#endif	
	return true;
}