Skip to content

Emergency Debugging Continued

August 29, 2015

First, I keep having to re-find the blog post I originally based the server on. It was done for the w5100 but it’s been a lot of help so herewith

Thanks again to rwb on ermicroblog
for http://www.ermicro.com/blog/?p=1773.

Once I had some hard data to look at, I realized I had the wrong idea about the failure.  Because the 1802 had gone unresponsive, I assumed it was in a tight loop or had hit an idle op code due to a memory overwrite.  The dump seemed to indicate that it was trucking along executing reasonable-looking instructions.  Doing a hand trace I found it was in a section of the “send0” routine that is checking for completion of a send.  It’s looking for the 0x10 bit to be set in SnIR but it never sees it.  Instead it is seeing 0x01 which is described in the data sheet as the connection interrupt http://www.mouser.com/pdfdocs/w5500_ds_v100e.PDF

Googling around I see someone with a similar issue on the W5100. It looks like this is something that can happen with some sort of send/receive/connect collision.
https://code.google.com/p/arduino/issues/detail?id=1049

The response from wiznet seems to indicate that by polling for the interrupt you could miss it. I think they recommend instead checking that SnTX_RD==SnTX_WR

In my original version of this for the w5100(adapted from the blog post referred to above) I never checked the interrupt register. I just made sure that the command register had been set to 0. I started checking the interrupt register when I was having big problems in february. Those problems were completely unrelated so i may just drop the whole interrupt register check.

I’m going to leave it alone for the weekend though since I seem to be the only one that can break it and it’s theoretically live for the VCFMW.

For my records:

16:59:17.748> memory from 2900
16:59:17.829> 0000: D3E2 8622 7396 5283 A693 B646 B346 A330
16:59:17.829> 0010: 00D3 86A3 96B3 42B6 42A6 3011 F824 FF01
16:59:17.909> 0020: 3A1E D5F8 00AF BF9D F6BD 8D76 AD3B 3B22
16:59:17.909> 0030: 8C52 8FF4 AF9C 529F 74BF 129D 3A41 8D32
16:59:17.909> 
16:59:17.909> registers 1-14
16:59:17.998> 0001: 0003
16:59:17.998> 0002: 7E73
16:59:17.998> 0003: 18C1
16:59:17.998> 0004: 2906
16:59:17.998> 0005: 2912
16:59:17.998> 0006: 1A68
16:59:17.998> 0007: 6969
16:59:17.998> 0008: 081A
16:59:17.998> 0009: 6819
16:59:18.103> 000A: 8569
16:59:18.103> 000B: 0820
16:59:18.103> 000C: 7B00
16:59:18.103> 000D: 0208
16:59:18.103> 000E: 087E
16:59:18.103> 
16:59:18.103> stack area
16:59:18.209> 7E60: DCF8 63AC 0003 7E73 18C1 2906 2912 1A68
16:59:18.209> 7E70: 6969 081A 6819 8569 0820 7B00 0208 087E
16:59:18.209> 7E80: 8400 0100 0307 4A00 021C 1F22 8000 0222
16:59:18.318> 7E90: 9821 1300 1000 0022 981C 1D00 6122 8022
16:59:18.318> 7EA0: 8201 3922 8022 8000 0100 0303 7327 4D1C
16:59:18.427> 7EB0: 0705 0227 3100 0002 0706 E402 0706 E100
16:59:18.427> 7EC0: 1000 0006 D000 0626 3C26 4300 060C 2300
16:59:18.427> 7ED0: 8000 800C FB00 170D 177F 0025 7A00 1714
16:59:18.522> 7EE0: 280A 0000 2807 0014 C0A8 00B6 0D8F 6900
16:59:18.522> 7EF0: 1428 0A00 1428 0700 17C0 A800 B60D 8F69
unsigned int send0(unsigned char *buf,unsigned int buflen){
    unsigned int timeout,txsize,txfree;
    unsigned char intval;
	unsigned int txwr;
	//printf("send0 %d\n",buflen);
    if (buflen <= 0) return 0;
    // Make sure the TX Free Size Register shows enough room
    txfree=wizGetCtl16(SnTX_FSR);
	//printf("free %d\n",txfree);
    timeout=0;
    while (txfree < buflen) {
      delay(1);
     txfree=wizGetCtl16(SnTX_FSR);
     // Timeout for approx 1000 ms
     if (timeout++ > 1000) {
       	printf("TX Free Size Error!\n");
		wizCmd(CR_DISCON);// Disconnect the connection
       	return 0;
     }
   }


   	txwr=wizGetCtl16(SnTX_WR);  // Read the Tx Write Pointer
   	wizWrite(txwr,WIZNET_WRITE_S0TX,buf, buflen); //write the outgoing data to the transmit buffer
   	wizSetCtl16(SnTX_WR,txwr+buflen);//update the buffer pointer
	wizCmd(CR_SEND); // Now Send the SEND command which tells the wiznet the pointer is updated
	intval=wizGetCtl8(SnIR); //get the interrupt status
	//printf ("post send interrupt status is %cx\n",intval);
	while((intval&0x10)!=0x10){ //wait for sendok status
		intval=wizGetCtl8(SnIR); //get the interrupt status
	}*****THIS IS WHERE I WAS LOOPING***
	wizSetCtl8(SnIR,0x15);//reset interrupt status
	//printf("Interrupt register reset\n");
    return 1;
}
Advertisements

From → web server

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: