getting interrupts to work with ehternet

I am trying to use interrupts with the ethernet shield. I have soldered the jumper on the back. I am trying to run this small program:

const unsigned int CSPin = 53; // chip select/slave select
const unsigned int DataPin = 51; // Data out/MOSI
const unsigned int ClockPin = 52;

const unsigned int ledPin = 13;

volatile int iGotMessage = 0;

void setup()
{

    pinMode(CSPin, OUTPUT);
    pinMode(ledPin, OUTPUT);

    Serial.begin(19200);

    setupNetwork();

    attachInterrupt(0, gotMessage, LOW);
    Serial.println("exiting setup");
}
void loop()
{
    delay(1000);
    digitalWrite(ledPin, HIGH);
    delay(1000);
    digitalWrite(ledPin, LOW);

    if (iGotMessage == 1)
    {
        noInterrupts();
        Serial.println("got ethernet interrupt");
        HandleCommands();
        iGotMessage = 0;
        interrupts();
    }
}
void gotMessage()
{
    iGotMessage = 1;
}

This does not work. I connect to the server via telnet ip and port, I get connected, but the messages typed there never make it to the server. I never see the string "got ethernet interrupt" in the usb console. If I call HandleCommands directly in the loop, it works fine. Anything I am missing here. I tried RISING, LOW, HIGH for the attachInterrupt.

I have soldered the jumper on the back.

Soldered to what?

It seems unlikely that anything on the Ethernet shield is pulling a pin low when a client connects. But, I could be wrong.

What else is the Arduino going to be doing? If it's a server, processing client requests needs to be the top priority. Whatever else it is doing needs to not use delay() or other blocking functions/design. The loop() function must be called frequently. If it is, using interrupts will not enable servicing a client request faster.

there is a jumper on the back of the shield, when soldered, it connects the wiz5100 interrupt line to D2, which is interrupt 0 on mega.

Processing clients is not a priority, my other code is more time sensitive (which is just a dummy blink the led right now). No issues if a client has to wait for half a second extra. Performance optimizations come because when there is no message from the client, I just waste one instruction in checking for a boolean. If I dont use interrupts, I need to call client.connected and client.available, which definitely are much more expensive than a single instruction.

    attachInterrupt(0, gotMessage, LOW);

You want FALLING, not LOW.

http://www.gammon.com.au/interrupts

I tried with FALLING also, but it doesnt go into the interrupt handler.. I can see the rx/tx light blink whenever i send a character from the telnet session. I connected the scope also to the D2 line, but I dont see any activity on the scope. Checked the continuity of the solder joint, thats ok.

Did you set the w5100 interrupt mask register? Page 21 and 22 here: https://www.sparkfun.com/datasheets/DevTools/Arduino/W5100_Datasheet_v1_1_6.pdf

IMR (Interrupt Mask Register) [R/W] [0x0016] [0x00] The Interrupt Mask Register is used to mask interrupts. Each interrupt mask bit corresponds to a bit in the Interrupt Register (IR). If an interrupt mask bit is set, an interrupt will be issued whenever the corresponding bit in the IR is set. If any bit in the IMR is set as ‘0’, an interrupt will not occur though the bit in the IR is set.

It appears the default [0x00] is "no interrupts enabled".

No, I havent done that. will go through the doc you sent. How do I do this. Is there a sample code to do this somewhere that I can use. If not, How do I got about achieving this. I guess I will have to send some data using SPI to the w5100. I want interrupts only for new connection or new data.

Once I get an interrupt, I will go and process all the messages that are available, keeping the interrupts disabled during this time. After that I will enable the interrupts, but I would like to discard any interrupts that have queued up in the mean time. How do I do this. Would this take care of that: EIFR = bit (INTF0); // clear flag for interrupt 0

I modified the dhcp ip printer to read and set that register.

/*
  DHCP-based IP printer
 
 This sketch uses the DHCP extensions to the Ethernet library
 to get an IP address via DHCP and print the address obtained.
 using an Arduino Wiznet Ethernet shield. 
 
 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 
 created 12 April 2011
 by Tom Igoe
 
 */

#include <SPI.h>
#include <Ethernet.h>
#include <utility/w5100.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };

// Initialize the Ethernet client library
// with the IP address and port of the server 
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

int freeRam() {
  extern int __heap_start,*__brkval;
  int v;
  return (int)&v - (__brkval == 0 ? (int)&__heap_start : (int) __brkval);  
}

void setup() {
  // start the serial library:
  Serial.begin(9600);

  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  Serial.print(F("SRAM left: "));
  Serial.println(freeRam());
  
  // start the Ethernet connection:
  Serial.println("Starting ethernet");
  while (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    delay(5000);

  Serial.print(F("SRAM left: "));
  Serial.println(freeRam());


    Serial.println("trying DHCP again");
  }
  // print your local IP address:
  Serial.print("My IP address: ");
  for (byte thisByte = 0; thisByte < 4; thisByte++) {
    // print the value of each byte of the IP address:
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    Serial.print("."); 
  }
  Serial.println();

// get default IMR
  byte oldIMR = W5100.readIMR();
  
  Serial.print("Old IMR = ");
  Serial.println(oldIMR,HEX);
  
// enable interrupts for all sockets
  W5100.writeIMR(0x0F);

// read again to insure it worked
  byte newIMR = W5100.readIMR();
  
  Serial.print("New IMR = ");
  Serial.println(newIMR,HEX);
}

void loop() {
}

edit: You will probably need these functions also. They read and write (clear) the interrupt register (socket interrupt bits).

// read the interrupt register
byte newIR = W5100.readIR();
// reset the interrupt register
W5100.writeIR(0xE0);

Thanx, that made it better. I can see the IMR changing. I get the interrupt when I establish a connection and the connection gets established. But not when there is a message/data coming in. Went through the datasheet and it does say that I should get it for both connection and data. I tried enabling interrupts again and attachInterrupt, but no success. Here's the code

volatile boolean iGotMessage = false;

void setup()
{
    pinMode(CSPin, OUTPUT);
    pinMode(SD_CS_PIN, OUTPUT);
       pinMode(ledPin, OUTPUT);

    digitalWrite(SD_CS_PIN, HIGH);
    Serial.begin(19200);

    setupNetwork();

    // get default IMR
    byte oldIMR = W5100.readIMR();
  
    Serial.print("Old IMR = ");
    Serial.println(oldIMR,HEX);
  
    // enable interrupts for all sockets
    W5100.writeIMR(0x0F);

    // read again to insure it worked
    byte newIMR = W5100.readIMR();
  
    Serial.print("New IMR = ");
    Serial.println(newIMR,HEX);

    attachInterrupt(0, gotMessage, FALLING);
    Serial.println("exiting setup");
}

void loop()
{
    delay(1000);
    digitalWrite(ledPin, HIGH);
    delay(1000);
    digitalWrite(ledPin, LOW);

    if (iGotMessage == true)
    {
        noInterrupts();
        Serial.println("got ethernet interrupt");
        HandleCommands();
        iGotMessage = false;
        Serial.println("enabled interrupts");
        interrupts();
        attachInterrupt(0, gotMessage, FALLING);
    }
}
void gotMessage()
{
    iGotMessage = true;
}

Edit: Added the resetting of IR just before the interrupts call in the if (iGotMessage) block. No effect.

There is a lot to this. You must clear the Sn_IR register before you will get another interrupt for that socket. Page 27 of the datasheet.

Are you sure this is the way you want to do this?

Tried this to set it to all 0s and all 1s both… didnt work.

		for (int i = 0; i < 4; i++)
		{
			// read the socket and interrupt register
			byte newSnSR = W5100.readSnSR(i);
			Serial.print("socket and int register ");
			Serial.println(newSnSR, HEX);
			// reset the socket and interrupt register
			W5100.writeSnSR(i, 0xFF);
		}

My code is time critical. I have a lot to do within a few microseconds. Once I get a message, then there is no time issue and I can take my own sweet time to process all the messages. Would like to avoid polling if possible. This way, I waste only one instruction when there is no new message. Otherwise I will have to use client.connected and available just to check if there is a new message and I think these are quite expensive operations. I am anyway using these once I know that I have a message. If there is another very efficient way to check if there is a message, i can consider it.

Even if I dont end up using it, I still would like to see it work, good learning exercise…

                noInterrupts();
        Serial.println("got ethernet interrupt");
        HandleCommands();
        iGotMessage = false;
        Serial.println("enabled interrupts");
        interrupts();

Don't do serial prints with interrupts off. They use interrupts to work.