W5500 Problems by open and sending UDP

Hi everyone,

at the moment I want to develop a solution with the W5500 chip. Im using the wiznet driver API.
The loopback server UDP/ TCP works good.
Now I implement a new abstraction layer to use the wiznet API in further projects.

At the moment I cant post my code, so I try to explain what happens with pseudo code.

void main(void)
{
/*
Based on wiznet udp loopback server,
Port will open correctly. Alter opening I
want to send a UDP broarcast frame in the network (inside the openUdpPort function)
*/
openUdpPort(3000);

sendto(something1); //After opening and sending upd broadcast send someting unicast
sendto(something2);//After opening and sending upd broadcast send someting unicast

while(1)
{
ownLoopbackUdp(); //Works stabile and fine (also based on wiznet loopbackserver)
}

}

The whole testing based on check the network with the wireshark.
Well… In the “openUdpPort” function, I close and open the socket 7 and configure him to port 3000. After the config (which seems to be ok) I want to send the broadcast.
But this dosnt work stable. In debugging mode, I saw, that I´ve got the timeout error by the sendto() function. If this happen “send something1 & 2” dosnt work ( nothing happen ). But the loopbackserver has, whether the broadcast and the two unicast working or not, no failure and work every time very good.

When I change the destination ip of the first frame in the openUdpPort function, from 192.168.1.255 (255.255.255.255) to a unicast address e.g. 192.168.1.162, every sendto() function works the most of the time very stable.

Have somebody an idea, why I get the timeout failure? And why the sendto function sometimes dont want to work after I open the port?

PS.: It seems to be that the chip is configured correctly with IP and so on, because the loopback works everytime very good. AND: If I debug the open function step by step, the broadcast and every other message where send to the network!? ._.

I hope somebody can help me!

Thanks in advantage,
Steve

Actually, I don’t understand your code well.
Why don’t you upload your real code?
I will make sure that after your uploading.
I don’t know if that helps.

Thanks.

Ok, here is my code:
First my Open UDP function:

int8_t UDP_OpenPort(uint8_t sn, uint16_t port)
{
int8_t tmp = 0;
int8_t retVal = UDP_OPEN_ERROR;

/* Wird nur ausgeführt wenn der Socket nicht bereits geöffnet ist */
if (getSn_SR(sn) != SOCK_UDP)
{
	/* Ă–ffne Socket (Port config)*/
	tmp = socket(sn, Sn_MR_UDP, port, 0x00);

	if (tmp != sn)
	{
		/* Signalisiere durch das 0 setzten, dass das öffnen des Ports nicht erfolgreich war. Kann zur Laufzeit als Bedingung genutzt werden */
		W5500_RuntimeInformation.wizUdp0 = 0;
		W5500_RuntimeInformation.wizUdp0Port = 0;
	}
	else
	{	
		/* Ăśbernehme Config in Runtimeinformation, da 'socket' function erfolgreich */
		W5500_RuntimeInformation.wizUdp0 = sn;
		W5500_RuntimeInformation.wizUdp0Port = port;
		retVal = UDP_OPEN_COMPLETE;
	}
}

return retVal;

}

Next my function where sending UDP frames out:

int8_t UDP_Send(ipMessage_t *message)
{
int8_t tmp = 0;
int8_t retVal = UDP_TRANSMISSION_NOT_COMPLETE;

if(message != NULL)
{
	switch (getSn_SR(W5500_RuntimeInformation.wizUdp0))
	{
	case SOCK_UDP:
	
		tmp = sendto(W5500_RuntimeInformation.wizUdp0, message->payloadBuff, message->numberOfBytes, message->destinationIp, message->destinationPort);
		
		if (tmp == message->numberOfBytes)
		{
			retVal = UDP_TRASNMISSION_COMPLETE;
		}
		else if (tmp < 0)
		{
			retVal = UDP_TRANSMISSION_ERROR;
		}

		break;

	case SOCK_CLOSED:
	
		/* Wenn SEND-Request ausgeführt wird, der Port jedoch nicht geöffnet ist, wird automatisch ein OpenUDS ausgeführt (Anhand der Runtimeinformation [ethComInterface.c/h])*/
		UDP_OpenPort(W5500_RuntimeInformation.wizUdp0, W5500_RuntimeInformation.wizUdp0Port);

		break;

	default:

		/* Error Handler */
		retVal = UDP_TRANSMISSION_ERROR;

		break;
	}
}

return retVal;

}

Here is my init function of the chip:

uint8_t ECI_InitComInterface(uint8_t *mac, uint8_t *ip, uint8_t *subnetMask, uint8_t *gateway, uint8_t *dns, bool bootFromFlash)
{
int8_t retValSetInfo = -1;
int8_t retValGetInfo = -1;
int8_t tmp;
uint8_t memsize[2][8] = { { 2, 2, 2, 2, 2, 2, 2, 2 }, { 2, 2, 2, 2, 2, 2, 2, 2 } };
uint8_t retVal = INIT_FAILED;

/* Boot the Main Config / else case get information from EEPROM */
if (bootFromFlash == true)
{
	/* Init the abstraction layer of SPI Write/ Read functions to the driver layer*/
	/* Chip selection call back */
	reg_wizchip_cs_cbfunc(ECI_SetSpiChipSelect, ECI_SetSpiChipDeselect);

	/* SPI Read & Write callback function */
	reg_wizchip_spi_cbfunc(ECI_SetSpiReadByte, ECI_SetSpiWriteByte);

	/* Reset the Wiznet W5500 Chip */
	ECI_ResetChip();

	/* Function set the arguments into the runtime information */
	SetRuntimeInformation(mac, ip, subnetMask, gateway, dns);

	//Bring the runtimeinformation to Initial values.
	W5500_RuntimeInformation.state = W5500_STATE_NOT_DEFINED;
	W5500_RuntimeInformation.failState = W5500_ERROR_NO_ERROR_OCCURED;
	W5500_RuntimeInformation.operationMode = W5500_MODE_NOT_DEFINED;

	/* WIZCHIP SOCKET Buffer initialize */
	if (ctlwizchip(CW_INIT_WIZCHIP, (void*)memsize) == -1)
	{
		W5500_RuntimeInformation.failState = W5500_ERROR_IN_MEM_CONFIG;

		return INIT_FAILED;
	}
	
	/* PHY link status check*/
	uint32_t start = HAL_GetTick(); 
	uint32_t time = 0;

	do
	{		
		if (ctlwizchip(CW_GET_PHYLINK, (void*)&tmp) == -1)
		{
			W5500_RuntimeInformation.failState = W5500_ERROR_UNKOWN_PHY;

			return INIT_FAILED;
		}

		/* Timeout to avoid infinit loop */
		time = HAL_GetTick() - start;
	} 
	while ((tmp == PHY_LINK_OFF) && (time < timeOutInit));

	if (tmp == PHY_LINK_OFF)
	{			
		W5500_RuntimeInformation.failState = W5500_ERROR_PHY_LINK_OFF;
		W5500_RuntimeInformation.state = W5500_STATE_INIT;
		W5500_RuntimeInformation.operationMode = W5500_MODE_INIT;

		return INIT_FAILED;
	}

	/* Init the Wiznet Chip. Function reaches this part only if all other parts were successfull */
	uint8_t stateOfConfig = ConfigW5500Chip(W5500_RuntimeInformation);

	if (stateOfConfig == ERROR_OCCURED)
	{
		W5500_RuntimeInformation.failState = W5500_ERROR_BASE_CONFIG_FAILED;

		retVal = INIT_FAILED;
	}
	else
	{
		W5500_RuntimeInformation.failState = W5500_ERROR_NO_ERROR_OCCURED;
	}

	if (W5500_RuntimeInformation.failState == W5500_ERROR_NO_ERROR_OCCURED)
	{	
		W5500_RuntimeInformation.state = W5500_STATE_IDLE;
		W5500_RuntimeInformation.operationMode = W5500_MODE_NORMAL;
		retVal = INIT_SUCCEED;
	}
	else
	{
		W5500_RuntimeInformation.state = W5500_STATE_INIT;
		W5500_RuntimeInformation.operationMode = W5500_MODE_INIT;				
	}

	EthRingbuffInitBuffer(&tcpRingBuff, tcpArray, ETH_RING_BUFF_SIZE, 0);

	

	
}

return retVal;

}
And here is my main:
int main(void)
{

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/* MCU Configuration----------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* Configure the system clock */
SystemClock_Config();

/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SPI1_Init(); //For EEPROM
MX_SPI2_Init(); //For W5500

/* USER CODE BEGIN 2 /
/
EEPROM Init*/
EEPROM_25LC320_InitEeprom();

/*Bsp.: Init des Ethernet-Chips W5500 & Configurieren des Treibers*/
ECI_InitComInterface(mac, ip, snm, dgw, dns, true);

/* Open UDP Port "internal socket 7" with port 3000*/
UDP_OpenPort(7, 3000);

/* PC ip address & port*/
message.destinationIp[0] = 192;
message.destinationIp[1] = 168;
message.destinationIp[2] = 1;
message.destinationIp[3] = 132;
message.destinationPort = 3000;

/* All data bytes are zero */
message.numberOfBytes = 100;
/* Send UDP Frame */
UDP_Send(&message);

while (1)
{
	
	
		
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
	ECI_Runtask();
}

/* USER CODE END 3 */

}

The ECI_Run task is a TCP/ UDP Loopbackserver (works good).
But if you look at the section before the while(1), you se I init the interface open the UDP Port an want to send a Frame. In debugging step-by-step it works really good, but when I let run my microcontroller with full speed (release) no frame would send :frowning:

I hope you can help me! Bechause I would even go so far as to say that this is a Bug of the W5500.

Steve

I checked your code. but I didn’t found suspicious part.
You have to check SPI interface between W5500 and your MCU again.
(SPI mode, SPI clock, SPI option or connection status etc…)
If you need to verify your schematic file, please send an email to support@wiznet.io with your file.

I know W5500 is sold about one million per year.
I think there is a problem in your porting carefully.
If you need to example codes, please refer to the following link.
Those are official products.

Thanks.

1 Like