S0_RX_WR not returning to RX_RD after overflow
Ethernet Chips
No replies yet. Be the first to reply.
Join the discussion.
Ethernet Chips
No replies yet. Be the first to reply.
Join the discussion.
Share projects and connect with makers.
Joined before the site update? first.
New to WIZnet Makers?
We sent a verification link to your address. Open it to activate your account, then log in.
Accounts from this email provider are reviewed by an administrator after verification. Approval usually takes one business day.
Already have an account?
Enter your email address. If it belongs to an account, we'll send a link to set a new password. Members who joined before the site update use this to set their password.
If an account uses that address, we sent a link to set a new password. The link works once and expires in 30 minutes.
Know your password?
Need an account?
RE: S0_RX_WR not returning to RX_RD after overflow
by hjjeon0608 ·
Hi, crod.
You should mask Sn_RX_WR also.
It is physical address. 2050 is logical address.
If you don’t understand, see reference code in WIZnet’s web.
Best regards.
RE: S0_RX_WR not returning to RX_RD after overflow
by jameskim ·
Hi crod,
You seem to be misunderstanding the mechanisam of buffer handling of W5100.
Sn_RX_RD, Sn_RX_WR, Sn_TX_RD and Sn_TX_WR registers are used as another purpose internally.
So, every pointer registers have the range to 4G byte map of 32bits length address internally.
But W5100 has 2K bytes physical Tx and Rx buffer per socket respectively.
in other words, we need memory mapping from logical address to physical address.
But this doesn’t mean that you should remap all these registers to 2K address range by force.
You have not to change the value of all pointer register to value within address range of 2K size.
Instead of this, in order to get data properly you have to follow below procedure.
First, you should not remap the value of Sn_RX_RD itself to real address.
For example, when Sn_RX_RD should be changed to 2050 after receiving 50 bytes, don’t update its value to 2(= 2050 - 2048).
Instead, update your function handling data receipt like below.
[code]void recv_data_processing(SOCKET s, uint8 *data, uint16 len)
{
uint16 ptr;
uint16 size;
uint16 src_mask;
uint8 * src_ptr;
ptr = IINCHIP_READ(Sn_RX_RD0(s));
ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_RX_RD0(s) + 1);
#ifdef DEF_IINCHIP_DBG
printf(" ISR_RX: rd_ptr : %.4x\r\n", ptr);
#endif
src_mask = (uint32)ptr & getIINCHIP_RxMASK(s);
src_ptr = (uint8 *)(getIINCHIP_RxBASE(s) + src_mask);
if( (src_mask + len) > getIINCHIP_RxMAX(s) )
{
size = getIINCHIP_RxMAX(s) - src_mask;
IINCHIP_READ_BLOCK((uint32)src_ptr, (uint8*)data,size);
data += size;
size = len - size;
src_ptr = (uint8 )(getIINCHIP_RxBASE(s));
IINCHIP_READ_BLOCK((uint32)src_ptr, (uint8) data,size);
}
else
{
IINCHIP_READ_BLOCK((uint32)src_ptr, (uint8*) data,len);
}
ptr += len;
IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
}
[/code]
This is a function in the driver of W5200.
If you see this function, you will be able to find what you did wrong and should change in your code.
1)First, it reads Sn_RX_RD
2)Then, it reads RxMASK. This can be changed according to users’ memory allocation
3)Then, it reads its Physical address’ base address
4)And it calculates its physical address to read data from its peer
For example, I suppose that Socket 0, 2K bytes RX buffer, current S0_RX_RD is 0x07CF(= 2000 in decimal) and Socket 0 received 50 bytes.
Because RxMASK is 0x7FFF, src_mask above code is 0x07CF(0x07CF & 0x7FFF).
And src_ptr is 0xC7CF(= RxBASE(0xC000) + src_mask(0x07CF))
At this case, src_mask + len exceeds RxMAX size.
So, we have to read data in two step.
5) Read data from RX buffer
6) Finally, it updates S0_RX_RD pointer register with its original value added by the length of data.
ptr += len; IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8)); IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));In case of our example, S0_RX_RD will be 0x0802, not 0x0002.(S0_RX_WR is also 0x0802)
If Socket 0 receives another 10 bytes, then S0_RX_WR will be changed to 0x080C.
Please refer to the driver of W5200 on WIZnet’s website.
Thanks.
javakys
RE: S0_RX_WR not returning to RX_RD after overflow
by crod ·
Thanks, that works!!!
Thank you so much for the help, I really appreciate it!
Best regards,
Christian
RE: S0_RX_WR not returning to RX_RD after overflow
by jameskim ·
You’re welcome.
It’s my pleasure.