TCP Server Sending Wrong Data Sometime


I configured the W5500 to be a server with no delay ACK (S0_MR(5) = 1) using socket 0 only. I wrote my own drivers and libs using TI TMS320F28335 MC.

My Tx data size is only 15 bytes, so I assume it will never exceed the max Tx size. Here is the process of preparing and sending data:

  1. Read the pointer address at S0_TX_WR
  2. Save my data to Tx buffer (BSB=0x02) beginning at the above pointer address to the size of my data (i.e. 15)
  3. Update S0_TX_WR (15+above pointer address)
  4. Command S0_CR = 0x20

Occasionally, the Tx data was wrong, and I captured a few of them here

Original data: 0 1 2 3 4 5 6 7 8 9 A B C D E
Data received from the client:
. Case 1: 0 1 2 3 4 5 6 0 0 9 A B C
. Case 2: 0 1 2 3 4 5 6 0 0 9 A B 0x1E

There are many others error in data, but this happened occasionally, and almost 4 or 5 out of 100 times of Tx.

Could you guy look into my process and see if I did any wrong here and give me your recommendation?

Thank you very much.

Print bytes you put into the TX buffer onto the screen / diagnostic console - literally - when you put byte to the TX buffer also print it onto the screen. It may happen there’s something corrupting characters during data move (e.g. interrupt routine not saving accumulator). Then check packets from the W5500 to see what data is in packets.

If this problem is not completely deterministic, maybe the SPI frequency is too high? Because with an increased frequency, the probability for errors also increases; furthermore the data that is transmitted from the host MCU to the W5500 doesn not have a checksum. You could try reading back your TX data after writing it to the buffer and see if the data matches

The W5500 datasheet says the device is stable up to SPI clock rates of 33.3MHz (Section 5.5.4 SPI Timing).

I know that, but I can’t see where OP mentioned that he does not exceed that frequency. Furthermore the chip’s SPI isn’t necessarily the only thing that might have trouble with a high clock frequency; Depending on the host MCU or the layout, other issues might arise too.

You made a valid point; I was providing more detail. Sadly, RTFM is a dying art.

1 Like

I thank you for that :slight_smile:

When I get this sort of issue, I mostly try drastically lowering the frequency, to verify whether it is an issue.
I think, that fact that 0x0C = 0000 1100 and 0x1E = 0001 1110 and that he said

might support this idea, because it looks like something is skewed.

You’re absolutely right.

Thanks for all of your helps.

I lowered my spi baud rate, and it helped a little not totally. However, it does not make sense unless my board is very noisy.

Did you try to implement a readback to see if the data makes it all the way to the chip?
Could you find any pattern as to under which circumstances this happens?
And out of curiousity: What was your frequency before and after, if I may ask?

Are there other SPI-connected devices in your system? If so, have you set their CS pin as an output and forced it to be HIGH?

Yes, I did. I verified data before updating S0_TX_WR pointer, and I found that occasionally few bytes of Tx data was loaded incorrectly when error occurred.

Not in pattern, but most of the time, error appeared to be coincidentally happened when the computer broadcast “Whohas”

I was running at 500Khz bit clock, and reduced to 50Khz…This does not help much - I think

There are a few more ICs (i.e. EEPROM, Encoder, and Switches) connected in the spi bus, but they should not be active because their CSx pins having pulled up resistors by default.

I’ve also seen that S0_SR having a few weird states such as 0x01, 0x02, 0x03 during disconnect and re-open the socket.

Where those the same bytes that ultimately were received wrong too?

Neither should be an issue

Only Pull-Up resistors? Or do you actively drive the pins high when de-selecting the devices? Did you verify the levels?

Do you maybe have oscilloscope screenshots of the SPI waveforms?

I drive the chip select pin (CS) low when communicate with the device, so I know for sure that others do not go low, except W5500 CS pin. Level had been verified too.

Monitoring S0_SR=0x14 listen mode

(Note: clock line has jitters due to the broken GND connector on the probe)


I found the issue, and it sounds weird.

I was reading S0_TX_RD as my TX pointer. After carefully reading the data sheet, I changed my pointer by reading S0_TX_WR. everything is correct after that.

What is the different between S0_TX_RD and S0_TX_WR beside [R] and [R/W], and as well as S0_RX_RD and S0_RX_WR?

When do we use them in the code?

Thanks y’all

TX_FSR is being calculated basing on the difference between these two pointers. RD is internal pointer for the stack, WR is pointer for driver data load into TX buffer.

Alright, it is clear. Thank you much for your clarification.