Socket Size Registers being read multiple times?

I would like to know why the Sn_TX_FSR and Sn_RX_RSR registers are read multiple times. Is it because their values change after a command is executed? If so, is that the only reason?


Yes, It’s because data can come into the chip while a command is executed. And yes, It’s the only reason.


Interesting. I wonder if that applies to the 2 bytes on the headers of UDP/IPRaw/MacRaw payloads. Can the 2 bytes header be wrong because more data arrived between the time I read the it and the time I finish reading the payload? For example, the 2 bytes header indicates there’s 100 bytes to be read. So I proceed to read 100 bytes, but before I finish reading 100 bytes, another 80 bytes arrived, but I will only read 100. What then?
Or the 2 bytes header value is only written once, meaning every time data arrives, it will be in a different payload?

Also, does reading Sn_RX_RSR at least twice guarantees that more data didn’t arrive between the the time I read it the second time and the time I started reading the RX memory? Or is it just supposed to be a small workaround?

And somewhat unrelated to the main topic, but not completely, and because I’m curious about how the inner-workings of the chip:

The datasheet states that the Sn_RX_RD and Sn_TX_WR registers change value after RECV and SEND commands. Why? Only their counterparts, Sn_RX_WR and Sn_TX_RD, should change values, indicating that data arrived or that data was sent. I assume we’re talking about a standard ring buffer implementation. Maybe we aren’t.

And how does the Sn_IR detects that there is still data to be read in order to keep the RECV bit as 1, even after attempting to clean the register? Does it derives this information from the RX buffer pointers, like Sn_RX_RD and Sn_RX_WR are not equal, or Sn_RX_RSR is not zero, or what?

It is different for each mode and is described in the datasheet. Please refer to the image captured in the datasheet below.


After reading 100 bytes, you can read RX_RSR to check 80 bytes and recv 80 bytes.

For example, Sn RX_RSR value is calculated as Sn_RX_RD-Sn_RX_WR. The value of Sn_RX_RD is increased when the received data is accumulated in the buffer, and the Sn_RX_WR value is increased by sending the Recv Command after taking the data from the receive buffer and increasing the Sn_RX_WR value.

I think I said it in a way that was open to be interpreted as all 3 modes having the same 2 bytes header like MAC_RAW. I apologize for not being clear enough.
What I meant was I only care about the 2 bytes, because I’m interested in the MAC_RAW mode only.

But what if I don’t read RX_RSR, but read the RX memory and go for the MAC_RAW header instead? Would there be another header + payload there? In other words, can I ignore RX_RSR completely if I use MAC_RAW mode? For instance, In my code below, recvfrom doesn’t take any size parameters, and I only read the S0_RX_RD register:

I think you mixed them up. What you’re calling Sn_RX_RD is actually the Sn_RX_WR, and vice-versa. But I’ll continue using your notation.

So the value changes because I changed it, and not because of the successful execution of the SEND/RECV commands, right? That’s my point. And yet, the datasheet states (at the bottom of the image):

which make no sense.

@becky @bangbh any follow up?

Come on, guys. I could really use the help, and I don’t like bumping threads.