/** ******************************************************************************************* * @fn void TcpIpMain(void) * @brief Update the uIP stack. * @return None * @attention ******************************************************************************************* */ void TcpIpMain(void) { uint8_t Index; uip_len = nic_poll(); if (uip_len == 0) { // If timed out, call periodic function for each connection if (TcpIpUipTimerCounter >= TCP_IP_CNT_TIME) { TcpIpUipTimerCounter = 0; for (Index = 0; Index < UIP_CONNS; Index++) { uip_periodic(Index); if (uip_len > 0) { uip_arp_out(); nic_send(); } } /* Call the ARP timer function every ~10 seconds. */ if (++TcpIpUipArpTimerCounter >= TCP_IP_ARP_CNT_TIME) { uip_arp_timer(); TcpIpUipArpTimerCounter = 0; } } } else // packet received { // process an IP packet if (TCP_IP_BUF->type == htons(UIP_ETHTYPE_IP)) { uip_arp_ipin(); uip_input(); if (uip_len > 0) { uip_arp_out(); nic_send(); } } // process an ARP packet else if (TCP_IP_BUF->type == htons(UIP_ETHTYPE_ARP)) { uip_arp_arpin(); if (uip_len > 0) nic_send(); } TcpIpUipTimerCounter = 0; } }
static void maybe_send(void) { /* 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(); nic_send(NULL); } }
static int nic_send_frame(snic *nic, frame_buffer *buffer) { unsigned int iobase = nic->iobase; if (buffer->len>MAX_FRSIZE) return ETOOBIG; outportg(0x00, iobase + INTERRUPTMASK); // Disable interrupts nic->tx_frame = tx_wait_pkt = buffer; nic->tx_frame->page = nic->pstart ; nic_block_output(nic,(struct frame_buffer *)nic->tx_frame); if(nic_send(nic)<0) { outportg(IMR_DEFAULT, iobase + INTERRUPTMASK); nic->tx_frame = NULL; return ERR; } outportg(IMR_DEFAULT, iobase + INTERRUPTMASK); return NOERR; }
/* TODO- Have it check how lonk a transmission is taking and attempt to restart the card if it's too long. */ int nic_send_packet(snic *nic, packet_buffer *buffer) { uint timeout; uint f; int iobase; /* kprintf("nic_send_packet()\n"); */ if(!buffer) return ERRARG; if(!buffer->count || !buffer->buf) return ERRARG; if(!nic || !nic->iobase) return ERR; iobase=nic->iobase; t(A); buffer->len=0; for(f=0;f<buffer->count;f++) buffer->len+=buffer->buf[f].len; if(buffer->len>MAX_LENGTH) return ERRTOOBIG; t(B); /* the following wait for anyother tasks that are calling // nic_send_packet() right now. Note that this doesn't use // an atomic semaphore, so something MAY leak through. */ /* timeout=ticks+10; wait 10 ticks */ timeout=ticks+100; while(nic->busy && ticks<=timeout) idle(); /* Replace this with a proper timeout thing that doesn't use the // ticks method which will be diffrent on each OS. */ t(C); if(nic->busy) { kprintf("NE2000: ERROR: Card stalled, timeout.\n"); return ERRTIMEOUT; } nic->busy=1; /* mark as busy, replace with semaphore */ t(D); outb_p(0x00, iobase + INTERRUPTMASK); /* mask ints for now */ t(E); timeout=ticks+TIMEOUT_TX; while(idle(), ticks<=timeout) for(f=0;f<MAX_TX;f++) { if(!nic->tx_packet[f]) { t(F); /* nic->tx_packet[f]=*buffer;*/ nic->tx_packet[f]=buffer; nic->tx_packet[f]->page=nic->pstart + (f * MAX_PAGESPERPACKET); /*output page */ /* kprintf("NE2000: sending packet with count:%x on page:%X with buffer:%x\n", buffer->count,buffer->page,buffer->buf); */ t(>); nic_block_output(nic,nic->tx_packet[f]); t(<); if(!nic->sending) { nic->send=f; nic->sending=1; /* now let's actually trigger the transmitter */ t(I); if(nic_send(nic,f)<0) { nic->sending=0; break; } /* note, the nic_tx() interrupt will mark this // tx_packet buffer as free again once it // confirms that the packet was sent. */ } t(J); nic->stat.tx_buffered++; outb_p(IMR_DEFAULT, iobase + INTERRUPTMASK); /* unmask */ nic->busy=0; /* V() */ t(K); return NOERR; } }
/*---------------------------------------------------------------------------*/ int main(void) { EEPROM_main(); int i; uip_ipaddr_t ipaddr; struct timer periodic_timer, arp_timer; memcpy (&uip_ethaddr.addr[0], &eeprom.MAC[0], 6); AVR_init(); egpio_init(); clock_init(); mbuf_init(); adlc_init(); GICR = (1 << INT0); timer_set(&periodic_timer, CLOCK_SECOND / 2); timer_set(&arp_timer, CLOCK_SECOND * 10); nic_init(); uip_ipaddr(ipaddr, eeprom.IPAddr[0],eeprom.IPAddr[1],eeprom.IPAddr[2],eeprom.IPAddr[3]); uip_sethostaddr(ipaddr); uip_ipaddr(ipaddr, eeprom.Gateway[0],eeprom.Gateway[1],eeprom.Gateway[2],eeprom.Gateway[3]); uip_setdraddr(ipaddr); uip_ipaddr(ipaddr, eeprom.Subnet[0],eeprom.Subnet[1],eeprom.Subnet[2],eeprom.Subnet[3]); uip_setnetmask(ipaddr); telnetd_init(); aun_init(); internet_init(); egpio_write (EGPIO_STATUS_GREEN); while(1) { // check the econet for complete packets adlc_poller(); aun_poller (); uip_len = nic_poll(); if(uip_len > 0) { if(BUF->type == htons(UIP_ETHTYPE_IP)) { uip_arp_ipin(); 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. */ maybe_send(); } 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) { nic_send(NULL); } } } else if(timer_expired(&periodic_timer)) { timer_reset(&periodic_timer); for(i = 0; i < UIP_CONNS; i++) { uip_periodic(i); maybe_send(); } #if UIP_UDP for(i = 0; i < UIP_UDP_CONNS; i++) { uip_udp_periodic(i); maybe_send(); } #endif /* UIP_UDP */ /* Call the ARP timer function every 10 seconds. */ if(timer_expired(&arp_timer)) { timer_reset(&arp_timer); uip_arp_timer(); } } } }
/***************************************************************************** * Main Control Loop * * *****************************************************************************/ int main(void) { //led PB4 // Pins als Ausgänge definieren: DDRB |= (1 << 4); PORTB |= (0 << 4); //DDRD |= (1 << 7); //PORTD |= (1 << 7); unsigned char i; unsigned char arptimer=0; // init NIC device driver nic_init(); // init uIP uip_init(); // init app services_init(); // init ARP cache uip_arp_init(); // init periodic timer initTimer(); SET_USART_9600(); //PORTB |= (1 << 4); //LED PB4 ein sei(); // if((mca25_stat.init=mca25_init())==0) mca25_stat.init=mca25_configure(); // if(mca25_stat.init) { // print error message?; // } #if USE_MCA25_CAM //DEBUG: MCA25_ERROR_LED_OFF(); MCA25_CLOCK_LED_OFF(); //DDRB = 0xFF; MCA25_STATUS_LED_ON(); mca25_init(); mca25_configure(); MCA25_STATUS_LED_OFF(); MCA25_ERROR_LED_ON(); MCA25_CLOCK_LED_ON(); #endif // #if USE_CLOCK // Start_Clock(); //#endif #if USE_SERVO servo_init(); #endif //PORTD |= (1 << 7); while(1) { // look for a packet uip_len = nic_poll(); if(uip_len == 0) { // if timed out, call periodic function for each connection if(timerCounter > TIMERCOUNTER_PERIODIC_TIMEOUT) { timerCounter = 0; for(i = 0; i < UIP_CONNS; i++) { uip_periodic(i); // transmit a packet, if one is ready if(uip_len > 0) { uip_arp_out(); nic_send(); } } /* Call the ARP timer function every 10 seconds. */ if(++arptimer == 20) { uip_arp_timer(); arptimer = 0; } } } else // packet received { // process an IP packet if(BUF->type == htons(UIP_ETHTYPE_IP)) { // add the source to the ARP cache // also correctly set the ethernet packet length before processing uip_arp_ipin(); uip_input(); // transmit a packet, if one is ready if(uip_len > 0) { uip_arp_out(); nic_send(); } } // process an ARP packet else if(BUF->type == htons(UIP_ETHTYPE_ARP)) { uip_arp_arpin(); // transmit a packet, if one is ready if(uip_len > 0) nic_send(); } } } return 1; }
/***************************************************************************** * Main Control Loop * * *****************************************************************************/ int main(void) { unsigned char i; unsigned char arptimer=0; // PORTB PB5 als Ausgang (in use LED) DDRB=(1<<PB5); PORTB=(1<<PB5); init_sensors(); // init NIC device driver nic_init(); // init uIP uip_init(); // init app example1_init(); // init ARP cache uip_arp_init(); // init periodic timer initTimer(); sei(); // initialisierendes lesen der Temperatur(en) read_temp_sensors(); while(1) { if(minInt==1){ minInt=0; read_temp_sensors(); } // look for a packet uip_len = nic_poll(); if(uip_len == 0) { // if timed out, call periodic function for each connection //if(timerCounter > TIMERCOUNTER_PERIODIC_TIMEOUT) if(tInt) { tInt = 0; //timerCounter = 0; for(i = 0; i < UIP_CONNS; i++) { uip_periodic(i); // transmit a packet, if one is ready if(uip_len > 0) { uip_arp_out(); nic_send(); } } /* Call the ARP timer function every 10 seconds. */ if(++arptimer == 20) { uip_arp_timer(); arptimer = 0; } } } else // packet received { // process an IP packet if(BUF->type == htons(UIP_ETHTYPE_IP)) { // add the source to the ARP cache // also correctly set the ethernet packet length before processing uip_arp_ipin(); uip_input(); // transmit a packet, if one is ready if(uip_len > 0) { uip_arp_out(); nic_send(); } } // process an ARP packet else if(BUF->type == htons(UIP_ETHTYPE_ARP)) { uip_arp_arpin(); // transmit a packet, if one is ready if(uip_len > 0) nic_send(); } } } return 1; }
/* * This is a co-operative task. This function must NEVER return */ void uip_task_main(void) { //initialise all the connections to point to the invalid handle for( i = 0 ; i < UIP_CONNS; i++) { uip_conns[i].appstate[0] = FILE_INVALID_HANDLE; } while(1) { task_yield(); if( UIP_DMA_RX_PACKET_READY ) { UIP_DMA_RX_PACKET_READY = 0; uip_len = uip_dma_rx_last_packet_length; // packet received - buffer is already acquired // process an IP packet if(BUF->type == HTONS(UIP_ETHTYPE_IP)) { // add the source to the ARP cache // also correctly set the ethernet packet length before processing uip_arp_ipin(); uip_input(); // transmit a packet, if one is ready if(uip_len > 0) { uip_arp_out(); nic_send(); } else nic_rx_maybe(); } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) { // process an ARP packet uip_arp_arpin(); // transmit a packet, if one is ready if(uip_len > 0) { nic_send(); } else { nic_rx_maybe(); } } else //don't know how to process this packet. Discard { puts("Unknown packet discarded"); nic_rx_maybe(); } } else if(UIP_DMA_PERIODIC_TIMEOUT && uip_acquireBuffer()) { if( next_conn_id != UIP_CONNS ) { uip_len = 0; while( uip_len == 0 && next_conn_id < UIP_CONNS ) { uip_periodic( next_conn_id ); // transmit a packet, if one is ready if(uip_len > 0) { uip_arp_out(); nic_send(); } next_conn_id++; } } if( next_conn_id == UIP_CONNS ) { UIP_DMA_PERIODIC_TIMEOUT=0; //blink LED to show we're alive LD1_O = !LD1_O; next_conn_id = 0; /* Call the ARP timer function every 10 seconds. */ if(++arptimer == 20) { uip_arp_timer(); arptimer = 0; } uip_releaseBuffer(); //possibly change test below to if( uip_len == 0)?? if( ENC_DMACONbits.CHEN == 0 ) nic_rx_maybe(); } } else { //anyone need to send something or close? unsigned char loop_end = next_send_id; do { struct uip_conn *connptr = &uip_conns[next_send_id]; file_handle_t fh = connptr->appstate[0]; struct file_t *f = file_get_by_handle(fh); if(f != NULL && ( f->state == ClosePending || (f->write_buffer != NULL && buffer_available( f->write_buffer) > 0 && connptr->len == 0 ) ) ) { #ifdef __DEBUG printf("\n TCP conn id: %hhd state: %hhd. File State: %hhx", next_send_id, connptr->tcpstateflags, f->state); #endif if( connptr->tcpstateflags == CLOSED ) { #ifdef __DEBUG puts("\r\nFreed tcp conn and file "); #endif file_free( fh ); connptr->appstate[0] = FILE_INVALID_HANDLE; } if( uip_acquireBuffer() ) { uip_periodic_conn(connptr); if(uip_len > 0) { #ifdef __DEBUG printf("\n id %hhd sending", next_send_id); #endif uip_arp_out(); nic_send(); break; } else uip_releaseBuffer(); } break; //this connection wants to write. try again later } next_send_id = ++next_send_id < UIP_CONNS ? next_send_id : 0; } while( next_send_id != loop_end ); } } //end while }