RX Buffer Read Address offset error


#1

My first attempt at reading the RX buffer, on receipt of a UDP packet, showed that the second octed received was at the address of the first. I worked around this by taking 1 from the calulated address and was able to receive a UDP datagram payload as shown on page 69 of the manual.

Having added the offset correction, every other datagram was now incorrect, being out by one the other way around. I have managed to read expected data by adding the offset to every alternate datagram received.

The read code posted below:
> //--------------------------------------------------------------------------------------------------------------------------
> short WIZ_NewRX(int8 Skt){
> // 02 NOV 2018 - Returns true when data waiting to be fetched
> int16 SktOS; // Register offset for socket
>
> // Begin Here
> SktOS = 0x0100 * Skt;
> WIZa_ToGoRXQ = _WIZ_Get16(WIZ_REG_RX_SZ + SktOS); // Anything in the buffer
> return (WIZa_ToGoRXQ > 0); // Just the status
>
> }// End NewRX
> //--------------------------------------------------------------------------------------------------------------------------
> void WIZ_GetRX(int8 Skt){
> // 05 NOV 2018 - Testing theory of updateing the read pointer to change queue size, appears to work.
> int16 SktOS; // Register offset for socket
> int16 RecOS; // RX Buffer head offset
> int16 BufRX = 0x06000; // Base address of RX Buffers, less 1 for a reason yet to be determined
> int16 AdrRX; // Calculated read address, offset from start of buffer
> int8 Comd = 0x40; //
> static short Alt = TRUE; // Testing theory that every alternate read is off by one
>
> // Begin Here
> SktOS = (0x0100 * Skt); //
> BufRX += (0x0800 * Skt); // Address spave for buffer
> WIZ_PIN_CS = 0; // Chip Select
> // - - - - - - - - - - - - - - - - - - - - - - - // Figure out address from offset
> RecOS = _WIZ_Get16(WIZ_REG_RX_RD + SktOS); // Where to start reading from
> // RecOS = 0; // Testing **************************
> AdrRX = BufRX | RecOS; // Offset from start of Socket buffer
> if (Alt)AdrRX–; Alt = !Alt; // ******************************
> _WIZ_GoTo(AdrRX); // Set to address
> // - - - - - - - - - - - - - - - - - - - - - - - //
> while(WIZa_ToGoRXQ–){ // All the while there is data to process
> if(RecOS > 0x07FF){ // Time to circulate buffer
> RecOS = 0; // Restart
> _WIZ_GoTo(BufRX); //
> //
> }//End If //
> NET_Accept(Skt, _WIZ_Get08()); //
> RecOS++; // Match pointer
> //
> }//End While //
> // - - - - - - - - - - - - - - - - - - - - - - - //
> _WIZ_Put16(RecOS,WIZ_REG_RX_RD + SktOS); // Update the pointer
> _WIZ_Put08(Comd, WIZ_REG_SX_CR + SktOS); //
> for(;;){ // Till the above set command is cleared
> Comd = _WIZ_Get08(WIZ_REG_SX_CR + SktOS); //
> if (!bit_test(Comd, 6)) break; //
> //
> }//End For //
> WIZ_PIN_CS = 1; // Chip UnSelect
>
> }//End GetRX

Has any one seen anything similar? The Datagram payload length is 17 octets.
I will try sending different length datagrams to see if there is a boundry issue with the silicon.


#2

Hmmm. Stranger still.

If a UDP datagram with an even number of octets is received, then I’m always subtracting 1 from the real address to access the correct RX buffer data. With UDP datagrams with an odd number of Octest, the -1 offset is only applied alternately to read the correct data from the socket RX buffer.

Now looking to see if I can work the correct offset out from the RX Write pointer less the RX buffer size.
Will update again with anything new learned.


#3

There are not enough information about c function like _WIZ_GoTo(), NET_Accept, etc.
But, I guess this part occurs problem.

if(RecOS > 0x07FF){ // Time to circulate buffer
RecOS = 0; // Restart
_WIZ_GoTo(BufRX); //
//
}//End If //

if you set the socket# rx memory size to 2KB, you should not read data over 2KB.
And RecOS has 16-bit data. It can not be limited to less than 0x800.
Therefore, you should not set the rx memory address to the base address (BufRX) even if RecOS is greater than 0x0800.

WIZnet supports a example code at the below site.
https://wizwiki.net/wiki/doku.php?id=products:w5100s:driver_temp

We can support you easier, when you use our example code(ioLibrary_Driver).
If the problem will not be solved, we need more information about your source code.

I hope your problem will be solved. If not, please leave reply.

thanks.


#4
void _WIZ_GoTo(int16 Addr){
// 22 OCT 2018 - Common to Read and Write operations


// Begin Here
// WIZ_PIN_CS = 0;			// Chip Select
   TRISA = 0x00;			// Write Mode
   WIZ_PIN_A0 = 1;			// Address 0
   WIZ_PIN_A1 = 0;			// Address 1
   LATA = make8(Addr, 1);		// Address High Byte
   WIZ_PIN_WR = 0;			//
   delay_cycles(4);			// 4 * 6.25nS & 16MHz * 4 = 25ns
   WIZ_PIN_WR = 1;			//
   WIZ_PIN_A0 = 0;			// Address 0
   WIZ_PIN_A1 = 1;			// Address 1
   LATA = make8(Addr, 0);		// Address Low Byte
   WIZ_PIN_WR = 0;			//
   delay_cycles(4);			// 4 * 6.25nS & 16MHz * 4 = 25ns
   WIZ_PIN_WR = 1;			// End of second write
   WIZ_PIN_A0 = 1;			// Address := 3
// WIZa_NewAddr = TRUE;			// Global State

}//End

The NET_Accpet is the datagram processing function.

This I am aware of, however, I have not yet managed to receive much beyond 1K without hitting issues.

I have looked at this Atmel code. My implimentation uses a Microchip PIC18…

Since my last post, I have identified more strange things, when updating socket RX_RD pointer, reading back the value does not allways return the value written, and in some cases when it was previously something like 32, it may then read zero.
In relation to this, reading the socket buffer size may then also still be at the value is was prior to the read causing a continual read loop. Sending another datagarm to the WIZchip will then clear / change this value,
so I am not inclined to believe that there is an issue with reading the register.

For any one interested, I have also determined that reading one more octet from a socket RX buffer than reported by the socket RX_SZ register will override any value written to the RX buffer Read pointer and then report an RX_SZ buffer read size of 2047 bytes/octets. That is not explained in the manual…


#5

Hi all.

I have discovered something that may be useful to others, related to my last post.
If, when reading in a datagram from the RX buffer, data should then be written to the TX buffer in response,
be aware that moving the last read/write address pointer before completeing the RX cycle and calling RECV
may break setting the RX_RD socket pointer write. This in turn has the effect of not resetting the socket RX Size register, giving the impression that a new datagram has been received.

My advice, therefor, is to to ensure mutual exclusion of receive and send routines.

This point about reading the entire content of the RX buffer and then setting the RX_RD offset pointer
without interleave could be explained in the user manual or errata, if there be such a thing…