W5500 UDP problem


#1

I am trying to interface W5500 with STM32f103c8t6 using UDP . Problem is I can’t send data trough UDP socket but I can receive data from the UDP socket . Please help me to solve the problem

Thank you


#2

There is not enough information in the question.

You have now written a question on the W5500 Ethernet Shield category. Are you using the W5500 Ethernet Shield?

Anyway, we need to know what code you used to help you.
In addition, we need information about what settings you have set up to send and receive data.


#3

Hi i have following Wiznet W5100 board

http://www.ebay.in/itm/112321091012?aff_source=Sok-Goog

and i am interfacing it following STM32 Board using UDP

http://www.st.com/en/evaluation-tools/stm32vldiscovery.html

I am trying to make an Echo server. Whatever data is sent to my chip via W5500 , data is returned back to the PC. I have a C# program written by myself to send and receive data using UDP socket. I am Monitoring communication by Wireshark. UDP send from PC is working ok. i can see the data sent in wireshark and data is received without any problem in my C program. But when i send the data back to the PC, Function SendData is stuck inside while(1) loop
such that Sok_0_INTR_Value is always 0x04. I neither get timeout or send_ok.Please drop me a word if possible
Thank You

#define BSB_Common_Reg 0b00000       // Block Selection Bits - Common Reg
#define BSB_Sok_0_Reg 0b00001

#define Wiz_CS  GPIO_Pin_3    // Port A
#define Wiz_RST GPIO_Pin_2    // Port A

unsigned volatile char DataRecieved = 0 ; // To be changed by Socket Interrupt = Volatile
int main(void)
{
	LEDSetup();
	SPI1_setup();
	ExtInterruptLineConfig();
	Wiz_Setup_A_INIT();
	Wiz_Setup_B_OPEN();

	unsigned short RecvCount = 0 ;
	unsigned short Count = 0 ;
	unsigned char Data[64];
	unsigned char SCADAInfo[8];

	while(1)
	{
		GPIO_SetBits(GPIOC, GPIO_Pin_8 | GPIO_Pin_9 );
		Delay(1,500);
		GPIO_ResetBits(GPIOC, GPIO_Pin_8 | GPIO_Pin_9 );
		Delay(1,500);
		RecvCount = DataRecievedCheck();
		if( RecvCount )
		{
			GetData(Data , &Count ,SCADAInfo); // Recieve Data
			SendData(Data ,Count );
			__disable_irq();
			RecvCount = 0 ;  // Atomic
			__enable_irq();
			Wiz_Setup_B_OPEN();  // Wiz UDP = Open-Close Socket every Time. But NOT in Wiz TCP
		}
	}
	return 1 ;
}
void Wiz_Setup_A_INIT(void)
{
	unsigned short GAR = 0x0001 ;   // Gateway 4 Bytes
	unsigned short SUBR = 0x0005 ;  // Subnet 4 Bytes
	unsigned short SAR = 0x0009  ;  // Source Hardware Address MAC - 6 Bytes
	unsigned short SIPR = 0x000F ;  // IP Address 4 Bytes
	unsigned short RCR = 0x001B ;   // Retry Count, Retry Attempts = RCR + 1, Set RCR = 2 so Attempts = 3
	unsigned short SIMR = 0x0016 ;  // Socket Interrupt Mask , Only enable for the Intterupts u would use , SIR = 0X00 = CLEARED BY STM32

	// Reset
	Delay(1,200);
	GPIO_ResetBits(GPIOA, Wiz_RST);
	Delay(1,5); // Reset Time = 1.5 Mili Sec
	GPIO_SetBits(GPIOA, Wiz_RST);
	Delay(1,2);

	// Auto Negotionaion = 2 Chips decide their Speed ( 10 / 100 MBPs ) and Duplex ( Sigle / double)
	// Link = Up => Auto Negotiation is success
	//	 unsigned short PHYCFGR = 0x002E  ;
	//	 unsigned char PHYCFGRValue = 0x00 ;    // If PHYCFGRValue && 0x01 = 1 => Link UP
	//	 while( ( PHYCFGRValue & 0x01) != 0 )  // 0Th bit of PHYCFGR Reg = 1
	//	 Wiz_Read_Multi( PHYCFGR , BSB_Common_Reg  , &PHYCFGRValue , 1);

	// Mode Reg = 0x00 after Reset = ok
	unsigned char mac[] = {0x00,0x16,0x36,0xDE,0x58,0xF6};
	unsigned char ip[] = {192,168,1,12};      // 0xC0 , 0xA8 , 0x01 , 0x0C
	unsigned char subnet[] = {255,255,255,0}; // 255 = 0xFF
	unsigned char gate[] = {192,168,1,1};

	Wiz_Write_Multi(SAR  , BSB_Common_Reg , mac , sizeof(mac));
	Wiz_Write_Multi(SIPR , BSB_Common_Reg , ip,   sizeof(ip));
	Wiz_Write_Multi(SUBR , BSB_Common_Reg , subnet , sizeof(subnet));
	Wiz_Write_Multi(GAR  , BSB_Common_Reg , gate ,   sizeof(gate));

	unsigned char RCRValue = 0x02 ; // Retry Count = 0x02 + 1 = 3
	Wiz_Write_Multi(RCR  , BSB_Common_Reg , &RCRValue ,   sizeof(RCRValue));
	// Default RTR Retry Time At Reset = 2000 = 2000 x 0.1 = 200 MiLi Sec = OK
	// Default IMR Interrupt Mask Reg = 0x00 = All Desabled = OK

	unsigned char SIMRValue = 0x01 ; // Socket Interrupt Mask keep Socket Interrupts Active AS PER PROJECT  Needs
	Wiz_Write_Multi(SIMR  , BSB_Common_Reg , &SIMRValue ,   sizeof(SIMRValue)); // Only Socket 0 Interrupt = Enable
}
void Wiz_Setup_B_OPEN(void)
{
	unsigned short Sok_0_Mod_Reg = 0x0000 ;  // Mode Offet Address
	unsigned char Sok_0_Mod_Value = 0x02 ;   // Sock 0 Mode = 0x22 = UDP

	unsigned short Sok_0_Port_Reg = 0x0004 ; // 2 Bytes - Sock 0 Port Offset Address
	unsigned char port[] = {0x13,0x88};  // 0x1388 = 5000

	unsigned short Sok_0_Comand_Reg = 0x0001 ; //
	unsigned char Comand_OPEN = 0x01 ;   // Command Reg = 0x01 => Socket OPEN
	unsigned char Comand_CLOSE = 0x10 ;  // Command Reg = 0x10 => Socket CLOSE

	unsigned short Sok_0_Status_Reg = 0x0003 ;
	unsigned char Status_Socket = 0x00 ; // => 0x02 = UDP

	START:   // Label
	Wiz_Write_Multi(Sok_0_Mod_Reg  , BSB_Sok_0_Reg , &Sok_0_Mod_Value , 1);  // Mode = 0x22 = UDP
	Wiz_Write_Multi(Sok_0_Port_Reg  , BSB_Sok_0_Reg , port , 2 );            // Port = 5000
	Wiz_Write_Multi(Sok_0_Comand_Reg  , BSB_Sok_0_Reg , &Comand_OPEN , 1 );  // Open Socket
	Wiz_Read_Multi(Sok_0_Status_Reg , BSB_Sok_0_Reg  , &Status_Socket , 1 );  // Get Socket Status
	if(Status_Socket != 0x22 ) // Status Reg = 0x22 => Socket = UDP
	{
		Wiz_Write_Multi(Sok_0_Comand_Reg  , BSB_Sok_0_Reg , &Comand_CLOSE , 1 );  // Close Socket
		goto START ;
	}
	// else socket is opened , Keep looping till Socket is opened
}
unsigned short DataRecievedCheck(void) // Socket Recieve Size Register RSR != 0x0000 .
{
	//	if(DataRecieved) // data Recieved
	//	{
	//		__disable_irq();
	//		DataRecieved = 0 ;   // Atomic
	//		__enable_irq();
	//		unsigned short Sok_0_IR_Reg = 0x0002 ;  // Sock 0 Interrupt Reg
	//		unsigned char Sok_0_IR_Value = 0x1F ;   // Write 1 to Clear Interupt
	//		Wiz_Write_Multi(Sok_0_IR_Reg  , BSB_Sok_0_Reg , &Sok_0_IR_Value , 1);
	//		// Clearing S0_IR (writing 1) also clears SIR_0
	//		return 1;
	//	}
	//	return 0 ;
	unsigned short Sok_0_RSR_reg = 0x0026 ; // 2 Bytes - Recieved Size
	unsigned char RSRValue[] = {0x00,0x00};
	Wiz_Read_Multi(Sok_0_RSR_reg  , BSB_Sok_0_Reg , RSRValue , 2 );
	unsigned short RCVCount =   ( RSRValue[0] << 8 ) | RSRValue[1];
	return RCVCount ;
}
unsigned char SendData(unsigned char* data , unsigned short count )
{
	// UDP MTU = 1472 Deafult
	unsigned char BSB_Sok_0_Tx_Buffer = 0b00010;

	unsigned short Sok_0_Tx_FreeSize_Reg = 0x0020 ; // 2 bytes
	unsigned char Sok_0_Tx_FreeSize_Value[] = {0x00 , 0x00};

	unsigned short Sok_0_RemoteIP_Reg = 0x000C ; // 4 bytes
	unsigned char Sok_0_RemoteIP_Value[] = {192, 168 , 1 , 8}; // SCADA PC IP

	unsigned short Sok_0_RemotePort_Reg = 0x0010 ; // 2 bytes
	unsigned char Sok_0_RemotePort_Value[] = {0x13 , 0x89}; // SCADA PC Listening Port 5001 = 0x1389

	unsigned short Sok_0_Tx_WritePT_Reg = 0x0024 ; // 2 bytes
	unsigned char Sok_0_Tx_WritePT_value[] = {0x00 , 0x00};

	unsigned short Sok_0_Comand_Reg = 0x0001 ;
	unsigned char Comand_SEND = 0x20 ;   // 0x20 => Socket SEND
	unsigned char Comand_CLOSE = 0x10 ;

	unsigned short Sok_0_INTR_Reg = 0x0002 ;
	unsigned char Sok_0_INTR_Value = 0x00 ;   // Check which Interrupt occured, Reset by Writing 1

	//	unsigned short IR_Reg = 0x0015 ; // Chip Level Interrupt Register
	//	unsigned char IR_Value = 0x00 ;

	unsigned short FreeSize = 0 ;
	FREESIZE : // Label
	Wiz_Read_Multi(Sok_0_Tx_FreeSize_Reg , BSB_Sok_0_Reg  , Sok_0_Tx_FreeSize_Value , 2 );
	FreeSize = ( Sok_0_Tx_FreeSize_Value[0] << 8 ) | Sok_0_Tx_FreeSize_Value[1];
	if( FreeSize < count)
		goto FREESIZE ;

	Wiz_Write_Multi(Sok_0_RemoteIP_Reg  , BSB_Sok_0_Reg , Sok_0_RemoteIP_Value , 4 ); // SCADA IP
	Wiz_Write_Multi(Sok_0_RemotePort_Reg  , BSB_Sok_0_Reg , Sok_0_RemotePort_Value , 2 ); // SCADA Listening Port

	unsigned short dist_ptr = 0 ;
	Wiz_Read_Multi(Sok_0_Tx_WritePT_Reg , BSB_Sok_0_Reg  , Sok_0_Tx_WritePT_value , 2 );
	dist_ptr = ( Sok_0_Tx_WritePT_value[0] << 8 ) | Sok_0_Tx_WritePT_value[1];

	Wiz_Write_Multi(dist_ptr , BSB_Sok_0_Tx_Buffer  , data , count ); // write Data to Wiz Tx Buffer

	dist_ptr += count;
	Sok_0_Tx_WritePT_value[0] = dist_ptr >> 8 ; // 0 = MS Byte
	Sok_0_Tx_WritePT_value[1] = dist_ptr & 0x00FF ; // 1 = LS Byte
	Wiz_Write_Multi(Sok_0_Tx_WritePT_Reg  , BSB_Sok_0_Reg , Sok_0_Tx_WritePT_value , 2 );

	Wiz_Write_Multi(Sok_0_Comand_Reg  , BSB_Sok_0_Reg , &Comand_SEND , 1 ); // SEND
	unsigned char success = 0 ;
	while(1)
	{
		Wiz_Read_Multi(Sok_0_INTR_Reg , BSB_Sok_0_Reg  , &Sok_0_INTR_Value , 1 ); // read Interrupt Reg
		if( (Sok_0_INTR_Value & ( 1 << 4)) != 0 )      //  Send Ok
		{
			success = 1 ; // Break out of While Loop
			break;
		}
		if( (Sok_0_INTR_Value & ( 1 << 3)) != 0 )      // Send Time Out
		{
			success = 0 ;
			break; // Break out of While Loop
		}
	}
	Sok_0_INTR_Value = 0xFF; //
	Wiz_Write_Multi(Sok_0_INTR_Reg , BSB_Sok_0_Reg  , &Sok_0_INTR_Value , 1 ); // Reset S0_IR = Write 1
	// IR_n = 1 To Reset INTR

	Wiz_Write_Multi(Sok_0_Comand_Reg  , BSB_Sok_0_Reg , &Comand_CLOSE , 1 ); // CLOSE

	return success ;
}
void GetData(unsigned char* data , unsigned short* count , unsigned char* UDPInfoPack) // Socket Recieve Size Register RSR != 0x0000 .
{
	unsigned short Sok_0_RD_Point_Reg = 0x0028 ; // 2 bytes
	unsigned char Sok_0_RD_Point_value[] = {0x00 , 0x00};
	Wiz_Read_Multi(Sok_0_RD_Point_Reg , BSB_Sok_0_Reg  , Sok_0_RD_Point_value , 2 );
	unsigned short src_ptr = ( Sok_0_RD_Point_value[0] << 8 ) | Sok_0_RD_Point_value[1];
	unsigned char BSB_Sok_0_Rx_Buffer = 0b00011;
	Wiz_Read_Multi(src_ptr , BSB_Sok_0_Rx_Buffer  , UDPInfoPack , 8 );
	*count = (*(UDPInfoPack + 6) << 8 ) | (*(UDPInfoPack + 7)) ;
	src_ptr += 8;
	Wiz_Read_Multi(src_ptr, BSB_Sok_0_Rx_Buffer  , data , *count );

	// Set Read-pointer of Socket_0
	src_ptr += *count ;
	src_ptr -= 8 ;
	Sok_0_RD_Point_value[0] = src_ptr >> 8 ;     // MS Byte
	Sok_0_RD_Point_value[1] = src_ptr & 0x00FF ; // LS Byte
	Wiz_Write_Multi(Sok_0_RD_Point_Reg  , BSB_Sok_0_Reg , Sok_0_RD_Point_value , 2 );

	// Set Command Recieve
	unsigned short Sok_0_Comand_Reg = 0x0001 ;
	unsigned char Comand_RECV = 0x04 ;   // Command Reg = 0x01 => Socket RECV
	Wiz_Write_Multi(Sok_0_Comand_Reg  , BSB_Sok_0_Reg , &Comand_RECV , 1 );  // Command = RECV

	//  Reset Interrupts - Clearing S0_IR (writing 1) also clears SIR_0
	//	unsigned short Sok_0_IR_Reg = 0x0002 ;  // Sock 0 Interrupt Reg
	//	unsigned char Sok_0_IR_Value = 0x1F ;   // Write 1 to Clear Interupt
	//	Wiz_Write_Multi(Sok_0_IR_Reg  , BSB_Sok_0_Reg , &Sok_0_IR_Value , 1);

	// Close Socket, it Rsets Rx buffer pointer
	unsigned char Comand_CLOSE = 0x10 ;  // Command Reg = 0x10 => Socket CLOSE
	Wiz_Write_Multi(Sok_0_Comand_Reg  , BSB_Sok_0_Reg , &Comand_CLOSE , 1 );  //  Close Socket
}

void Wiz_Write_Multi( unsigned short address ,  unsigned char BSB , unsigned char* bytes , unsigned short count )
{
	unsigned char control = ( BSB << 3 ) | 0x04 ; // BSB_RW_OM
	// BSB 5 Bits, R/W bit W = 1 R = 0, OM 2 Bits = 00 = VDM = Chip Slect is NOT ground
	unsigned short x = 0 ;
	GPIO_ResetBits(GPIOA, Wiz_CS);
	Delay(0,15);
	SPI_SendBye(address >> 8);        // Offset Address High Byte
	SPI_SendBye(address & 0x00FF);    // Offset Address Low Byte
	SPI_SendBye(control);   // VDM
	for( x = 0 ; x < count ; x++ )   // Send Data
		SPI_SendBye(*bytes++); //  * has precedence over ++
	Delay(0,15);
	GPIO_SetBits(GPIOA, Wiz_CS);
	Delay(0,15);
}
void Wiz_Read_Multi( unsigned short address , unsigned char BSB  , unsigned char* data , unsigned short count)
{
	unsigned char control =  BSB << 3  ; // BSB_RW_OM => R/W = 0 , OM = 00
	// BSB 5 Bits, R/W bit W = 1 R = 0, OM 2 Bits = 00 = VDM = Chip Slect is NOT ground
	unsigned short x = 0 ;
	GPIO_ResetBits(GPIOA, Wiz_CS);
	Delay(0,15);
	SPI_SendBye(address >> 8);           // Offset Address High Byte
	SPI_SendBye(address & 0x00FF);       // Offset Address Low Byte
	SPI_SendBye(control);                // VDM - Read
	for( x = 0 ; x < count ; x++ )       // Read Data
		*data++ = SPI_ReadByte();  // * has precedence over ++
	Delay(0,15);
	GPIO_SetBits(GPIOA, Wiz_CS);
	Delay(0,15);
	// In C Array cant be returned , so pass an array by REFERENCE and fill it
}

void SPI_SendBye(unsigned char byte)
{
	while (  SPI_I2S_GetFlagStatus(SPI1 , SPI_I2S_FLAG_TXE) == RESET );  // sending data Wait
	SPI_I2S_SendData(SPI1 , byte);
	while (  SPI_I2S_GetFlagStatus(SPI1 , SPI_I2S_FLAG_RXNE) == RESET ); // Wait for data
	byte = SPI_I2S_ReceiveData(SPI1);        // Dummy read to generate clock
}
unsigned char SPI_ReadByte(void)
{
	while (  SPI_I2S_GetFlagStatus(SPI1 , SPI_I2S_FLAG_TXE) == RESET );
	SPI_I2S_SendData(SPI1 , 0xff);     // Dummy write to generate clock
	while (  SPI_I2S_GetFlagStatus(SPI1 , SPI_I2S_FLAG_RXNE) == RESET );
	return (unsigned char)SPI_I2S_ReceiveData(SPI1);
}
void SPI1_setup(void)
{
	// Enable clock for SPI1 AFIO GPIOA  GPIOB
	RCC->APB2ENR |= ( 1<<12 ) | ( 1<<0 ) | ( 1<<2 ) | ( 1<<3 );

	// PA 3 = CS           PA 2 = RST
	GPIO_InitTypeDef GpioPin;
	GpioPin.GPIO_Pin = Wiz_CS | Wiz_RST ;
	GpioPin.GPIO_Speed = GPIO_Speed_2MHz;
	GpioPin.GPIO_Mode = GPIO_Mode_Out_PP ; // CS = DO = Out Push Pull
	GPIO_Init(GPIOA, &GpioPin);
	GPIO_SetBits(GPIOA, Wiz_CS | Wiz_RST ); // CS + RST = High

	// SCK  = PA5 = Alternate Push Pull 10 MHz
	// MISO = PA6 = Input pull up
	// MOSI = PA7 = Alternate Push Pull 10 MHz

	GpioPin.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7 ; // Clock + MOSI
	GpioPin.GPIO_Speed = GPIO_Speed_10MHz;
	GpioPin.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &GpioPin);
	// Few example say MOSI is Alternate Push Pull
	GpioPin.GPIO_Pin = GPIO_Pin_6 ;
	GpioPin.GPIO_Mode = GPIO_Mode_IPU; // Input Pull Up
	GPIO_Init(GPIOA, &GpioPin); // Clock + MOSI

	SPI_InitTypeDef   MySPI;
	MySPI.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
	MySPI.SPI_Mode = SPI_Mode_Master;
	MySPI.SPI_DataSize = SPI_DataSize_8b;
	MySPI.SPI_CPOL = SPI_CPOL_Low; // Mode 0
	MySPI.SPI_CPHA = SPI_CPHA_1Edge; // Mode 0
	MySPI.SPI_NSS = SPI_NSS_Soft;  // CS handles by Software
	MySPI.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2 ; // 24 / 2 = 12 MHz < 33.3 MHz
	MySPI.SPI_CRCPolynomial = 7;
	SPI_Init(SPI1 , &MySPI);
	SPI_Cmd(SPI1 , ENABLE);
}

// Tim 2 = General Purpose , CNT ARR PSC = 16 Bit in STM32F100RB.
void Tim2_init(unsigned char base) // base = 0 = Micro , base = 1 Mili
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	TIM_TimeBaseInitTypeDef TIM;
	TIM_TimeBaseStructInit(&TIM);
	if(base)
		TIM.TIM_Prescaler = (SystemCoreClock/1000)-1;    // 10 CNT = 1 Mili Sec
	else
		TIM.TIM_Prescaler = (SystemCoreClock/1000000)-1; // 1 CNT = 1 Micro Sec
	TIM.TIM_Period = 0xFFFF - 1 ; // ARR 32 Bits
	TIM.TIM_ClockDivision = 0;
	TIM.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM2,&TIM);
	TIM2->CNT = 0 ; // Reset
	TIM_Cmd(TIM2,ENABLE); // Timer Start
	// STM32F100RB Tim CLK = SystemCoreClock
	// STM32F4 Tim CLK = SystemCoreClock / 2
}

void Delay( unsigned char base , unsigned short Ticks) // 0 = Micro , 1 = Mili
{
	Tim2_init(base); // Reset during Init
	volatile unsigned short start = TIM2->CNT;
	while((TIM2->CNT - start) <= Ticks);
	// Stop timer
	TIM_Cmd(TIM2,DISABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,DISABLE); // Power Save
}

void LEDSetup(void)
{
	RCC->APB2ENR |= ( 1 << 4 );
	GPIO_InitTypeDef GpioPin;
	GpioPin.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 ;
	GpioPin.GPIO_Speed = GPIO_Speed_10MHz;
	GpioPin.GPIO_Mode = GPIO_Mode_Out_PP ;
	GPIO_Init(GPIOC, &GpioPin);
}

void ExtInterruptLineConfig(void)
{
	RCC->APB2ENR |= (1<<4) | (1<<0) ; // AFIO is must for EXTI
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 ;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(GPIOC, &GPIO_InitStruct);

	EXTI_InitTypeDef EXTI_InitStruct;
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource0); // Port Source = GPIOC
	EXTI_InitStruct.EXTI_Line = EXTI_Line0 ;  // EXTI_Line0 = PA0 PB0 PC0 PD0 ....
	EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; // So EXTI_Line0 = PC0
	EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling; // Falling Edge
	EXTI_InitStruct.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStruct);

	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn; // EXTI0_IRQn = EXTI_Line0
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x0F; // lowest priority
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x0F; // lowest subpriority
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStruct);
	// NVIC_EnableIRQ(EXTI0_IRQn);
}
void EXTI0_IRQHandler(void)  // Data Recieved
{
	if(EXTI_GetITStatus(EXTI_Line0) != RESET)
		DataRecieved = 1 ;
	EXTI_ClearITPendingBit(EXTI_Line0); // Must
}

#4
Hi i have following Wiznet W5100 board

* http://www.ebay.in/itm/112321091012?aff_source=Sok-Goog

and i am interfacing it following STM32 Board using UDP

* http://www.st.com/en/evaluation-tools/stm32vldiscovery.html

I am trying to make an Echo server. Whatever data is sent to my chip via W5500 , data is returned back to the PC. I have a C# program written by myself to send and receive data using UDP socket. I am Monitoring communication by Wireshark. UDP send from PC is working ok. i can see the data sent in wireshark and data is received without any problem in my C program. But when i send the data back to the PC, Function SendData is stuck inside while(1) loop such that Sok_0_INTR_Value is always 0x04. I neither get timeout or send_ok. Physically there is a direct connection by patch cable between W5500 and my laptop. and w5500 gateway defined as laptop IP
Thank You

#include<stm32f10x.h>
#include<stm32f10x_gpio.h>

#define BSB_Common_Reg 0b00000       // Block Selection Bits - Common Reg
#define BSB_Sok_0_Reg 0b00001

#define Wiz_CS  GPIO_Pin_3    // Port A
#define Wiz_RST GPIO_Pin_2    // Port A

unsigned volatile char DataRecieved = 0 ; // To be changed by Socket Interrupt = Volatile
int main(void)
{
	SPI1_setup();
	Wiz_Setup_A_INIT();
	Wiz_Setup_B_OPEN();

	unsigned short RecvCount = 0 ;
	unsigned short Count = 0 ;
	unsigned char Data[64];
	unsigned char SCADAInfo[8];

	while(1)
	{
		GPIO_SetBits(GPIOC, GPIO_Pin_8 | GPIO_Pin_9 );
		Delay(1,500);  // 500 Mili Sec 
		GPIO_ResetBits(GPIOC, GPIO_Pin_8 | GPIO_Pin_9 );
		Delay(1,500); // 500 Mili Sec
		RecvCount = DataRecievedCheck();
		if( RecvCount )
		{
			GetData(Data , &Count ,SCADAInfo);  // Recieve Data = Closes Soket in the end
			SendData(Data ,Count );             // Send Data = Closes Soket in the end
			__disable_irq();
			RecvCount = 0 ;  // Atomic
			__enable_irq();
			Wiz_Setup_B_OPEN();  // Wiz UDP = Open-Close Socket every Time. But NOT in Wiz TCP
		}
	}
	return 1 ;
}
void Wiz_Setup_A_INIT(void)
{
	unsigned short GAR = 0x0001 ;   // Gateway 4 Bytes
	unsigned short SUBR = 0x0005 ;  // Subnet 4 Bytes
	unsigned short SAR = 0x0009  ;  // Source Hardware Address MAC - 6 Bytes
	unsigned short SIPR = 0x000F ;  // IP Address 4 Bytes
	unsigned short RCR = 0x001B ;   // Retry Count, Retry Attempts = RCR + 1, Set RCR = 2 so Attempts = 3
	unsigned short SIMR = 0x0016 ;  // Socket Interrupt Mask , Only enable for the Intterupts u would use , SIR = 0X00 = CLEARED BY STM32

	// Reset
	Delay(1,200);  // 200 Mili Sec
	GPIO_ResetBits(GPIOA, Wiz_RST);
	Delay(1,5); // Reset Time = 1.5 Mili Sec
	GPIO_SetBits(GPIOA, Wiz_RST);
	Delay(1,2); // 2 mili sec

	// Auto Negotionaion = 2 Chips decide their Speed ( 10 / 100 MBPs ) and Duplex ( Sigle / double)
	// Link = Up => Auto Negotiation is success
	//	 unsigned short PHYCFGR = 0x002E  ;
	//	 unsigned char PHYCFGRValue = 0x00 ;    // If PHYCFGRValue && 0x01 = 1 => Link UP
	//	 while( ( PHYCFGRValue & 0x01) != 0 )  // 0Th bit of PHYCFGR Reg = 1
	//	 Wiz_Read_Multi( PHYCFGR , BSB_Common_Reg  , &PHYCFGRValue , 1);

	// Mode Reg = 0x00 after Reset = ok
	unsigned char mac[] = {0x00,0x16,0x36,0xDE,0x58,0xF6};
	unsigned char ip[] = {192,168,1,12};      // 0xC0 , 0xA8 , 0x01 , 0x0C
	unsigned char subnet[] = {255,255,255,0}; // 255 = 0xFF
	unsigned char gate[] = {192,168,1,1};
                // Direct connection by patch cable between W5500 and laptop. gateway defined as laptop IP

	Wiz_Write_Multi(SAR  , BSB_Common_Reg , mac , sizeof(mac));
	Wiz_Write_Multi(SIPR , BSB_Common_Reg , ip,   sizeof(ip));
	Wiz_Write_Multi(SUBR , BSB_Common_Reg , subnet , sizeof(subnet));
	Wiz_Write_Multi(GAR  , BSB_Common_Reg , gate ,   sizeof(gate));

	unsigned char RCRValue = 0x02 ; // Retry Count = 0x02 + 1 = 3
	Wiz_Write_Multi(RCR  , BSB_Common_Reg , &RCRValue ,   sizeof(RCRValue));
	// Default RTR Retry Time At Reset = 2000 = 2000 x 0.1 = 200 MiLi Sec = OK
	// Default IMR Interrupt Mask Reg = 0x00 = All Desabled = OK

	unsigned char SIMRValue = 0x01 ; // Socket Interrupt Mask keep Socket Interrupts Active AS PER PROJECT  Needs
	Wiz_Write_Multi(SIMR  , BSB_Common_Reg , &SIMRValue ,   sizeof(SIMRValue)); // Only Socket 0 Interrupt = Enable
}
void Wiz_Setup_B_OPEN(void)
{
	unsigned short Sok_0_Mod_Reg = 0x0000 ;  // Mode Offet Address
	unsigned char Sok_0_Mod_Value = 0x02 ;   // Sock 0 Mode = 0x22 = UDP

	unsigned short Sok_0_Port_Reg = 0x0004 ; // 2 Bytes - Sock 0 Port Offset Address
	unsigned char port[] = {0x13,0x88};  // 0x1388 = 5000

	unsigned short Sok_0_Comand_Reg = 0x0001 ; //
	unsigned char Comand_OPEN = 0x01 ;   // Command Reg = 0x01 => Socket OPEN
	unsigned char Comand_CLOSE = 0x10 ;  // Command Reg = 0x10 => Socket CLOSE

	unsigned short Sok_0_Status_Reg = 0x0003 ;
	unsigned char Status_Socket = 0x00 ; // => 0x02 = UDP

	START:   // Label
	Wiz_Write_Multi(Sok_0_Mod_Reg  , BSB_Sok_0_Reg , &Sok_0_Mod_Value , 1);  // Mode = 0x22 = UDP
	Wiz_Write_Multi(Sok_0_Port_Reg  , BSB_Sok_0_Reg , port , 2 );            // Port = 5000
	Wiz_Write_Multi(Sok_0_Comand_Reg  , BSB_Sok_0_Reg , &Comand_OPEN , 1 );  // Open Socket
	Wiz_Read_Multi(Sok_0_Status_Reg , BSB_Sok_0_Reg  , &Status_Socket , 1 );  // Get Socket Status
	if(Status_Socket != 0x22 ) // Status Reg = 0x22 => Socket = UDP
	{
		Wiz_Write_Multi(Sok_0_Comand_Reg  , BSB_Sok_0_Reg , &Comand_CLOSE , 1 );  // Close Socket
		goto START ;
	}
	// else socket is opened , Keep looping till Socket is opened
}
unsigned short DataRecievedCheck(void) // Socket Recieve Size Register RSR != 0x0000 .
{
	unsigned short Sok_0_RSR_reg = 0x0026 ; // 2 Bytes - Recieved Size
	unsigned char RSRValue[] = {0x00,0x00};
	Wiz_Read_Multi(Sok_0_RSR_reg  , BSB_Sok_0_Reg , RSRValue , 2 );
	unsigned short RCVCount =   ( RSRValue[0] << 8 ) | RSRValue[1];
	return RCVCount ;
}
unsigned char SendData(unsigned char* data , unsigned short count )
{
	// UDP MTU = 1472 Deafult
	unsigned char BSB_Sok_0_Tx_Buffer = 0b00010;

	unsigned short Sok_0_Tx_FreeSize_Reg = 0x0020 ; // 2 bytes
	unsigned char Sok_0_Tx_FreeSize_Value[] = {0x00 , 0x00};

	unsigned short Sok_0_RemoteIP_Reg = 0x000C ; // 4 bytes
	unsigned char Sok_0_RemoteIP_Value[] = {192, 168 , 1 , 8}; // SCADA PC IP

	unsigned short Sok_0_RemotePort_Reg = 0x0010 ; // 2 bytes
	unsigned char Sok_0_RemotePort_Value[] = {0x13 , 0x89}; // SCADA PC Listening Port 5001 = 0x1389

	unsigned short Sok_0_Tx_WritePT_Reg = 0x0024 ; // 2 bytes
	unsigned char Sok_0_Tx_WritePT_value[] = {0x00 , 0x00};

	unsigned short Sok_0_Comand_Reg = 0x0001 ;
	unsigned char Comand_SEND = 0x20 ;   // 0x20 => Socket SEND
	unsigned char Comand_CLOSE = 0x10 ;

	unsigned short Sok_0_INTR_Reg = 0x0002 ;
	unsigned char Sok_0_INTR_Value = 0x00 ;   // Check which Interrupt occured, Reset by Writing 1

	//	unsigned short IR_Reg = 0x0015 ; // Chip Level Interrupt Register
	//	unsigned char IR_Value = 0x00 ;

	unsigned short FreeSize = 0 ;
	FREESIZE : // Label
	Wiz_Read_Multi(Sok_0_Tx_FreeSize_Reg , BSB_Sok_0_Reg  , Sok_0_Tx_FreeSize_Value , 2 );
	FreeSize = ( Sok_0_Tx_FreeSize_Value[0] << 8 ) | Sok_0_Tx_FreeSize_Value[1];
	if( FreeSize < count)
		goto FREESIZE ;

	Wiz_Write_Multi(Sok_0_RemoteIP_Reg  , BSB_Sok_0_Reg , Sok_0_RemoteIP_Value , 4 ); // SCADA IP
	Wiz_Write_Multi(Sok_0_RemotePort_Reg  , BSB_Sok_0_Reg , Sok_0_RemotePort_Value , 2 ); // SCADA Listening Port

	unsigned short dist_ptr = 0 ;
	Wiz_Read_Multi(Sok_0_Tx_WritePT_Reg , BSB_Sok_0_Reg  , Sok_0_Tx_WritePT_value , 2 );
	dist_ptr = ( Sok_0_Tx_WritePT_value[0] << 8 ) | Sok_0_Tx_WritePT_value[1];

	Wiz_Write_Multi(dist_ptr , BSB_Sok_0_Tx_Buffer  , data , count ); // write Data to Wiz Tx Buffer

	dist_ptr += count;
	Sok_0_Tx_WritePT_value[0] = dist_ptr >> 8 ; // 0 = MS Byte
	Sok_0_Tx_WritePT_value[1] = dist_ptr & 0x00FF ; // 1 = LS Byte
	Wiz_Write_Multi(Sok_0_Tx_WritePT_Reg  , BSB_Sok_0_Reg , Sok_0_Tx_WritePT_value , 2 );

	Wiz_Write_Multi(Sok_0_Comand_Reg  , BSB_Sok_0_Reg , &Comand_SEND , 1 ); // SEND
	unsigned char success = 0 ;
	while(1)
	{
		Wiz_Read_Multi(Sok_0_INTR_Reg , BSB_Sok_0_Reg  , &Sok_0_INTR_Value , 1 ); // read Interrupt Reg
		if( (Sok_0_INTR_Value & ( 1 << 4)) != 0 )      //  Send Ok
		{
			success = 1 ; // Break out of While Loop
			break;
		}
		if( (Sok_0_INTR_Value & ( 1 << 3)) != 0 )      // Send Time Out
		{
			success = 0 ;
			break; // Break out of While Loop
		}
	}
	Sok_0_INTR_Value = 0xFF;// IR_n = 1 To Reset INTR
	Wiz_Write_Multi(Sok_0_INTR_Reg , BSB_Sok_0_Reg  , &Sok_0_INTR_Value , 1 ); // Reset S0_IR = Write 1

	Wiz_Write_Multi(Sok_0_Comand_Reg  , BSB_Sok_0_Reg , &Comand_CLOSE , 1 ); // CLOSE

	return success ;
}
void GetData(unsigned char* data , unsigned short* count , unsigned char* UDPInfoPack) // Socket Recieve Size Register RSR != 0x0000 .
{
	unsigned short Sok_0_RD_Point_Reg = 0x0028 ; // 2 bytes
	unsigned char Sok_0_RD_Point_value[] = {0x00 , 0x00};
	Wiz_Read_Multi(Sok_0_RD_Point_Reg , BSB_Sok_0_Reg  , Sok_0_RD_Point_value , 2 );
	unsigned short src_ptr = ( Sok_0_RD_Point_value[0] << 8 ) | Sok_0_RD_Point_value[1];
	unsigned char BSB_Sok_0_Rx_Buffer = 0b00011;
	Wiz_Read_Multi(src_ptr , BSB_Sok_0_Rx_Buffer  , UDPInfoPack , 8 );
	*count = (*(UDPInfoPack + 6) << 8 ) | (*(UDPInfoPack + 7)) ;
	src_ptr += 8;
	Wiz_Read_Multi(src_ptr, BSB_Sok_0_Rx_Buffer  , data , *count );

	// Set Read-pointer of Socket_0
	src_ptr += *count ;
	src_ptr -= 8 ;
	Sok_0_RD_Point_value[0] = src_ptr >> 8 ;     // MS Byte
	Sok_0_RD_Point_value[1] = src_ptr & 0x00FF ; // LS Byte
	Wiz_Write_Multi(Sok_0_RD_Point_Reg  , BSB_Sok_0_Reg , Sok_0_RD_Point_value , 2 );

	// Set Command Recieve
	unsigned short Sok_0_Comand_Reg = 0x0001 ;
	unsigned char Comand_RECV = 0x04 ;   // Command Reg = 0x01 => Socket RECV
	Wiz_Write_Multi(Sok_0_Comand_Reg  , BSB_Sok_0_Reg , &Comand_RECV , 1 );  // Command = RECV

	//  Reset Interrupts - Clearing S0_IR (writing 1) also clears SIR_0
	//	unsigned short Sok_0_IR_Reg = 0x0002 ;  // Sock 0 Interrupt Reg
	//	unsigned char Sok_0_IR_Value = 0x1F ;   // Write 1 to Clear Interupt
	//	Wiz_Write_Multi(Sok_0_IR_Reg  , BSB_Sok_0_Reg , &Sok_0_IR_Value , 1);

	// Close Socket, it Rsets Rx buffer pointer
	unsigned char Comand_CLOSE = 0x10 ;  // Command Reg = 0x10 => Socket CLOSE
	Wiz_Write_Multi(Sok_0_Comand_Reg  , BSB_Sok_0_Reg , &Comand_CLOSE , 1 );  //  Close Socket
}

void Wiz_Write_Multi( unsigned short address ,  unsigned char BSB , unsigned char* bytes , unsigned short count )
{
	unsigned char control = ( BSB << 3 ) | 0x04 ; // BSB_RW_OM
	// BSB 5 Bits, R/W bit W = 1 R = 0, OM 2 Bits = 00 = VDM = Chip Slect is NOT ground
	unsigned short x = 0 ;
	GPIO_ResetBits(GPIOA, Wiz_CS);
	Delay(0,15);
	SPI_SendBye(address >> 8);        // Offset Address High Byte
	SPI_SendBye(address & 0x00FF);    // Offset Address Low Byte
	SPI_SendBye(control);   // VDM
	for( x = 0 ; x < count ; x++ )   // Send Data
		SPI_SendBye(*bytes++); //  * has precedence over ++
	Delay(0,15);
	GPIO_SetBits(GPIOA, Wiz_CS);
	Delay(0,15);
}
void Wiz_Read_Multi( unsigned short address , unsigned char BSB  , unsigned char* data , unsigned short count)
{
	unsigned char control =  BSB << 3  ; // BSB_RW_OM => R/W = 0 , OM = 00
	// BSB 5 Bits, R/W bit W = 1 R = 0, OM 2 Bits = 00 = VDM = Chip Slect is NOT ground
	unsigned short x = 0 ;
	GPIO_ResetBits(GPIOA, Wiz_CS);
	Delay(0,15);
	SPI_SendBye(address >> 8);           // Offset Address High Byte
	SPI_SendBye(address & 0x00FF);       // Offset Address Low Byte
	SPI_SendBye(control);                // VDM - Read
	for( x = 0 ; x < count ; x++ )       // Read Data
		*data++ = SPI_ReadByte();  // * has precedence over ++
	Delay(0,15);
	GPIO_SetBits(GPIOA, Wiz_CS);
	Delay(0,15);
	// In C Array cant be returned , so pass an array by REFERENCE and fill it
}

void SPI_SendBye(unsigned char byte)
{
	while (  SPI_I2S_GetFlagStatus(SPI1 , SPI_I2S_FLAG_TXE) == RESET );  // sending data Wait
	SPI_I2S_SendData(SPI1 , byte);
	while (  SPI_I2S_GetFlagStatus(SPI1 , SPI_I2S_FLAG_RXNE) == RESET ); // Wait for data
	byte = SPI_I2S_ReceiveData(SPI1);        // Dummy read to generate clock
}
unsigned char SPI_ReadByte(void)
{
	while (  SPI_I2S_GetFlagStatus(SPI1 , SPI_I2S_FLAG_TXE) == RESET );
	SPI_I2S_SendData(SPI1 , 0xff);     // Dummy write to generate clock
	while (  SPI_I2S_GetFlagStatus(SPI1 , SPI_I2S_FLAG_RXNE) == RESET );
	return (unsigned char)SPI_I2S_ReceiveData(SPI1);
}
void SPI1_setup(void)
{
	// Enable clock for SPI1 AFIO GPIOA  GPIOB
	RCC->APB2ENR |= ( 1<<12 ) | ( 1<<0 ) | ( 1<<2 ) | ( 1<<3 );

	// PA 3 = CS           PA 2 = RST
	GPIO_InitTypeDef GpioPin;
	GpioPin.GPIO_Pin = Wiz_CS | Wiz_RST ;
	GpioPin.GPIO_Speed = GPIO_Speed_2MHz;
	GpioPin.GPIO_Mode = GPIO_Mode_Out_PP ; // CS = DO = Out Push Pull
	GPIO_Init(GPIOA, &GpioPin);
	GPIO_SetBits(GPIOA, Wiz_CS | Wiz_RST ); // CS + RST = High

	// SCK  = PA5 = Alternate Push Pull 10 MHz
	// MISO = PA6 = Input pull up
	// MOSI = PA7 = Alternate Push Pull 10 MHz

	GpioPin.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7 ; // Clock + MOSI
	GpioPin.GPIO_Speed = GPIO_Speed_10MHz;
	GpioPin.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &GpioPin);
	// Few example say MOSI is Alternate Push Pull
	GpioPin.GPIO_Pin = GPIO_Pin_6 ;
	GpioPin.GPIO_Mode = GPIO_Mode_IPU; // Input Pull Up
	GPIO_Init(GPIOA, &GpioPin); // Clock + MOSI

	SPI_InitTypeDef   MySPI;
	MySPI.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
	MySPI.SPI_Mode = SPI_Mode_Master;
	MySPI.SPI_DataSize = SPI_DataSize_8b;
	MySPI.SPI_CPOL = SPI_CPOL_Low; // Mode 0
	MySPI.SPI_CPHA = SPI_CPHA_1Edge; // Mode 0
	MySPI.SPI_NSS = SPI_NSS_Soft;  // CS handles by Software
	MySPI.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2 ; // 24 / 2 = 12 MHz < 33.3 MHz
	MySPI.SPI_CRCPolynomial = 7;
	SPI_Init(SPI1 , &MySPI);
	SPI_Cmd(SPI1 , ENABLE);
}

#5

This is a working UDP code both by polling and interrupt , tested on STM32F100RB

    #include<stm32f10x.h>
    #include<stm32f10x_gpio.h>
    #include<stm32f10x_rcc.h>
    #include<stm32f10x_usart.h>
    #include<stm32f10x_tim.h>
    #include<stm32f10x_spi.h>
    #include<stm32f10x_exti.h>
    #include<misc.h>

    // ip.addr == 192.168.1.12

    void Wiz_Write_Multi( unsigned short , unsigned char , unsigned char * , unsigned short ) ; // , , Pointer , Array Count
    void Wiz_Read_Multi( unsigned short , unsigned char , unsigned char *, unsigned short ) ;   // , , Pointer , Array Count
    void LEDSetup(void);
    void SPI1_setup(void);
    void SPI_SendBye(unsigned char);
    unsigned char SPI_ReadByte();
    void Tim2_init(unsigned char);
    void Delay( unsigned char , unsigned short); // 0 = Micro , 1 = Mili
    void Wiz_Setup_A_INIT(void);
    void Wiz_Setup_B_OPEN(void);
    void ExtInterruptLineConfig(void) ;
    void GetData(unsigned char* , unsigned short* , unsigned char*);
    unsigned char SendData(unsigned char* , unsigned short);
    unsigned short DataRecievedCheck(void);

    #define BSB_Common_Reg 0b00000       // Block Selection Bits - Common Reg
    #define BSB_Sok_0_Reg 0b00001

    #define Wiz_CS  GPIO_Pin_3    // Port A
    #define Wiz_RST GPIO_Pin_2    // Port A
    //			__disable_irq();RecvCount = 0 ;  // Atomic  __enable_irq();
    unsigned volatile char DataRecieved = 0 ; // To be changed by Socket Interrupt = Volatile
    int main(void)
    {
    	LEDSetup();
    	SPI1_setup();
    	ExtInterruptLineConfig();
    	Wiz_Setup_A_INIT();
    	Wiz_Setup_B_OPEN();

    	unsigned short RecvCount = 0 ;
    	unsigned short Count = 0 ;
    	unsigned char Data[64];
    	unsigned char SCADAInfo[8];

    	while(1)
    	{
    		GPIO_SetBits(GPIOC, GPIO_Pin_8 | GPIO_Pin_9 );
    		Delay(1,500);
    		GPIO_ResetBits(GPIOC, GPIO_Pin_8 | GPIO_Pin_9 );
    		Delay(1,500);
    		// RecvCount = DataRecievedCheck();  // if( RecvCount ) Polling
    		if( DataRecieved ) // Interrupt
    		{
    			DataRecieved = 0 ;
    			GetData(Data , &Count ,SCADAInfo);  // Recieve Data = Closes Soket in the end
    			Wiz_Setup_B_OPEN();
    			SendData(Data ,Count );             // Send Data = Closes Soket in the end
    			Wiz_Setup_B_OPEN();  // Wiz UDP = Open-Close Socket every Time. But NOT in Wiz TCP
    		}
    	}
    	return 1 ;
    }
    void Wiz_Setup_A_INIT(void)
    {
    	unsigned short GAR = 0x0001 ;   // Gateway 4 Bytes
    	unsigned short SUBR = 0x0005 ;  // Subnet 4 Bytes
    	unsigned short SAR = 0x0009  ;  // Source Hardware Address MAC - 6 Bytes
    	unsigned short SIPR = 0x000F ;  // IP Address 4 Bytes
    	unsigned short RCR = 0x001B ;   // Retry Count, Retry Attempts = RCR + 1, Set RCR = 2 so Attempts = 3
    	unsigned short SIMR = 0x0018 ;  // Socket Interrupt Mask , Only enable for the Intterupts u would use , SIR = 0X00 = CLEARED BY STM32

    	// Reset
    	Delay(1,200);
    	GPIO_ResetBits(GPIOA, Wiz_RST);
    	Delay(1,5); // Reset Time = 1.5 Mili Sec
    	GPIO_SetBits(GPIOA, Wiz_RST);
    	Delay(1,2);

    	// Auto Negotionaion = 2 Chips decide their Speed ( 10 / 100 MBPs ) and Duplex ( Sigle / double)
    	// Link = Up => Auto Negotiation is success
    	//	 unsigned short PHYCFGR = 0x002E  ;
    	//	 unsigned char PHYCFGRValue = 0x00 ;    // If PHYCFGRValue && 0x01 = 1 => Link UP
    	//	 while( ( PHYCFGRValue & 0x01) != 0 )  // 0Th bit of PHYCFGR Reg = 1
    	//	 Wiz_Read_Multi( PHYCFGR , BSB_Common_Reg  , &PHYCFGRValue , 1);

    	// Mode Reg = 0x00 after Reset = ok
    	unsigned char mac[] = {0x00,0x16,0x36,0xDE,0x58,0xF6};
    	unsigned char ip[] = {192,168,1,12};      // 0xC0 , 0xA8 , 0x01 , 0x0C
    	unsigned char subnet[] = {255,255,255,0}; // 255 = 0xFF
    	unsigned char gate[] = {192,168,1,8}; // My Own laptop
    	// Direct connection by patch cable between W5500 and laptop. gateway defined as laptop IP

    	Wiz_Write_Multi(SAR  , BSB_Common_Reg , mac , sizeof(mac));
    	Wiz_Write_Multi(SIPR , BSB_Common_Reg , ip,   sizeof(ip));
    	Wiz_Write_Multi(SUBR , BSB_Common_Reg , subnet , sizeof(subnet));
    	Wiz_Write_Multi(GAR  , BSB_Common_Reg , gate ,   sizeof(gate));

    	unsigned char RCRValue = 0x02 ; // Retry Count = 0x02 + 1 = 3
    	Wiz_Write_Multi(RCR  , BSB_Common_Reg , &RCRValue ,   sizeof(RCRValue));
    	// Default RTR Retry Time At Reset = 2000 = 2000 x 0.1 = 200 MiLi Sec = OK
    	// Default IMR Interrupt Mask Reg = 0x00 = All Desabled = OK

    	unsigned char SIMRValue = 0x01 ; // Socket Interrupt Mask keep Socket Interrupts Active AS PER PROJECT  Needs
    	Wiz_Write_Multi(SIMR  , BSB_Common_Reg , &SIMRValue ,   sizeof(SIMRValue)); // Only Socket 0 Interrupt = Enable
    }
    void Wiz_Setup_B_OPEN(void)
    {
    	unsigned short Sok_0_Mod_Reg = 0x0000 ;  // Mode Offet Address
    	unsigned char Sok_0_Mod_Value = 0x02 ;   // Sock 0 Mode = 0x22 = UDP

    	unsigned short Sok_0_Port_Reg = 0x0004 ; // 2 Bytes - Sock 0 Port Offset Address
    	unsigned char port[] = {0x13,0x88};  // 0x1388 = 5000

    	unsigned short Sok_0_Comand_Reg = 0x0001 ; //
    	unsigned char Comand_OPEN = 0x01 ;   // Command Reg = 0x01 => Socket OPEN
    	unsigned char Comand_CLOSE = 0x10 ;  // Command Reg = 0x10 => Socket CLOSE

    	unsigned short Sok_0_Status_Reg = 0x0003 ;
    	unsigned char Status_Socket = 0x00 ; // => 0x02 = UDP

    	START:   // Label
    	Wiz_Write_Multi(Sok_0_Mod_Reg  , BSB_Sok_0_Reg , &Sok_0_Mod_Value , 1);  // Mode = 0x22 = UDP
    	Wiz_Write_Multi(Sok_0_Port_Reg  , BSB_Sok_0_Reg , port , 2 );            // Port = 5000
    	Wiz_Write_Multi(Sok_0_Comand_Reg  , BSB_Sok_0_Reg , &Comand_OPEN , 1 );  // Open Socket
    	Wiz_Read_Multi(Sok_0_Status_Reg , BSB_Sok_0_Reg  , &Status_Socket , 1 );  // Get Socket Status
    	if(Status_Socket != 0x22 ) // Status Reg = 0x22 => Socket = UDP
    	{
    		Wiz_Write_Multi(Sok_0_Comand_Reg  , BSB_Sok_0_Reg , &Comand_CLOSE , 1 );  // Close Socket
    		goto START ;
    	}
    	// else socket is opened , Keep looping till Socket is opened
    }
    unsigned short DataRecievedCheck(void) // Socket Recieve Size Register RSR != 0x0000 .
    {
    	unsigned short Sok_0_RSR_reg = 0x0026 ; // 2 Bytes - Recieved Size
    	unsigned char RSRValue[] = {0x00,0x00};
    	Wiz_Read_Multi(Sok_0_RSR_reg  , BSB_Sok_0_Reg , RSRValue , 2 );
    	unsigned short RCVCount =   ( RSRValue[0] << 8 ) | RSRValue[1];
    	return RCVCount ;
    }
    unsigned char SendData(unsigned char* data , unsigned short count )
    {
    	// Disable Interrupt during send, else Sending data will fire Send_OK or Time Out Interrupt
    	// which will make volatile DataRecieved = 1 so senddata will run again........making it Infinite Loop
    	// After send is complete , SIMR = 0x01 = Data Recieved interrupt will fire
    	unsigned short SIMR = 0x0018;
    	unsigned char SIMRValueDisable = 0x00 ;  // Disable All Wiz Interrupt
    	unsigned char SIMRValueEnable0 = 0x01 ;  // Enable Interrupt 0 Wiz Interrupt
    	Wiz_Write_Multi(SIMR  , BSB_Common_Reg , &SIMRValueDisable , 1); // Disable Interrupt


    	// UDP MTU = 1472 Deafult
    	unsigned char BSB_Sok_0_Tx_Buffer = 0b00010;

    	unsigned short Sok_0_Tx_FreeSize_Reg = 0x0020 ; // 2 bytes
    	unsigned char Sok_0_Tx_FreeSize_Value[] = {0x00 , 0x00};

    	unsigned short Sok_0_RemoteIP_Reg = 0x000C ; // 4 bytes
    	unsigned char Sok_0_RemoteIP_Value[] = {192, 168 , 1 , 8}; // SCADA PC IP

    	unsigned short Sok_0_RemotePort_Reg = 0x0010 ; // 2 bytes
    	unsigned char Sok_0_RemotePort_Value[] = {0x13 , 0x89}; // SCADA PC Listening Port 5001 = 0x1389

    	unsigned short Sok_0_Tx_WritePT_Reg = 0x0024 ; // 2 bytes
    	unsigned char Sok_0_Tx_WritePT_value[] = {0x00 , 0x00};

    	unsigned short Sok_0_Comand_Reg = 0x0001 ;
    	unsigned char Comand_SEND = 0x20 ;   // 0x20 => Socket SEND
    	unsigned char Comand_CLOSE = 0x10 ;

    	unsigned short Sok_0_INTR_Reg = 0x0002 ;
    	unsigned char Sok_0_INTR_Value = 0x00 ;   // Check which Interrupt occured, Reset by Writing 1

    	//	unsigned short IR_Reg = 0x0015 ; // Chip Level Interrupt Register
    	//	unsigned char IR_Value = 0x00 ;

    	unsigned short FreeSize = 0 ;
    	FREESIZE : // Label
    	Wiz_Read_Multi(Sok_0_Tx_FreeSize_Reg , BSB_Sok_0_Reg  , Sok_0_Tx_FreeSize_Value , 2 );
    	FreeSize = ( Sok_0_Tx_FreeSize_Value[0] << 8 ) | Sok_0_Tx_FreeSize_Value[1];
    	if( FreeSize < count)
    		goto FREESIZE ;

    	Wiz_Write_Multi(Sok_0_RemoteIP_Reg  , BSB_Sok_0_Reg , Sok_0_RemoteIP_Value , 4 ); // SCADA IP
    	Wiz_Write_Multi(Sok_0_RemotePort_Reg  , BSB_Sok_0_Reg , Sok_0_RemotePort_Value , 2 ); // SCADA Listening Port

    	unsigned short dist_ptr = 0 ;
    	Wiz_Read_Multi(Sok_0_Tx_WritePT_Reg , BSB_Sok_0_Reg  , Sok_0_Tx_WritePT_value , 2 );
    	dist_ptr = ( Sok_0_Tx_WritePT_value[0] << 8 ) | Sok_0_Tx_WritePT_value[1];

    	Wiz_Write_Multi(dist_ptr , BSB_Sok_0_Tx_Buffer  , data , count ); // write Data to Wiz Tx Buffer

    	dist_ptr += count;
    	Sok_0_Tx_WritePT_value[0] = dist_ptr >> 8 ; // 0 = MS Byte
    	Sok_0_Tx_WritePT_value[1] = dist_ptr & 0x00FF ; // 1 = LS Byte
    	Wiz_Write_Multi(Sok_0_Tx_WritePT_Reg  , BSB_Sok_0_Reg , Sok_0_Tx_WritePT_value , 2 );

    	Wiz_Write_Multi(Sok_0_Comand_Reg  , BSB_Sok_0_Reg , &Comand_SEND , 1 ); // SEND
    	unsigned char success = 0 ;
    	while(1)
    	{
    		Wiz_Read_Multi(Sok_0_INTR_Reg , BSB_Sok_0_Reg  , &Sok_0_INTR_Value , 1 ); // read Interrupt Reg
    		if( (Sok_0_INTR_Value & ( 1 << 4)) != 0 )      //  Send Ok
    		{
    			success = 1 ; // Break out of While Loop
    			break;
    		}
    		if( (Sok_0_INTR_Value & ( 1 << 3)) != 0 )      // Send Time Out
    		{
    			success = 0 ;
    			break; // Break out of While Loop
    		}
    	}
    	Sok_0_INTR_Value = 0x1F;// IR_n = 1 To Reset INTR
    	Wiz_Write_Multi(Sok_0_INTR_Reg , BSB_Sok_0_Reg  , &Sok_0_INTR_Value , 1 ); // Reset S0_IR = Write 1
    	Wiz_Write_Multi(Sok_0_Comand_Reg  , BSB_Sok_0_Reg , &Comand_CLOSE , 1 ); // CLOSE

    	// Enable only All Interrupt
    	Wiz_Write_Multi(SIMR  , BSB_Common_Reg , &SIMRValueEnable0 , 1); // Disable Interrupt
    	return success ;
    }
    void GetData(unsigned char* data , unsigned short* count , unsigned char* UDPInfoPack) // Socket Recieve Size Register RSR != 0x0000 .
    {
    	unsigned short Sok_0_RD_Point_Reg = 0x0028 ; // 2 bytes
    	unsigned char Sok_0_RD_Point_value[] = {0x00 , 0x00};
    	Wiz_Read_Multi(Sok_0_RD_Point_Reg , BSB_Sok_0_Reg  , Sok_0_RD_Point_value , 2 );
    	unsigned short src_ptr = ( Sok_0_RD_Point_value[0] << 8 ) | Sok_0_RD_Point_value[1];
    	unsigned char BSB_Sok_0_Rx_Buffer = 0b00011;
    	Wiz_Read_Multi(src_ptr , BSB_Sok_0_Rx_Buffer  , UDPInfoPack , 8 );
    	*count = (*(UDPInfoPack + 6) << 8 ) | (*(UDPInfoPack + 7)) ;
    	src_ptr += 8;
    	Wiz_Read_Multi(src_ptr, BSB_Sok_0_Rx_Buffer  , data , *count );

    	// Set Read-pointer of Socket_0
    	src_ptr += *count ;
    	src_ptr -= 8 ;
    	Sok_0_RD_Point_value[0] = src_ptr >> 8 ;     // MS Byte
    	Sok_0_RD_Point_value[1] = src_ptr & 0x00FF ; // LS Byte
    	Wiz_Write_Multi(Sok_0_RD_Point_Reg  , BSB_Sok_0_Reg , Sok_0_RD_Point_value , 2 );

    	// Set Command Recieve
    	unsigned short Sok_0_Comand_Reg = 0x0001 ;
    	unsigned char Comand_RECV = 0x04 ;   // Command Reg = 0x01 => Socket RECV
    	Wiz_Write_Multi(Sok_0_Comand_Reg  , BSB_Sok_0_Reg , &Comand_RECV , 1 );  // Command = RECV

    	//  Reset Interrupts - Clearing S0_IR (writing 1) also clears SIR_0
    	unsigned short Sok_0_IR_Reg = 0x0002 ;  // Sock 0 Interrupt Reg
    	unsigned char Sok_0_IR_Value = 0x1F ;   // Write 1 to Clear Interupt
    	Wiz_Write_Multi(Sok_0_IR_Reg  , BSB_Sok_0_Reg , &Sok_0_IR_Value , 1);

    	// Close Socket, it Rsets Rx buffer pointer
    	unsigned char Comand_CLOSE = 0x10 ;  // Command Reg = 0x10 => Socket CLOSE
    	Wiz_Write_Multi(Sok_0_Comand_Reg  , BSB_Sok_0_Reg , &Comand_CLOSE , 1 );  //  Close Socket
    }

    void Wiz_Write_Multi( unsigned short address ,  unsigned char BSB , unsigned char* bytes , unsigned short count )
    {
    	unsigned char control = ( BSB << 3 ) | 0x04 ; // BSB_RW_OM
    	// BSB 5 Bits, R/W bit W = 1 R = 0, OM 2 Bits = 00 = VDM = Chip Slect is NOT ground
    	unsigned short x = 0 ;
    	GPIO_ResetBits(GPIOA, Wiz_CS);
    	Delay(0,15);
    	SPI_SendBye(address >> 8);        // Offset Address High Byte
    	SPI_SendBye(address & 0x00FF);    // Offset Address Low Byte
    	SPI_SendBye(control);   // VDM
    	for( x = 0 ; x < count ; x++ )   // Send Data
    		SPI_SendBye(*bytes++); //  * has precedence over ++
    	Delay(0,15);
    	GPIO_SetBits(GPIOA, Wiz_CS);
    	Delay(0,15);
    }
    void Wiz_Read_Multi( unsigned short address , unsigned char BSB  , unsigned char* data , unsigned short count)
    {
    	unsigned char control =  BSB << 3  ; // BSB_RW_OM => R/W = 0 , OM = 00
    	// BSB 5 Bits, R/W bit W = 1 R = 0, OM 2 Bits = 00 = VDM = Chip Slect is NOT ground
    	unsigned short x = 0 ;
    	GPIO_ResetBits(GPIOA, Wiz_CS);
    	Delay(0,15);
    	SPI_SendBye(address >> 8);           // Offset Address High Byte
    	SPI_SendBye(address & 0x00FF);       // Offset Address Low Byte
    	SPI_SendBye(control);                // VDM - Read
    	for( x = 0 ; x < count ; x++ )       // Read Data
    		*data++ = SPI_ReadByte();  // * has precedence over ++
    	Delay(0,15);
    	GPIO_SetBits(GPIOA, Wiz_CS);
    	Delay(0,15);
    	// In C Array cant be returned , so pass an array by REFERENCE and fill it
    }

    void SPI_SendBye(unsigned char byte)
    {
    	while (  SPI_I2S_GetFlagStatus(SPI1 , SPI_I2S_FLAG_TXE) == RESET );  // sending data Wait
    	SPI_I2S_SendData(SPI1 , byte);
    	while (  SPI_I2S_GetFlagStatus(SPI1 , SPI_I2S_FLAG_RXNE) == RESET ); // Wait for data
    	byte = SPI_I2S_ReceiveData(SPI1);        // Dummy read to generate clock
    }
    unsigned char SPI_ReadByte(void)
    {
    	while (  SPI_I2S_GetFlagStatus(SPI1 , SPI_I2S_FLAG_TXE) == RESET );
    	SPI_I2S_SendData(SPI1 , 0xff);     // Dummy write to generate clock
    	while (  SPI_I2S_GetFlagStatus(SPI1 , SPI_I2S_FLAG_RXNE) == RESET );
    	return (unsigned char)SPI_I2S_ReceiveData(SPI1);
    }
    void SPI1_setup(void)
    {
    	// Enable clock for SPI1 AFIO GPIOA  GPIOB
    	RCC->APB2ENR |= ( 1<<12 ) | ( 1<<0 ) | ( 1<<2 ) | ( 1<<3 );

    	// PA 3 = CS           PA 2 = RST
    	GPIO_InitTypeDef GpioPin;
    	GpioPin.GPIO_Pin = Wiz_CS | Wiz_RST ;
    	GpioPin.GPIO_Speed = GPIO_Speed_2MHz;
    	GpioPin.GPIO_Mode = GPIO_Mode_Out_PP ; // CS = DO = Out Push Pull
    	GPIO_Init(GPIOA, &GpioPin);
    	GPIO_SetBits(GPIOA, Wiz_CS | Wiz_RST ); // CS + RST = High

    	// SCK  = PA5 = Alternate Push Pull 10 MHz
    	// MISO = PA6 = Input pull up
    	// MOSI = PA7 = Alternate Push Pull 10 MHz

    	GpioPin.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7 ; // Clock + MOSI
    	GpioPin.GPIO_Speed = GPIO_Speed_10MHz;
    	GpioPin.GPIO_Mode = GPIO_Mode_AF_PP;
    	GPIO_Init(GPIOA, &GpioPin);
    	// Few example say MOSI is Alternate Push Pull
    	GpioPin.GPIO_Pin = GPIO_Pin_6 ;
    	GpioPin.GPIO_Mode = GPIO_Mode_IPU; // Input Pull Up
    	GPIO_Init(GPIOA, &GpioPin); // Clock + MOSI

    	SPI_InitTypeDef   MySPI;
    	MySPI.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    	MySPI.SPI_Mode = SPI_Mode_Master;
    	MySPI.SPI_DataSize = SPI_DataSize_8b;
    	MySPI.SPI_CPOL = SPI_CPOL_Low; // Mode 0
    	MySPI.SPI_CPHA = SPI_CPHA_1Edge; // Mode 0
    	MySPI.SPI_NSS = SPI_NSS_Soft;  // CS handles by Software
    	MySPI.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2 ; // 24 / 2 = 12 MHz < 33.3 MHz
    	MySPI.SPI_CRCPolynomial = 7;
    	SPI_Init(SPI1 , &MySPI);
    	SPI_Cmd(SPI1 , ENABLE);
    }

    // Tim 2 = General Purpose , CNT ARR PSC = 16 Bit in STM32F100RB.
    void Tim2_init(unsigned char base) // base = 0 = Micro , base = 1 Mili
    {
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
    	TIM_TimeBaseInitTypeDef TIM;
    	TIM_TimeBaseStructInit(&TIM);
    	if(base)
    		TIM.TIM_Prescaler = (SystemCoreClock/1000)-1;    // 10 CNT = 1 Mili Sec
    	else
    		TIM.TIM_Prescaler = (SystemCoreClock/1000000)-1; // 1 CNT = 1 Micro Sec
    	TIM.TIM_Period = 0xFFFF - 1 ; // ARR 32 Bits
    	TIM.TIM_ClockDivision = 0;
    	TIM.TIM_CounterMode = TIM_CounterMode_Up;
    	TIM_TimeBaseInit(TIM2,&TIM);
    	TIM2->CNT = 0 ; // Reset
    	TIM_Cmd(TIM2,ENABLE); // Timer Start
    	// STM32F100RB Tim CLK = SystemCoreClock
    	// STM32F4 Tim CLK = SystemCoreClock / 2
    }

    void Delay( unsigned char base , unsigned short Ticks) // 0 = Micro , 1 = Mili
    {
    	Tim2_init(base); // Reset during Init
    	volatile unsigned short start = TIM2->CNT;
    	while((TIM2->CNT - start) <= Ticks);
    	// Stop timer
    	TIM_Cmd(TIM2,DISABLE);
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,DISABLE); // Power Save
    }

    void LEDSetup(void)
    {
    	RCC->APB2ENR |= ( 1 << 4 );
    	GPIO_InitTypeDef GpioPin;
    	GpioPin.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 ;
    	GpioPin.GPIO_Speed = GPIO_Speed_10MHz;
    	GpioPin.GPIO_Mode = GPIO_Mode_Out_PP ;
    	GPIO_Init(GPIOC, &GpioPin);
    }

    void ExtInterruptLineConfig(void)
    {
    	RCC->APB2ENR |= (1<<4) | (1<<0) ; // AFIO is must for EXTI
    	GPIO_InitTypeDef GPIO_InitStruct;
    	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
    	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 ;
    	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
    	GPIO_Init(GPIOC, &GPIO_InitStruct);

    	EXTI_InitTypeDef EXTI_InitStruct;
    	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource0); // Port Source = GPIOC
    	EXTI_InitStruct.EXTI_Line = EXTI_Line0 ;  // EXTI_Line0 = PA0 PB0 PC0 PD0 ....
    	EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; // So EXTI_Line0 = PC0
    	EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling; // Falling Edge
    	EXTI_InitStruct.EXTI_LineCmd = ENABLE;
    	EXTI_Init(&EXTI_InitStruct);

    	NVIC_InitTypeDef NVIC_InitStruct;
    	NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn; // EXTI0_IRQn = EXTI_Line0
    	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x0F; // lowest priority
    	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x0F; // lowest subpriority
    	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    	NVIC_Init(&NVIC_InitStruct);
    	// NVIC_EnableIRQ(EXTI0_IRQn);
    }
    void EXTI0_IRQHandler(void)  // Data Recieved
    {
    	if(EXTI_GetITStatus(EXTI_Line0) != RESET)
    		DataRecieved = 1 ;
    	EXTI_ClearITPendingBit(EXTI_Line0); // Must
    }

#6

Your question seems to have already been solved in the following article :slight_smile:
Thank you for providing a good reference.


#7

Thank you . Your code help me a lot


#8

Well then develop the TCP code with Interrupt , test it and share it with me…