bug in wiznet spi driver produces short UDP packets
jstjohnz
Posts: 91
I was having a problem with some of my transmitted UDP packets being too short, and while debugging that I found what I'm pretty sure is a bug in the wiz5100 SPI driver.
This is the existing code (in txUDP):
'Write the data based on rolling over in the buffer or not
if (pcktoffset + payloadsize) > (_TX_mask + 1)
'process the data in two parts because the buffers rolls over
rolloverpoint := (_TX_mask + 1) - pcktoffset
writeSPI(true, pcktstart, _dataPtr, rolloverpoint)
pcktstart := (_TX_base + (_socket * $0800))
payloadsize -= rolloverpoint
writeSPI(true, pcktstart, (_dataPtr + rolloverpoint), payloadsize)
else
'process the data in one part
writeSPI(true, pcktstart, _dataPtr, payloadsize)
'Calculate the packet pointer for the next go around and save it
temp0 := (pcktptr + payloadsize)
pcktptr.byte[1] := temp0.byte[0]
pcktptr.byte[0] := temp0.byte[1]
writeSPI(true, (_S0_TX_WR0 + (_socket * $0100)), @pcktptr, 2)
The problem is the line:
payloadsize -= rolloverpoint
The payloadsize variable is no longer the payload size after this, and it is used a few lines later to update the tx write register on the wiz. This results in an incorrect value being written to the tx write register any time a packet wraps around the end of the buffer. The result will be that the transmitted packet is too short.
My fix was to add one line:
payloadsize -= rolloverpoint
writeSPI(true, pcktstart, (_dataPtr + rolloverpoint), payloadsize)
payloadsize+= rolloverpoint
to get the payloadsize variable value back where it belongs.
I haven't checked yet to see if this same issue is present in the TCP routines.
-jim-
This is the existing code (in txUDP):
'Write the data based on rolling over in the buffer or not
if (pcktoffset + payloadsize) > (_TX_mask + 1)
'process the data in two parts because the buffers rolls over
rolloverpoint := (_TX_mask + 1) - pcktoffset
writeSPI(true, pcktstart, _dataPtr, rolloverpoint)
pcktstart := (_TX_base + (_socket * $0800))
payloadsize -= rolloverpoint
writeSPI(true, pcktstart, (_dataPtr + rolloverpoint), payloadsize)
else
'process the data in one part
writeSPI(true, pcktstart, _dataPtr, payloadsize)
'Calculate the packet pointer for the next go around and save it
temp0 := (pcktptr + payloadsize)
pcktptr.byte[1] := temp0.byte[0]
pcktptr.byte[0] := temp0.byte[1]
writeSPI(true, (_S0_TX_WR0 + (_socket * $0100)), @pcktptr, 2)
The problem is the line:
payloadsize -= rolloverpoint
The payloadsize variable is no longer the payload size after this, and it is used a few lines later to update the tx write register on the wiz. This results in an incorrect value being written to the tx write register any time a packet wraps around the end of the buffer. The result will be that the transmitted packet is too short.
My fix was to add one line:
payloadsize -= rolloverpoint
writeSPI(true, pcktstart, (_dataPtr + rolloverpoint), payloadsize)
payloadsize+= rolloverpoint
to get the payloadsize variable value back where it belongs.
I haven't checked yet to see if this same issue is present in the TCP routines.
-jim-
Comments
You can PM him here.
Timothy Swieter may not be available to update the code, but this is an open-source project, so we can still continue on. We don't have a repository system up and running yet, but we can use the forums system to maintain code. If you create a new thread and post an updated version of Tim's code, then other users can post their own updates to the same thread. You could also add it to the collaborative projects thread at http://forums.parallax.com/showthread.php?127258-Collaborative-projects so that others could quickly find it.
David Carrier
Parallax Inc.
.