TX/RX NOT WORKING IN UDP MODE FOR W5300

Hi all,

I am using w5300 in my design . I use 8bit data bus to interface w5300 with my 32 bit MCU.
I have configured the w5300 to respond to ping commands. I have also sucessfully carried out the internal TX/RX memory checks.
when I am trying to do the UDP loopback using the sample code provided by wiznet team I am facing problems
I am using the hercules utility from PC to transmit few(<10) bytes to w5300. but the Sn_RX_RSR register is not showing the correct length of the data received & keeps changing even when the data is stopped.
Also when Iam trying to transmit data from w5300 to PC after writing in the internal memory the data is not getting transmitted at all.
Iam restrictly adhering to the sample code given by wiznet team. but no sucess till now. plz help.
kindly note that the mode registers & status registers are all working normal.
for transmission my sequence is

  1. set the mode as UDP (0x2)
  2. open socket
  3. wait for SSR to show 0x22. set DIPR & DPORTR
  4. write into internal tx memory using FIFO registers
  5. set the TX_WRSR size
  6. issue send data command
    7)wait till the command is executed

for reception my sequence is

  1. set the mode as UDP (0x2)
  2. open socket
  3. wait for SSR to show 0x22
  4. check for received data size Sn_RX_RSR is non zero
  5. read data from internal memory by FIFO register

what I observe is that in loopback mode the w5300 is sending back some magicpacket in WOL protocol… when i tx some packets to w5300 in UDP mode.

Anyone kindly help

Regards
shijesh

I don’t think you can solve the problem right now with your explanation.

First, please review the iolibrary we provided.
After sending the send/recv command, you have to wait until it is cleared.

Hi there,

Thanks for replying.

I am using the hercules utility from PC to transmit few(<10) bytes to w5300. but the Sn_RX_RSR register is not showing the correct length of the data received & keeps changing even when the data is stopped.
I have verified from wireshark that data is getting transmitted to W5300.
why is this happening kindly explain???
I will send u the copy of my entire code .

Regards
shijesh

Here is my code which Iam using. kindly go through the same.

Main()
{
uint16 data_buf = (uint16) 0xC000; // buffer for loopback data
wiz_sysinit ();
while (1)
{
loopback_udp (7, 200,data_buf, 0); // using socket 7
}

}

INSIDE MAIN FN I am calling this

Wiznet intialisation

void wiz_sysinit (void)
{
//----------WIZNET 5300 CONFIGURATION SECTION -----------------------//

	     *(vuint16 *)MR0 = 0x38;  
	     *(vuint16 *)MR1 = 0x00;  

	     *(vuint16 *)IMR0  = 0x00;
	     *(vuint16 *)IMR1  = 0x00; 

	     *(vuint16 *)SHAR0 = 0x00;  // MAC address
	     *(vuint16 *)SHAR1 = 0x08;
	     *(vuint16 *)SHAR2 = 0xDC;
	     *(vuint16 *)SHAR3 = 0x01;
	     *(vuint16 *)SHAR4 = 0x02;
	     *(vuint16 *)SHAR5 = 0x03;

	     *(vuint16 *)GAR0 = 0xC0;  // Gateway IP address 192.168.0.1
	     *(vuint16 *)GAR1 = 0xA8;
	     *(vuint16 *)GAR2 = 0x00;
	     *(vuint16 *)GAR3 = 0x01;

	     *(vuint16 *)SUBR0 = 0xFF;  // SUBNET MASK 255.255.255.0
	     *(vuint16 *)SUBR1 = 0xFF;
	     *(vuint16 *)SUBR2 = 0xFF;
	     *(vuint16 *)SUBR3 = 0x00;

	     *(vuint16 *)SIPR0 = 0xC0;  // SOURCE IP 192.168.0.3
	     *(vuint16 *)SIPR1 = 0xA8;
	     *(vuint16 *)SIPR2 = 0x00;
	     *(vuint16 *)SIPR3 = 0x03;

*(vuint16 *)TMSR0 = 0x08; // TX MEM SIZE EACH SOCKET
*(vuint16 *)TMSR1 = 0x08;
*(vuint16 *)TMSR2 = 0x08;
*(vuint16 *)TMSR3 = 0x08;
*(vuint16 *)TMSR4 = 0x08;
*(vuint16 *)TMSR5 = 0x08;
*(vuint16 *)TMSR6 = 0x08;
*(vuint16 *)TMSR7 = 0x08;

*(vuint16 *)RMSR0 = 0x08; // RX MEM SIZE EACH SOCKET
*(vuint16 *)RMSR1 = 0x08;
*(vuint16 *)RMSR2 = 0x08;
*(vuint16 *)RMSR3 = 0x08;
*(vuint16 *)RMSR4 = 0x08;
*(vuint16 *)RMSR5 = 0x08;
*(vuint16 *)RMSR6 = 0x08;
*(vuint16 *)RMSR7 = 0x08;

	     *(vuint16 *)MTYPER0  = 0xFF;  // TX MEMORY
	     *(vuint16 *)MTYPER1  = 0x00;  // RX MEMORY

*(vuint16 *)RTR0 = 0x0F; // Retransmission time out , 400ms
*(vuint16 *)RTR1 = 0x0A;

	     *(vuint16 *)RCR0    = 0x00;  // Retransmission counter, 07
	     *(vuint16 *)RCR1    = 0x07;		     

}

/******** UDP loopback program*****/

void loopback_udp(SOCKET s, uint16 port, uint16* buf, uint16 mode)

{

   uint32 len=0;
   uint16 destip[4];
   uint16 destport;

   switch(getSn_SSR(s))
   {                                                      // -------------------------------
      case SOCK_UDP:                                     //

      if((len = getSn_RX_RSR(s)) > 0) // check the size of received data
         {
            len = recvfrom(s,buf,len,destip,&destport);  // receive data from a destination

            sendto(s,buf,len,destip,destport);
         }
         break;

      case SOCK_CLOSED:                         
    	   close_socket(s);                       // close the SOCKET
           socket(s,Sn_MR_UDP,port,mode);//open the SOCKET with UDP 
           break;
      default:
           break;
   }

}

Function definitions for the above functions are given below
uint8 getSn_SSR(SOCKET s)
{
uint8 ssr, ssr1;
ssr = (uint8)IINCHIP_READ(Sn_SSR1(s)) & 0x00FF; // first read

while(1)
{
ssr1 = (uint8)IINCHIP_READ(Sn_SSR1(s))& 0x00FF; // second read
if(ssr == ssr1)
{
break; // if first == second, Sn_SSR value is valid.
}
ssr = ssr1; // if first <> second,
}
return ssr;
}
uint32 getSn_RX_RSR(SOCKET s)
{
uint32 received_rx_size=0;
uint32 received_rx_size1=1;
uint32 a=0,b=0,c=0,d=0;
uint32 e=0,f=0,g=0;
e = IINCHIP_READ(Sn_RX_RSR0(s));
a = (e<<24);
f = IINCHIP_READ(Sn_RX_RSR1(s));
b = (f<<16);
g = IINCHIP_READ(Sn_RX_RSR2(s));
c = (g<<8);
d = IINCHIP_READ(Sn_RX_RSR3(s));
while(1)
{
received_rx_size = ((b & 0x00FF0000) | (c & 0x0000FF00) | (d & 0x000000FF));

  if(received_rx_size == received_rx_size1)
	  break;
  received_rx_size1 = received_rx_size;                                      

}
return received_rx_size;
}
uint16 IINCHIP_READ(uint32 addr)
{
return *(vuint16 *)addr;
}

uint8 socket(SOCKET s, uint8 protocol, uint16 port, uint16 flag)
{
IINCHIP_WRITE(Sn_MR1(s),(uint16)(protocol | flag));

IINCHIP_WRITE(Sn_PORTR1(s),port); //

setSn_CR(s, Sn_CR_OPEN); // open s-th SOCKET

check_sendok_flag[s] = 1; // initialize the sendok flag.

return 1;
}

void IINCHIP_WRITE(uint32 addr,uint16 data)
{
*(vuint16 *)addr = data;
}

void setSn_CR(SOCKET s, uint16 com)
{
IINCHIP_WRITE(Sn_CR1(s),com); //
while(IINCHIP_READ(Sn_CR1(s))); // wait until Sn_CR is cleared.
}

void close_socket(SOCKET s)
{

setSn_IR(s ,0x00FF); // Clear the remained interrupt bits.
setSn_CR(s ,Sn_CR_CLOSE); // Close s-th SOCKET
}

uint8 getSn_IR(SOCKET s)
{

  return (uint8)IINCHIP_READ(Sn_IR1(s));  // 

}

uint32 sendto(SOCKET s, uint16 * buf, uint32 len, uint16 * addr, uint16 port)
{
uint16 status=0;
uint16 isr=0;
uint32 ret=0;

if (len > getIINCHIP_TxMAX(s)) // check size not to exceed MAX size.
ret = getIINCHIP_TxMAX(s);
else
ret = len;

IINCHIP_WRITE(Sn_DIPR0(s),192); // 192
IINCHIP_WRITE(Sn_DIPR1(s),168); // 168
IINCHIP_WRITE(Sn_DIPR2(s),0); // 0
IINCHIP_WRITE(Sn_DIPR3(s),10); // 10

IINCHIP_WRITE(Sn_DPORTR1(s),100); // 100

wiz_write_buf(s, buf, ret); 

setSn_TX_WRSR(s,ret); 

setSn_CR(s, Sn_CR_SEND);

while (!((isr = getSn_IR(s)) & Sn_IR_SENDOK))// wait SEND command
{
status = getSn_SSR(s)

  if ((status == SOCK_CLOSED) || (isr & Sn_IR_TIMEOUT)) 
  {                                                     
     setSn_IR(s,Sn_IR_TIMEOUT);
     return 0;
 }

}

setSn_IR(s, Sn_IR_SENDOK); // Clear Sn_IR_SENDOK

return ret;
}

uint32 wiz_write_buf(SOCKET s,uint8* buf,uint32 len)
{
uint32 k=0;
uint32 r_val;
uint32 r_val1;

  if (len%2==0) // length is even number
  {
      len = len/2 ;
  }
  else
  {
     len = (len +1)/2 ;
  }

  for (k = 0; k < len; k++)
  {
    
	  IINCHIP_WRITE(0x2003EE,*((uint16*)(buf)));  
	  IINCHIP_WRITE(0x2003EF,*((uint16*)(buf+1)));
	  buf = buf + 2;
  }
return len;

}

void setSn_TX_WRSR(SOCKET s, uint32 size)
{
IINCHIP_WRITE(Sn_TX_WRSR0(s), (uint16)(size >> 24));
IINCHIP_WRITE(Sn_TX_WRSR1(s), (uint16)(size >> 16));
IINCHIP_WRITE(Sn_TX_WRSR2(s), (uint16)(size >> 8)) ;
IINCHIP_WRITE(Sn_TX_WRSR3(s), (uint16)size);
}

uint32 recvfrom(SOCKET s, uint16 * buf, uint32 len, uint16 * addr, uint16 *port)
{
uint16 head[10];
uint32 data_len=0;

if ( len > 0 )
{
switch (IINCHIP_READ(Sn_MR1(s)) & 0x07)
{
case Sn_MR_UDP : // UDP mode
wiz_read_buf(s, (uint8*)head, 8);

        *port = ((head[5]<<8)& 0xFF00)|head[4]; // destination port 
        data_len = ((head[7]<<8)& 0xFF00)|head[6];// DATA 
        wiz_read_buf(s, buf, data_len);        // data copy.
        setSn_CR(s,Sn_CR_RECV);                // recv
        break;
                                               
     default:
       break;
  }

}

return data_len;
}

uint32 wiz_read_buf(SOCKET s, uint8* buf,uint32 len)
{
uint32 k;
if (len%2==0) // length is even number
{
len = len/2 ;
}
else
{
len = (len +1)/2 ;
}

  for (k = 0; k < len; k++)
  {
   
	   *((uint16*)(buf))   = IINCHIP_READ(0x2003F0); 
	   *((uint16*)(buf+1)) = IINCHIP_READ(0x2003F1); 
	   buf = buf + 2;
  }
return len;}