Skip to content

The Horror… The Horror…, but maybe an approach

February 16, 2015

So, I re-captured an initialization and receive/send sequence and continued my horrible python hacking. The python code is hidden down at the bottom of this post along with a description of the data streams.

The wiznet initialization sequence is different from mine because it sets all the transmit and receive buffer sizes to 2K. This is the default so i don’t do it. I have also bodged it to deliberately set the gateway ip address to something on the wrong subnet in hopes this was the problem but i don’t think it was.

0 001E 0C ['0x02'] 0x00 the first 16 commands
1 001F 0C ['0x02'] 0x00 set the tx & rx buffer sizes of each socket to 2K
2 001E 2C ['0x02'] 0x00
3 001F 2C ['0x02'] 0x00
4 001E 4C ['0x02'] 0x00
5 001F 4C ['0x02'] 0x00
6 001E 6C ['0x02'] 0x00
7 001F 6C ['0x02'] 0x00
8 001E 8C ['0x02'] 0x00
9 001F 8C ['0x02'] 0x00
10 001E AC ['0x02'] 0x00
11 001F AC ['0x02'] 0x00
12 001E CC ['0x02'] 0x00
13 001F CC ['0x02'] 0x00
14 001E EC ['0x02'] 0x00
15 001F EC ['0x02'] 0x00

16 0009 04 ['0xDE', '0xAD', '0xBE', '0xEF', '0xFE', '0xED'] set MAC
17 000F 04 ['0xC0', '0xA8', '0x01', '0xB1'] 0x00 set my IP
18 0001 04 ['0x0A', '0x00', '0x00', '0x01'] 0x00 set gateway
19 0005 04 ['0xFF', '0xFF', '0xFF', '0x00'] 0x00 set subnet mask

The socket initialization sequence is different only in that it sets the interrupt register to FF. I don’t know if this matters but i’ll try it.

20 0003 08 ['0x00'] 0x00  status socket 0 is closed
21 0001 0C ['0x10'] 0x00  command close socket 0
22 0001 08 ['0x00'] 0x00  check it's complete
23 0002 0C ['0xFF'] 0x00  set socket 0 interrupt to FF
24 0000 0C ['0x01'] 0x00  set socket 0 mode to tcp/ip
25 0004 0C ['0x00'] 0x00  set socket 0 port to 0050
26 0005 0C ['0x50'] 0x00
27 0001 0C ['0x01'] 0x00  command open socket 0  
28 0001 08 ['0x00'] 0x00  check it's complete
29 0003 08 ['0x00'] 0x13  socket is open in tcp/ip mode
30 0001 0C ['0x02'] 0x00  command listen on socket 0
31 0001 08 ['0x00'] 0x00  check it's complete

We then see a long period of polling the socket 0 status register waiting for it to change from 0x14 to 0x17 showing a session has been established.

Once it goes to 0x17, it initializes socket 1(!) and sets it to listening. I don’t know whether this is important but it would be a last resort to try coding it.

status listening on 0
1668 0003 08 ['0x00'] 0x17  reads the status as session established 3X
1669 0003 08 ['0x00'] 0x17
1670 0003 08 ['0x00'] 0x17

1671 0003 28 ['0x00'] 0x00  starts listening on socket 1
1672 0001 2C ['0x10'] 0x00
1673 0001 28 ['0x00'] 0x00
1674 0002 2C ['0xFF'] 0x00
1675 0000 2C ['0x01'] 0x00
1676 0004 2C ['0x00'] 0x00
1677 0005 2C ['0x50'] 0x00
1678 0001 2C ['0x01'] 0x00
1679 0001 28 ['0x00'] 0x00
1680 0003 28 ['0x00'] 0x13
1681 0001 2C ['0x02'] 0x00
1682 0001 28 ['0x00'] 0x00

Now the horror. We have received almost 350 bytes(0x015f). The code reads the length and the w5500 would happily slurp us the whole thing in one go but instead we painfully read one byte: check that we’re connected, read the buffer address, read one byte, update the buffer address, tell the chip we’ve updated it, check that the command is done. It then does this AGAIN for each of the received bytes! I don’t think this is any sort of deliberate belt-and-suspenders programming, it’s just the result of how the C++ code was written. Note that we don’t care about any of this, it’s just looking to see the blank line at the end of the data.

1683 0003 08 ['0x00'] 0x17  reads socket 0 status again

1684 0026 08 ['0x00'] 0x01  reads rx data length 2X
1685 0027 08 ['0x00'] 0x5F
1686 0026 08 ['0x00'] 0x01
1687 0027 08 ['0x00'] 0x5F

1688 0003 08 ['0x00'] 0x17  reads socket 0 status again
1689 0026 08 ['0x00'] 0x01  reads rx data length 4X
1690 0027 08 ['0x00'] 0x5F
1691 0026 08 ['0x00'] 0x01
1692 0027 08 ['0x00'] 0x5F
1693 0026 08 ['0x00'] 0x01
1694 0027 08 ['0x00'] 0x5F
1695 0026 08 ['0x00'] 0x01
1696 0027 08 ['0x00'] 0x5F
1697 0028 08 ['0x00'] 0x00  reads rx data pointer
1698 0029 08 ['0x00'] 0x00
RXD 0  47                   reads one byte of rx data ascii 47=G
1700 0028 0C ['0x00'] 0x00  writes the rx data pointer
1701 0029 0C ['0x01'] 0x00
1702 0001 0C ['0x40'] 0x00  tells the chip it has written the pointer
1703 0001 08 ['0x00'] 0x00  checks command completion

1704 0003 08 ['0x00'] 0x17  reads socket 0 status again
1705 0026 08 ['0x00'] 0x01  reads rx data length 4X(now shows 1 byte less)
1706 0027 08 ['0x00'] 0x5E
1707 0026 08 ['0x00'] 0x01
1708 0027 08 ['0x00'] 0x5E
1709 0026 08 ['0x00'] 0x01
1710 0027 08 ['0x00'] 0x5E
1711 0026 08 ['0x00'] 0x01
1712 0027 08 ['0x00'] 0x5E
1713 0028 08 ['0x00'] 0x00  reads rx data pointer
1714 0029 08 ['0x00'] 0x01
RXD 0  45                   reads one byte of rx data ascii 45=E
1716 0028 0C ['0x00'] 0x00
1717 0029 0C ['0x02'] 0x00
1718 0001 0C ['0x40'] 0x00
1719 0001 08 ['0x00'] 0x00
ad frigging nauseam!

Once it has read the whole incoming data stream, it sends a response back. The only difference i can see with my code is that it reads the socket 0 interrupt register looking for the 0x10 bit(send OK) to be set then rewrites the register clearing the rest of the bits. I might jump on this as being interesting but, in fact, it only ever has to read/write the register once i.e. the bit is set right away so it may be moot -easy to try though, at least back in florida.

7308 0003 08 ['0x00'] 0x17  still connected

7309 0024 08 ['0x00'] 0x7B  reads tx buf write pointer
7310 0025 08 ['0x00'] 0x04  7b04

7311 7B04 14 ['0x48', '0x54', '0x54', '0x50', '0x2F', '0x31', '0x2E', '0x30', '0x20', '0x32', '0x30', '0x30', '0x20', '0x4F', '0x4B', '0x0D', '0x0A', '0x43', '0x6F', '0x6E', '0x74', '0x65', '0x6E', '0x74', '0x2D', '0x54', '0x79', '0x70', '0x65', '0x3A', '0x20', '0x74', '0x65', '0x78', '0x74', '0x2F', '0x68', '0x74', '0x6D', '0x6C', '0x0D', '0x0A', '0x0D', '0x0A', '0x3C', '0x68', '0x74', '0x6D', '0x6C', '0x3E', '0x3C', '0x73', '0x70', '0x61', '0x6E', '0x20', '0x73', '0x74', '0x79', '0x6C', '0x65', '0x3D', '0x22', '0x63', '0x6F', '0x6C', '0x6F', '0x72', '0x3A', '0x23', '0x30', '0x30', '0x30', '0x30', '0x41', '0x30', '0x22', '0x3E', '0x0D', '0x0A', '0x3C', '0x63', '0x65', '0x6E', '0x74', '0x65', '0x72', '0x3E', '0x3C', '0x68', '0x31', '0x3E', '0x53', '0x69', '0x6D', '0x70', '0x6C', '0x65', '0x73', '0x74', '0x20', '0x53', '0x65', '0x72', '0x76', '0x65', '0x72', '0x20', '0x6F', '0x6E', '0x20', '0x57', '0x69', '0x7A', '0x6E', '0x65', '0x74', '0x20', '0x57', '0x35', '0x35', '0x30', '0x30', '0x3C', '0x2F', '0x68', '0x31', '0x3E', '0x3C', '0x2F', '0x63', '0x65', '0x6E', '0x74', '0x65', '0x72'] 0x00
..writes hdr1 text..
7312 0024 0C ['0x7B'] 0x00  updates tx write pointer
7313 0025 0C ['0x8C'] 0x00

7314 0001 0C ['0x20'] 0x00  issuse 'send' command
7315 0001 08 ['0x00'] 0x00  checks command complete

7316 0002 08 ['0x00'] 0x15  reads interrupt register
7317 0002 0C ['0x10'] 0x00  sets interrupt register to 0x10

The other interesting difference is that once it has sent all the data it issues the disconnect command and has to read the status several times before it clears. And it then starts polling on socket 1.

7332 0001 0C ['0x08'] 0x00  command disconnect
7333 0001 08 ['0x00'] 0x00  check complete

7334 0003 08 ['0x00'] 0x18  status 0x18 means socket is closing
7335 0003 08 ['0x00'] 0x18
7336 0003 08 ['0x00'] 0x18
7337 0003 08 ['0x00'] 0x00  now it's closed
7338 0003 08 ['0x00'] 0x00
status listening on 1
status listening on 1

So, things I can do:

  • set the gateway ip address properly for the comcast network
  • explicitly set the buffer sizes to 2k
  • set the interrupt register to ff before i open the socket
  • check and reset the interrupt register after the send
  • explicitly wait for the socket to show closed after i issue the disconnect
  • start a second socket listening when i am processing the first one. (this seems like too much work but…)

I’m going to read about the interrupt register and have a good look at the olduino logic trace and see if i see any other differences.

def emit2(opcode,addr):
    if opcode=='08' and addr=='0003' and misolist[-1]=='0x14':
        print 'status listening on 0'
    elif opcode=='28' and addr=='0003' and misolist[-1]=='0x14':
        print 'status listening on 1'
    elif opcode=='18' :
        print 'RXD 0 ',misolist[-1][2:]
        print oldid,addr,opcode,mosilist[3:],misolist[-1]
def emit():
    global oldid,misolist,mosilist
    if oldid!='zz':
def accumulate(id,miso,mosi):
    global misolist,mosilist
def handleoneline(oneline):
    global oldid
    parts=line.strip().split(',') #Time [s],Packet ID,MOSI,MISO
    #print id,mosi,miso
    if id!=oldid:

with open('/Users/bill/Desktop/arduinowronggateway.csv') as fp:
    global count
    for line in fp:
        #print line
        if count>1:

The base data from the logic analyzer is shown below. Each line contains a time stamp, a packet id(changes every time /SS is cycled), the contents of MOSI as output by the master(olduino), and MISO as output by the slave W5500. The python code assembles the data from each packet as:
id addr op [OO] ii where id is the packet id, addr is the first two bytes of MOSI data, op is the third, [OO..] is any remaining MOSI bytes and ii is the last byte of any MISO data.
addr is the register or data address being written to or read in the w5500, op is the opcode, OO is the data being written if any and ii is the data being read back. for example, the first packet gets formatted as:
0 001E 0C [‘0x02’] 0x00
where 0C says we’re writing to a register for socket 0, 001E says it’s the transmit buffer size and the data we’re writing is the 0x02 meaning 2K bytes. The interpretation comes from the w5500 data sheet.

Time [s],Packet ID,MOSI,MISO

From → web server

One Comment

Trackbacks & Pingbacks

  1. Telnet/Putty Preamble | olduino

Leave a Reply

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

You are commenting using your 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: