WIZnet Developer Forum

Managing RX buffer pointers

I’m new to Wiznet. I have a wiz550io connected to a Microchip 16F1847.
After resetting the wiz550io, I can receive a packet, and send a packet via TCP. I can’t set up for the next packet.
I’m comparing the Sn_RX_RD to the Sn_RX_WR to see if new data came. After reading the packet, I try to advance the Sn_RX_RD to equal the Sn_RX_WR. It doesn’t store the new Sn_RX_RD value. As a consequence, I always think I’ve received new data via TCP.

This is my reset code:

void reset_RXBUFF_PNTRS(){
output_low(SPI_ENABLE);
spi_write(0x00);
spi_write(SOCR_RX_RD0); //0x28
spi_write(SOC0_REG|SPI_CNT_CNT_WR|SPI_OP_MODE1); //0x08|0x04|0x01 or 0xD
spi_write(SOCK_RX_WR_BF_PNT_MSB); //example 1
spi_write(0x00);
spi_write(SOCR_RX_RD1); //0x29
spi_write(SOC0_REG|SPI_CNT_CNT_WR|SPI_OP_MODE1); //0x08|0x04|0x01 or 0xD
spi_write(SOCK_RX_WR_BF_PNT_LSB); //example 110
output_high(SPI_ENABLE);
delay_us(10);
}

I read the RD and WR pointers before running reset_RXBUFF_PNTRS()
I read the RD and WR pointers after running reset_RXBUFF_PNTRS() and there is absolutely no change.

Once I get this understood and operational, I will have to figure out how to handle the roll over.

It would be a whole lot easier to re-set the WR pointer to zero. Is the RX_WR pointer a read only register?
How should I handle the roll over? With a 2K buffer, mask the address with 0x03FF?

Thanks!

Mike,

Please refer to W5100 datasheet wiznet.co.kr/wp-content/uplo … v1.2.6.pdf for detailed explanation of pointer management - starting with Chapter 5 “Functional description”. W5500 is similar to W5100 in design, thus most rules will apply.

You already have register called Sn_RX_RSR, which has the same information you need.

This is correct - to have Sn_RX_RD pointer change you should issue RECV command. Until you do it, RD pointer will read old value.

Even though there’s a window for data - for example 2kB which means relative offset 0-7ff within the socket’s buffer, you should use 16-bit pointers. For example, if Sn_RX_RD is equal to 0x9f76, if you received 0x2e5 bytes, updated pointer you write back is 0xa25b.

Datasheet is clear about it:
Sn_RX_WR (Socket n RX Write Pointer Register) [R] [0x002A-0x002B] [0x0000]

No, 2K is 0x800, thus mask is 0x7ff. Read theory in W5100 datasheet, and you will understand.

Thankyou for you response to my question.
I wish I could say everything worked fine, but no change.
This is what I’m doing to set the receive buffer read pointer:

void reset_RXBUFF_PNTRS(){
output_low(SPI_ENABLE);
spi_write(0x00);
spi_write(SOCR_RX_RD0); //0x28
spi_write(SOC0_REG|SPI_CNT_CNT_WR|SPI_OP_MODE1); //0x08|0x04|0x01 or 0x0D
spi_write(SOCK_RX_WR_BF_PNT_MSB); //example 1
spi_write(0x00);
spi_write(SOCR_RX_RD1); //0x29
spi_write(SOC0_REG|SPI_CNT_CNT_WR|SPI_OP_MODE1); //0x08|0x04|0x01 or 0x0D
spi_write(SOCK_RX_WR_BF_PNT_LSB); //example 110
spi_write(SOCK_RX_RD_BF_PNT_MSB); //0
spi_write(SOCK_RX_RD_BF_PNT_LSB); //0
spi_write(SOC0_RX_BF|SPI_CNT_CNT_RD|SPI_OP_MODE1); //0x18|0x00|0x01 or 0x1D
RXDATA_BYTE=spi_read(0); //RECV command
output_high(SPI_ENABLE);
delay_us(10);
}

This is what I do to read the pointers:

void read_sock0_RX_buff_pointer(){
output_low(SPI_ENABLE);
spi_write(0x00);
spi_write(SOCR_RX_RD0); //0x28
spi_write(SOC0_REG|SPI_CNT_CNT_RD|SPI_OP_MODE1); //0x08|0x00|0x01 or 0x09
SOCK_RX_RD_BF_PNT_MSB=spi_read(0);
spi_write(0x00);
spi_write(SOCR_RX_RD1); //0x29
spi_write(SOC0_REG|SPI_CNT_CNT_RD|SPI_OP_MODE1);
SOCK_RX_RD_BF_PNT_LSB=spi_read(0);
output_high(SPI_ENABLE);
SOCK_RX_RD_BF_PNT=(SOCK_RX_RD_BF_PNT_MSB*256); //build 16 bit address from two bytes.
SOCK_RX_RD_BF_PNT=(SOCK_RX_RD_BF_PNT+SOCK_RX_RD_BF_PNT_LSB);
}

Socket 0 receive buffer read pointer stays at zero regardless what I do.

Thanks in advance.

Ahah! This is what was meant by a RECV command:

spi_write(0);
spi_write(SOCR_CR);
spi_write(SOC0_REG|SPI_CNT_CNT_WR|SPI_OP_MODE1);
spi_write(0x40);	//send RECV command

When I finally did it, the Sn_RD_RX buffer pointer finally updated.
Thanks for the help. When you understand the instruction and do it, things work.

Just curious, obviously RECV doesn’t mean receive. What does it mean?

It makes chip send acknowledge for already received data, requesting more data from remote device. I simplify a bit, but you get the idea.

Hello there…
is there any way to reset the Sn_RX_WR to 0 ? because eventually Sn_RX_WR will exceed the maximum buffer size (default is 2K which is 0x07FF)
i know if i close/disconnect the socket and reconnect it, the pointers will reset to 0, but i don’t want to do that. I want to keep the connection alive. Please give me suggestion.

Copyright © 2017 WIZnet Co., Ltd. All Rights Reserved.