/** * Receive a single packet. * The contents will be placed in uip_buf, and uIP is called * as appropriate. */ void enc_receive_packet(void) { /* Receive a single packet */ uint8_t header[6]; uint8_t *status = header + 2; WRITE_REG(ENC_ERDPTL, enc_next_packet & 0xFF); WRITE_REG(ENC_ERDPTH, (enc_next_packet >> 8) & 0xFF); enc_rbm(header, 6); /* Update next packet pointer */ enc_next_packet = header[0] | (header[1] << 8); uint16_t data_count = status[0] | (status[1] << 8); if (status[2] & (1 << 7)) { uip_len = data_count; enc_rbm(uip_buf, data_count); if( BUF->type == htons(UIP_ETHTYPE_IP) ) { uip_arp_ipin(); uip_input(); if( uip_len > 0 ) { uip_arp_out(); enc_send_packet(uip_buf, uip_len); uip_len = 0; } } else if( BUF->type == htons(UIP_ETHTYPE_ARP) ) { uip_arp_arpin(); if( uip_len > 0 ) { //uip_arp_out(); enc_send_packet(uip_buf, uip_len); uip_len = 0; } } } uint16_t erxst = READ_REG(ENC_ERXSTL) | (READ_REG(ENC_ERXSTH) << 8); /* Mark packet as read */ if (enc_next_packet == erxst) { WRITE_REG(ENC_ERXRDPTL, READ_REG(ENC_ERXNDL)); WRITE_REG(ENC_ERXRDPTH, READ_REG(ENC_ERXNDH)); } else { WRITE_REG(ENC_ERXRDPTL, (enc_next_packet-1) & 0xFF); WRITE_REG(ENC_ERXRDPTH, ((enc_next_packet-1) >> 8) & 0xFF); } SET_REG_BITS(ENC_ECON2, ENC_ECON2_PKTDEC); }
/**Callback for every incoming packet. * */ void arp_callback(uint8_t* data, uint16_t len) { printf("arp_callback\n"); ethernet_header* eh = (ethernet_header*)data; if(eh->len_field == ETHERTYPE_ARP) { arp_header* ah = (arp_header*)(data+ETH_HLEN); if(ah->oper == ARP_OPCODE_REPLY) { arp_add_to_table(ah); } else if(ah->oper == ARP_OPCODE_REQUEST) { arp_add_to_table(ah); //Send arp reply.. eth_addr source_ether = ah->sha; ip_addr source_ip; source_ip.data = ah->spa; ethernet_gen_header(&(source_ether), ETHERTYPE_ARP, eth_data); arp_header* ah_rep = (arp_header*)(eth_data+ETH_HLEN); ah_rep->hType = ARP_HTYPE_ETHERNET; ah_rep->pType = ETHERTYPE_IP; ah_rep->hlen = 6; ah_rep->plen = 4; ah_rep->oper = ARP_OPCODE_REPLY; SET_MAC((&(ah_rep->sha))); ah_rep->spa = LOCAL_IP; ah_rep->tpa = source_ip.data; ah_rep->tha = source_ether; enc_prepare_ethernet_packet((ethernet_header*)eth_data); enc_add_packet_data(eth_data+ETH_HLEN, sizeof(arp_header)); enc_send_packet(); } } }
void arp_send_request(ip_addr* ip) { eth_addr brdcast; brdcast.words[0] = HTONS(0xffff); brdcast.words[1] = HTONS(0xffff); brdcast.words[2] = HTONS(0xffff); buffer_t* buf = NULL; buffer_create(buf, ARP_PLEN); ethernet_gen_header(&brdcast, ETHERTYPE_ARP, buf->data); ethernet_header* eh = (ethernet_header*)buf->data; arp_request(ip, buf->data+sizeof(ethernet_header)); enc_prepare_ethernet_packet(eh); enc_add_packet_data(buf->data+sizeof(ethernet_header), sizeof(arp_header)); enc_send_packet(); }
void main(void) { static struct uip_eth_addr eth_addr; uip_ipaddr_t ipaddr; cpu_init(); uart_init(); printf("Welcome\n"); spi_init(); enc28j60_comm_init(); printf("Welcome\n"); enc_init(mac_addr); // // Configure SysTick for a periodic interrupt. // MAP_SysTickPeriodSet(MAP_SysCtlClockGet() / SYSTICKHZ); MAP_SysTickEnable(); MAP_SysTickIntEnable(); //MAP_IntEnable(INT_GPIOA); MAP_IntEnable(INT_GPIOE); MAP_IntMasterEnable(); MAP_SysCtlPeripheralClockGating(false); printf("int enabled\n"); MAP_GPIOIntTypeSet(GPIO_PORTE_BASE, ENC_INT, GPIO_FALLING_EDGE); MAP_GPIOPinIntClear(GPIO_PORTE_BASE, ENC_INT); MAP_GPIOPinIntEnable(GPIO_PORTE_BASE, ENC_INT); uip_init(); eth_addr.addr[0] = mac_addr[0]; eth_addr.addr[1] = mac_addr[1]; eth_addr.addr[2] = mac_addr[2]; eth_addr.addr[3] = mac_addr[3]; eth_addr.addr[4] = mac_addr[4]; eth_addr.addr[5] = mac_addr[5]; uip_setethaddr(eth_addr); #define DEFAULT_IPADDR0 10 #define DEFAULT_IPADDR1 0 #define DEFAULT_IPADDR2 0 #define DEFAULT_IPADDR3 201 #define DEFAULT_NETMASK0 255 #define DEFAULT_NETMASK1 255 #define DEFAULT_NETMASK2 255 #define DEFAULT_NETMASK3 0 #undef STATIC_IP #ifdef STATIC_IP uip_ipaddr(ipaddr, DEFAULT_IPADDR0, DEFAULT_IPADDR1, DEFAULT_IPADDR2, DEFAULT_IPADDR3); uip_sethostaddr(ipaddr); printf("IP: %d.%d.%d.%d\n", DEFAULT_IPADDR0, DEFAULT_IPADDR1, DEFAULT_IPADDR2, DEFAULT_IPADDR3); uip_ipaddr(ipaddr, DEFAULT_NETMASK0, DEFAULT_NETMASK1, DEFAULT_NETMASK2, DEFAULT_NETMASK3); uip_setnetmask(ipaddr); #else uip_ipaddr(ipaddr, 0, 0, 0, 0); uip_sethostaddr(ipaddr); printf("Waiting for IP address...\n"); uip_ipaddr(ipaddr, 0, 0, 0, 0); uip_setnetmask(ipaddr); #endif httpd_init(); #ifndef STATIC_IP dhcpc_init(mac_addr, 6); dhcpc_request(); #endif long lPeriodicTimer, lARPTimer; lPeriodicTimer = lARPTimer = 0; int i; // = MAP_GPIOPinRead(GPIO_PORTA_BASE, ENC_INT) & ENC_INT; while(true) { //MAP_IntDisable(INT_UART0); MAP_SysCtlSleep(); //MAP_IntEnable(INT_UART0); //i = MAP_GPIOPinRead(GPIO_PORTA_BASE, ENC_INT) & ENC_INT; /*while(i != 0 && g_ulFlags == 0) { i = MAP_GPIOPinRead(GPIO_PORTA_BASE, ENC_INT) & ENC_INT; }*/ if( HWREGBITW(&g_ulFlags, FLAG_ENC_INT) == 1 ) { HWREGBITW(&g_ulFlags, FLAG_ENC_INT) = 0; enc_action(); } if(HWREGBITW(&g_ulFlags, FLAG_SYSTICK) == 1) { HWREGBITW(&g_ulFlags, FLAG_SYSTICK) = 0; lPeriodicTimer += SYSTICKMS; lARPTimer += SYSTICKMS; //printf("%d %d\n", lPeriodicTimer, lARPTimer); } if( lPeriodicTimer > UIP_PERIODIC_TIMER_MS ) { lPeriodicTimer = 0; int l; for(l = 0; l < UIP_CONNS; l++) { uip_periodic(l); // // 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(); enc_send_packet(uip_buf, uip_len); uip_len = 0; } } for(l = 0; l < UIP_UDP_CONNS; l++) { uip_udp_periodic(l); if( uip_len > 0) { uip_arp_out(); enc_send_packet(uip_buf, uip_len); uip_len = 0; } } } if( lARPTimer > UIP_ARP_TIMER_MS) { lARPTimer = 0; uip_arp_timer(); } } }