title: Unable to run input cature mode with SPI
body: <p>I am Trying to run a web-server on AVR ATmega8 using ENC28J60 module. For this I got sample code <a href="http://www.tuxgraphics.org/common/src2/article06111/eth_rem_dev_tcp-2.17.tar.gz" rel="nofollow">from here</a>. This code is working fine. Here is my code:-</p>
  
  <pre><code>#define F_CPU 8000000UL
  
  #include &lt;avr/io.h&gt;
  #include &lt;string.h&gt;
  #include "ip_arp_udp_tcp.h"
  #include "enc28j60.h"
  #include "timeout.h"
  #include "avr_compat.h"
  #include "net.h"
  
  // please modify the following two lines. mac and ip have to be unique
  // in your local area network. You can not have the same numbers in
  // two devices:
  static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x24};
  // how did I get the mac addr? Translate the first 3 numbers into ascii is: TUX
  static uint8_t myip[4] = {192,168,24,39};
  // listen port for www
  #define MYWWWPORT 80
  //// listen port for udp
  #define MYUDPPORT 1200
  //
  
  #define BUFFER_SIZE 450
  static uint8_t buf[BUFFER_SIZE+1];
  
  int main(void)
  {
  
      uint16_t plen;
      uint16_t dat_p;
      uint8_t i=0;
      uint8_t payloadlen=0;
  
      _delay_loop_1(50); 
  
      /*initialize enc28j60*/
      enc28j60Init(mymac);
      enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz
      _delay_loop_1(50); // 12ms
      enc28j60PhyWrite(PHLCON,0x476);
      _delay_loop_1(50); // 12ms
  
      //init the ethernet/ip layer:
      init_ip_arp_udp_tcp(mymac,myip,MYWWWPORT);
  
      while(1)
      {
          // get the next new packet:
          plen = enc28j60PacketReceive(BUFFER_SIZE, buf);
  
          /*plen will ne unequal to zero if there is a valid * packet (without crc error) */
          if(plen==0)
          {
              continue;
          }
          // arp is broadcast if unknown but a host may also
          // verify the mac address by sending it to 
          // a unicast address.
          if(eth_type_is_arp_and_my_ip(buf,plen))
          {
              make_arp_answer_from_request(buf);
              continue;
          }
          // check if ip packets (icmp or udp) are for us:
          if(eth_type_is_ip_and_my_ip(buf,plen)==0)
          {
          continue;
          }
  
  
          if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V &amp;&amp; buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V)
          {
              // a ping packet, let's send pong
              make_echo_reply_from_request(buf,plen);
              continue;
          }
          // tcp port www start, compare only the lower byte
          if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&amp;&amp;buf[TCP_DST_PORT_H_P]==0&amp;&amp;buf[TCP_DST_PORT_L_P]==MYWWWPORT)
          {
              if (buf[TCP_FLAGS_P] &amp; TCP_FLAGS_SYN_V)
              {
                  make_tcp_synack_from_syn(buf);
                  // make_tcp_synack_from_syn does already send the syn,ack
                  continue;
              }
              if (buf[TCP_FLAGS_P] &amp; TCP_FLAGS_ACK_V)
              {
                  init_len_info(buf); // init some data structures
                  // we can possibly have no data, just ack:
                  dat_p=get_tcp_data_pointer();
                  if (dat_p==0)
                  {
                      if (buf[TCP_FLAGS_P] &amp; TCP_FLAGS_FIN_V)
                      {
                          // finack, answer with ack
                          make_tcp_ack_from_any(buf);
                      }
  
                      // just an ack with no data, wait for next packet
                      continue;
                  }
                  if (strncmp("GET ",(char *)&amp;(buf[dat_p]),4)!=0)
                  {
                      plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n&lt;h1&gt;200 OK&lt;/h1&gt;"));
                  }
                  else
                  {
                      // Web Code
                      plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n&lt;p&gt;PLANETCAST MEDIA SERVICES LTD&lt;/p&gt;"));
  
                      plen=fill_tcp_data_p(buf,plen,PSTR("&lt;body&gt;"));
                      plen=fill_tcp_data_p(buf,plen,PSTR("&lt;input type=\"text\" id=\"myurl\" name=\"url\" placeholder=\"Enter Url\"/&gt;&lt;br&gt;"));
                      plen=fill_tcp_data_p(buf,plen,PSTR("&lt;input type=\"submit\" id=\"clickbutton\" name=\"Click Here\" /&gt;"));
                      plen=fill_tcp_data_p(buf,plen,PSTR("&lt;script type=\"text/javascript\"&gt;"));
                      plen=fill_tcp_data_p(buf,plen,PSTR("document.getElementById(\"clickbutton\").onclick = function(){"));                          
                      plen=fill_tcp_data_p(buf,plen,PSTR("var url = document.getElementById(\"myurl\").value;"));
                      plen=fill_tcp_data_p(buf,plen,PSTR("location.href=url;"));
                      plen=fill_tcp_data_p(buf,plen,PSTR("};"));
                      plen=fill_tcp_data_p(buf,plen,PSTR("&lt;/script&gt;"));   
                      plen=fill_tcp_data_p(buf,plen,PSTR("&lt;/body"));
                  }
  
  
                  make_tcp_ack_from_any(buf); // send ack for http get
                  make_tcp_ack_with_data(buf,plen); // send data
                  continue;
             }
  
        }
        // udp interface:
        if (buf[IP_PROTO_P]==IP_PROTO_UDP_V)
        {
          payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
          // the received command has to start with t and be 4 char long
          // e.g "test\0"
          if (buf[UDP_DATA_P]=='t' &amp;&amp; payloadlen==5)
          {
              make_udp_reply_from_request(buf,"hello",6,MYUDPPORT);
          }
        }
     }
     return (0);
  }
  </code></pre>
  
  <p>Now I want to add Input Capture Mode , so I add <code>interrupt header file</code> then start Input capture mode in main() and then introduce <code>sei()</code> function. Now My code look like this:-</p>
  
  <pre><code>#define F_CPU 8000000UL
  
  #include &lt;avr/io.h&gt;
  #include &lt;string.h&gt;
  #include "ip_arp_udp_tcp.h"
  #include "enc28j60.h"
  #include "timeout.h"
  #include "avr_compat.h"
  #include "net.h"
  #include &lt;avr/interrupt.h&gt;
  // please modify the following two lines. mac and ip have to be unique
  // in your local area network. You can not have the same numbers in
  // two devices:
  static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x24};
  // how did I get the mac addr? Translate the first 3 numbers into ascii is: TUX
  static uint8_t myip[4] = {192,168,24,39};
  // listen port for www
  #define MYWWWPORT 80
  //// listen port for udp
  #define MYUDPPORT 1200
  //
  
  #define BUFFER_SIZE 450
  static uint8_t buf[BUFFER_SIZE+1];
  
  int main(void)
  {
  
  
      TCCR1A = 0;
      TCCR1B = (1&lt;&lt;ICNC1)|(1&lt;&lt;ICES1)|(1&lt;&lt;CS11);
      TIMSK = (1&lt;&lt;TICIE1);
      TCNT1 = 0;
      sei();
      uint16_t plen;
      uint16_t dat_p;
      uint8_t i=0;
      uint8_t payloadlen=0;
  
      _delay_loop_1(50); 
  
      /*initialize enc28j60*/
      enc28j60Init(mymac);
      enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz
      _delay_loop_1(50); // 12ms
      enc28j60PhyWrite(PHLCON,0x476);
      _delay_loop_1(50); // 12ms
  
      //init the ethernet/ip layer:
      init_ip_arp_udp_tcp(mymac,myip,MYWWWPORT);
  
      while(1)
      {
          // get the next new packet:
          plen = enc28j60PacketReceive(BUFFER_SIZE, buf);
  
          /*plen will ne unequal to zero if there is a valid * packet (without crc error) */
          if(plen==0)
          {
              continue;
          }
          // arp is broadcast if unknown but a host may also
          // verify the mac address by sending it to 
          // a unicast address.
          if(eth_type_is_arp_and_my_ip(buf,plen))
          {
              make_arp_answer_from_request(buf);
              continue;
          }
          // check if ip packets (icmp or udp) are for us:
          if(eth_type_is_ip_and_my_ip(buf,plen)==0)
          {
          continue;
          }
  
  
          if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V &amp;&amp; buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V)
          {
              // a ping packet, let's send pong
              make_echo_reply_from_request(buf,plen);
              continue;
          }
          // tcp port www start, compare only the lower byte
          if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&amp;&amp;buf[TCP_DST_PORT_H_P]==0&amp;&amp;buf[TCP_DST_PORT_L_P]==MYWWWPORT)
          {
              if (buf[TCP_FLAGS_P] &amp; TCP_FLAGS_SYN_V)
              {
                  make_tcp_synack_from_syn(buf);
                  // make_tcp_synack_from_syn does already send the syn,ack
                  continue;
              }
              if (buf[TCP_FLAGS_P] &amp; TCP_FLAGS_ACK_V)
              {
                  init_len_info(buf); // init some data structures
                  // we can possibly have no data, just ack:
                  dat_p=get_tcp_data_pointer();
                  if (dat_p==0)
                  {
                      if (buf[TCP_FLAGS_P] &amp; TCP_FLAGS_FIN_V)
                      {
                          // finack, answer with ack
                          make_tcp_ack_from_any(buf);
                      }
  
                      // just an ack with no data, wait for next packet
                      continue;
                  }
                  if (strncmp("GET ",(char *)&amp;(buf[dat_p]),4)!=0)
                  {
                      plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n&lt;h1&gt;200 OK&lt;/h1&gt;"));
                  }
                  else
                  {
                      // Web Code
                      plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n&lt;p&gt;PLANETCAST MEDIA SERVICES LTD&lt;/p&gt;"));
  
                      plen=fill_tcp_data_p(buf,plen,PSTR("&lt;body&gt;"));
                      plen=fill_tcp_data_p(buf,plen,PSTR("&lt;input type=\"text\" id=\"myurl\" name=\"url\" placeholder=\"Enter Url\"/&gt;&lt;br&gt;"));
                      plen=fill_tcp_data_p(buf,plen,PSTR("&lt;input type=\"submit\" id=\"clickbutton\" name=\"Click Here\" /&gt;"));
                      plen=fill_tcp_data_p(buf,plen,PSTR("&lt;script type=\"text/javascript\"&gt;"));
                      plen=fill_tcp_data_p(buf,plen,PSTR("document.getElementById(\"clickbutton\").onclick = function(){"));                          
                      plen=fill_tcp_data_p(buf,plen,PSTR("var url = document.getElementById(\"myurl\").value;"));
                      plen=fill_tcp_data_p(buf,plen,PSTR("location.href=url;"));
                      plen=fill_tcp_data_p(buf,plen,PSTR("};"));
                      plen=fill_tcp_data_p(buf,plen,PSTR("&lt;/script&gt;"));   
                      plen=fill_tcp_data_p(buf,plen,PSTR("&lt;/body"));
                  }
  
  
                  make_tcp_ack_from_any(buf); // send ack for http get
                  make_tcp_ack_with_data(buf,plen); // send data
                  continue;
             }
  
        }
        // udp interface:
        if (buf[IP_PROTO_P]==IP_PROTO_UDP_V)
        {
          payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
          // the received command has to start with t and be 4 char long
          // e.g "test\0"
          if (buf[UDP_DATA_P]=='t' &amp;&amp; payloadlen==5)
          {
              make_udp_reply_from_request(buf,"hello",6,MYUDPPORT);
          }
        }
     }
     return (0);
  }
  
  
  ISR(TIMER1_CAPT_vect)
  {
      //do something
  }
  </code></pre>
  
  <p>Now when I run my code , I got no webpage on my browser. So, I comment out <code>sei()</code> function. After this my code works fine. So, I check SPI settings in <code>enc28j60.c</code>. As per my knowledge SPI is not running on interrupt , so it shouldn't be affected by <code>sei()</code>. Here is my SPi settings in <code>enc28j60.c</code>:-  </p>
  
  <pre><code>#define ENC28J60_CONTROL_PORT   PORTB
  #define ENC28J60_CONTROL_DDR    DDRB
  #define ENC28J60_CONTROL_CS     2
  #define ENC28J60_CONTROL_SO 4
  #define ENC28J60_CONTROL_SI 3
  #define ENC28J60_CONTROL_SCK 5
  
  void enc28j60Init(uint8_t* macaddr)
  {
      // initialize I/O
          // ss as output:
      ENC28J60_CONTROL_DDR |= 1&lt;&lt;ENC28J60_CONTROL_CS;
      CSPASSIVE; // ss=0
          //  
      ENC28J60_CONTROL_DDR  |= 1&lt;&lt;ENC28J60_CONTROL_SI | 1&lt;&lt;ENC28J60_CONTROL_SCK; // mosi, sck output
      cbi(ENC28J60_CONTROL_DDR,ENC28J60_CONTROL_SO); // MISO is input
          //
          cbi(ENC28J60_CONTROL_PORT,ENC28J60_CONTROL_SI); // MOSI low
          cbi(ENC28J60_CONTROL_PORT,ENC28J60_CONTROL_SCK); // SCK low
  </code></pre>
  
  <p>So, can anyone tell me why my SPI mode is geting effected by sei() function and how get rid of this.</p>