Clearing receive pointers in WIZNET3100 makes ACK


I am using WIZNET3100 for Ethernet for long time in PLCs,
Found out that clearing receive pointers activate the WIZNET3100 to send intrinsa ACK.
My question is why?

clearing receive pointers is:

void ClearReceivePointers ( byte bSocket )
unsigned int wDummy;

wDummy = *ShadowRxWriteRegister(bSocket);
unWrPtr.bVal[3] = (byte)(*(RxWritePointerRegister(bSocket) + 0));
unWrPtr.bVal[2] = (byte)(*(RxWritePointerRegister(bSocket) + 1));
unWrPtr.bVal[1] = (byte)(*(RxWritePointerRegister(bSocket) + 2));
unWrPtr.bVal[0] = (byte)(*(RxWritePointerRegister(bSocket) + 3));

wDummy = *ShadowRxReadRegisters(bSocket);
unRdPtr.bVal[3] = (byte)(*(RxReadPointerRegister(bSocket) + 0));
unRdPtr.bVal[2] = (byte)(*(RxReadPointerRegister(bSocket) + 1));
unRdPtr.bVal[1] = (byte)(*(RxReadPointerRegister(bSocket) + 2));
unRdPtr.bVal[0] = (byte)(*(RxReadPointerRegister(bSocket) + 3));

if ( unWrPtr.dwVal != unRdPtr.dwVal )
	// Update REGS for data taken:
	*(RxReadPointerRegister(bSocket) + 0) = (word)unWrPtr.bVal[3];
	*(RxReadPointerRegister(bSocket) + 1) = (word)unWrPtr.bVal[2];
	*(RxReadPointerRegister(bSocket) + 2) = (word)unWrPtr.bVal[1];
	*(RxReadPointerRegister(bSocket) + 3) = (word)unWrPtr.bVal[0];
Command Register(bSocket) = 0x0040;




I’m sorry I don’t understand your question?

What is “intrinsa ACK” ?

W3100 have 4 byte pointer registers such as RX_RD, RX_WR, TX_RD, TX_WR and TX_ACK.

For safety reading these registers, you should read the related shadow registers like as your code.

While RX_WR, TX_RD, TX_ACK pointers antomaticially managed by W3100, RX_RD, TX_WR pointers should be manually managed by you.

Thank you.


You are right the pointers managed by me,
This is the strange thing -
If the WIZNET3100 was in transmission proccess,
and it stop by clearing the receive pointers, it sends TCP ACK number of times - why?



[quote]If the WIZNET3100 was in transmission proccess,
and it stop by clearing the receive pointers, it sends TCP ACK number of times - why?[/quote]

Im sorry, I don’t understand what is your question. the receive pointer is what? Sn_TX_RD?
Among TCP Tx pointer registers as Cn_TW_PR, Cn_TR_PR, Cn_TA_PR, You can only update the Cn_TW_PR, the others is read only.

Can you explain to me more detail?

Thank you.


I will try to explain the problem again.
I am using WIZNET3100 incorporated into a PLC controller, it works fine.
While the WIZNET3100 is in transmission process, and the PLC enters Sleep mode, it clears the receive pointers.
The process of clearing the pointers for socket 0 is:

  • reading C0_SRW_PR ( the shadow register)

  • waiting Tx_CLK * 4

  • reading C0_ RW_PR to xx_rw

  • reading C0_SRR_PR ( the shadow register)

  • waiting Tx_CLK * 4

  • reading C0_ RR_PR to xx_rr

  • If the value of xx_rw is different from the value in xx_rr, the value xx_rw is written to C0_ RR_PR.

  • At the end, the value 0x0040 is written to C0_CR.
    If I check at that point with a communication sniffer, I see that the WIZNET3100 sends ACK to the network.
    My question is why it sends the ACK?


Cn_RW_PR & Cn_RR_PR is used for receiving data in Cn’s Rx memory.
Cn_RW_PR is read only and It updated by W3100. Cn_RR_PR shoul be updated by you.
If you want to update the Cn_RR_PR,

  1. Reading Cn_RR_PR with Cn_SRR_PR
  2. Read data from Cn_RR_PR to Cn_RR_PR + read size
  3. Update Cn_RR_PR. Cn_RR_PR = Cn_RR_PR + read size
  4. Command RECV in Cn_CR.

Notice that W3100’s all pointer register are masked with Cn’s RX or TX memory size. Because W3100’s data memory is managed like as ring-buffer.

After RECV command, W3100 send the ack packet to the peer. the ack packet means notifying the data from the peer is received safely.

W3100 sending ACK cases are as following.

  1. After the configued time is expired after data is received and you do not anything.
  2. Command RECV in CN_cr.
  3. Immediately ACK send as soon as data is received. This case need to No-delay option.

Thank you.


Thank you,
You help me very much, with your explanation.
I have another question:
In your example of server/client of WIZNET 3100A, the calcutation of “receive data size” is:

EX0 = 0;
wr_ptr.cVal[0] = *RX_WR_PTR(s);
wr_ptr.cVal[1] = *(RX_WR_PTR(s) + 1);
wr_ptr.cVal[2] = *(RX_WR_PTR(s) + 2);
wr_ptr.cVal[3] = *(RX_WR_PTR(s) + 3);

rd_rd_ptr.cVal[1] = *(RX_RD_PTR(s) + 1);
rd_ptr.cVal[2] = *(RX_RD_PTR(s) + 2);
rd_ptr.cVal[3] = *(RX_RD_PTR(s) + 3);
EX0 = 1;

// Calculate received data size
if(len <=0) return 0;
else if (wr_ptr.lVal >= rd_ptr.lVal) size = wr_ptr.lVal - rd_ptr.lVal;
else size = 0 - rd_ptr.lVal + wr_ptr.lVal;
if(size == 0) return 0;

I am asking about the second case, that wr_ptr.lVal < rd_ptr.lVal,
In that case, needs to mask the result with the RMASK[s]?
for example:
2K allocation of the channel
Cx_RR_PR isincreased to 0x00123400, Cx_RW_PR isincreased to 0x00123280
size will be : 0xFE80, need to be (after mask with 0x7FF) 0x680.
May be I missed something, please explain it.


That case as you mentioned can not be happened.
Becasue the second case can be only happened when the RD pointer increased over the limitation 0xFFFFFFFF(32bit).

Without abnormal control the pointer register, Don’t worry about that.

Thank you.