/** * 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; }
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); } }
/** * 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; }