W5500 UDP sending timeout (Sn_IR always is 0x08)

I have successfully used a W5500 to behave as a TCP server on several ports, but I am trying to send a UDP request to a NTP server, but whenever I send a Send via Sn_CR the Sn_IR always reports 0x08 (ie a timeout error), although setting up and opening the port is always ok.

According to Wireshark, the only traffic on the network is an ARP request to 0.0.0.0.

I am using fixed IPs and the Destination IP and port (123) in Sn_DIPR and Sn_DPORT respectively, 1024 in Sn_PORT (not 100% sure this is correct though) and havent written anything into Sn_DHAR.

The W5500s MAC, IP, mask, and gateway is set in SHAR, SIPR, SUBR, and GAR.

PORT INIT:

unsigned long Timeout;
unsigned short int SrcPort = 1024;//anything over 1023
unsigned char ServerIP[4], SR;
NetworkSettingsStruct NetSettings;

WriteByteToWiznet5500(  SOCKET_MR,  	BSB_Socket,   SOCKET_MODE_UDP ); // sets TCP/UDP mode
 
WriteByteToWiznet5500(  ADDR_RCR,  BSB_Socket,	3 );

GetModbusEthernetSettings( &NetSettings );
ServerIP[0] =   (unsigned char)NetSettings.NTSAddress[0];
ServerIP[1] =   (unsigned char)NetSettings.NTSAddress[1];
ServerIP[2] =   (unsigned char)NetSettings.NTSAddress[2];
ServerIP[3] =   (unsigned char)NetSettings.NTSAddress[3];

WriteArrayToWiznet5500( SOCKET_DIPR0, 
						BSB_SOCKET_3_TX, 
						ServerIP, 
						4 );    
//src
WriteByteToWiznet5500(  SOCKET_PORT0,  	BSB_SOCKET_3_TX,	(1024)>>8 );
WriteByteToWiznet5500(  SOCKET_PORT1,  	BSB_SOCKET_3_TX,    (1024)&0x00ff );
//dest....typically 123
WriteByteToWiznet5500(  SOCKET_DPORT0,  BSB_SOCKET_3_TX,	(NetSettings.NTS_UDPPort) >>8     );
WriteByteToWiznet5500(  SOCKET_DPORT1,  BSB_SOCKET_3_TX,    (NetSettings.NTS_UDPPort) &0x00ff );

//clear any outstanding interrupt flags
WriteByteToWiznet5500(  SOCKET_IR,  BSB_Socket, 0x1f );
    
//Open socket
Timeout    =    _CP0_GET_COUNT() + WIZZNET_TIMEOUT_500ms;
WriteByteToWiznet5500(  SOCKET_CR,  	BSB_Socket, 	SOCKET_CMD_OPEN ); 
while( (SR=ReadByteFromWiznet5500( SOCKET_SR, BSB_Socket )) != SOCKET_STAT_SOCK_UDP  )
{ 
    if( _CP0_GET_COUNT()>Timeout )
       return 0;
}

return SOCKET_STAT_SOCK_UDP;

PORT SEND:

unsigned short int RxSize, OffsetAddress, i;
NPTStruct NetTimeReq;
unsigned char IR;
unsigned long int Timeout;

//clear the request to all zeros, except the 3 bit VN=4, And Mode=3 (ie client)
memset( &NetTimeReq, 0x00, sizeof(NetTimeReq) );
NetTimeReq.ModeBits = 0x1b;//(4<<2) | (0x03<<5);

OffsetAddress = ReadUINT16FromWiznet5500( SOCKET_TX_WR0, BSB_SOCKET_3_REG);

WriteArrayToWiznet5500( OffsetAddress, 
						BSB_SOCKET_3_TX, 
						&NetTimeReq, 
						sizeof(NetTimeReq) );

OffsetAddress	= OffsetAddress + sizeof(NetTimeReq);
	
WriteUINT16ToWiznet5500( SOCKET_TX_WR0, BSB_SOCKET_3_REG, OffsetAddress );
WriteByteToWiznet5500( SOCKET_CR, BSB_SOCKET_3_REG, SOCKET_CMD_SEND );    

Timeout    =    _CP0_GET_COUNT() + WIZZNET_TIMEOUT_900ms;		        
while( (IR = ReadByteFromWiznet5500( SOCKET_IR, BSB_SOCKET_3_REG)) == 0x00 )
{
   // if( _CP0_GET_COUNT() > Timeout )
   //     return 0;
}
//clear down the interrupt/flag for next time
WriteByteToWiznet5500( SOCKET_IR, BSB_SOCKET_3_REG, IR );    

if( IR == SOCKET_INT_SENDOK )    
    return 1;        
else
    return 0;

My only guess so far is might be a setting up the registers problem…any ideas? Thanks

Further information:

Despite setting the Destination Target to 192.168.18.100 the ARP requests on the network dont seem to be asking for this, but 0.0.0.0 instead:

Furthermore, if I load Sn_DHAR with the MAC address of the destination and use SENDMAC instead of SEND there are no corresponding ARP requests but the NTP packet is spotted with the destination still set to 0.0.0.0.

I see in your code where you set your server IP address and where you set the server and destination ports but I don’t see any code that sets the destination IP address.

I set the target (NTP server) as below:

ServerIP[0] = (unsigned char)NetSettings.NTSAddress[0];
ServerIP[1] = (unsigned char)NetSettings.NTSAddress[1];
ServerIP[2] = (unsigned char)NetSettings.NTSAddress[2];
ServerIP[3] = (unsigned char)NetSettings.NTSAddress[3];

WriteArrayToWiznet5500( SOCKET_DIPR0,
BSB_SOCKET_3_TX,
ServerIP,
4 );

Incidentally, I have set SIPR0 to 192.168.18.69 too (although I realize this isnt shown above) as well as the MAC, Mask, and Gateway to SHAR, SUBR, and GAR.

Try reading the server IP from the W5500 SIPR register after you set it, and see if it has the value you expect.

Curiously, I did try adding a line reading DIPR0 just before the SEND is issued and it had reverted back to 0.0.0.0 which is unexpected although explains the ARP requests (no other code is known to be writing over it). I also tried re-ordered when the DIPR0, PORT0/1 and the OPEN_CMD is written to Sn_CR but didn’t really to come to any conclusion why the DIPR would change.

As a useful workaround I now re-write the destination IP into DIPR0 each time just before a SEND is written to the Sn_CR as a precaution… The targeted IP address then responds via UDP port 123 as expected.