Index: ctrl/firmware/Main/SES/Core/Inc/eth_task.h
===================================================================
--- ctrl/firmware/Main/SES/Core/Inc/eth_task.h	(revision 79)
+++ ctrl/firmware/Main/SES/Core/Inc/eth_task.h	(revision 79)
@@ -0,0 +1,15 @@
+#ifndef __ETH_THREAD_H
+#define __ETH_THREAD_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+void ethTaskStart(void* argument);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* __ETH_THREAD_H */
Index: ctrl/firmware/Main/SES/Core/Inc/eth_thread.h
===================================================================
--- ctrl/firmware/Main/SES/Core/Inc/eth_thread.h	(revision 78)
+++ 	(revision )
@@ -1,17 +1,0 @@
-#ifndef __ETH_THREAD_H
-#define __ETH_THREAD_H
-
-#include "tx_api.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-VOID ethThread(ULONG initial_input);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif /* __ETH_THREAD_H */
Index: ctrl/firmware/Main/SES/Core/Src/eth_task.cpp
===================================================================
--- ctrl/firmware/Main/SES/Core/Src/eth_task.cpp	(revision 79)
+++ ctrl/firmware/Main/SES/Core/Src/eth_task.cpp	(revision 79)
@@ -0,0 +1,167 @@
+#include <cstdio>
+#include <cstdint>
+
+#include "main.h"
+#include "FreeRTOS.h"
+#include "task.h"
+
+#include "eth_task.h"
+
+#include "loopback.h"
+#include "wizchip_conf.h"
+#include "dhcp.h"
+
+
+static constexpr unsigned ETH_MAX_BUF_SIZE = 2048U;
+static constexpr unsigned SOCKET_DHCP = 1;
+
+static constexpr uint16_t delay_ms = 500U;
+
+
+static uint8_t dhcp_buffer[ETH_MAX_BUF_SIZE];
+
+wiz_NetInfo gWIZNETINFO = {
+		.mac = {0x00, 0x08, 0xdc, 0x6f, 0x00, 0x8a},
+		.ip = {192, 168, 11, 109},
+		.sn = {255, 255, 255, 0},
+		.gw = {192, 168, 11, 1},
+		.dns = {8, 8, 8, 8},
+		.dhcp = NETINFO_DHCP
+};
+
+static void ip_assigned(void);
+static void ip_updated(void);
+static void ip_conflict(void);
+static void wizchip_initialize(void);
+static void wizchip_reset(void);
+static void wizchip_check(void);
+static void wizchip_dhcp_init(void);
+
+//------------------------------------------------------------------------------
+
+void ethTaskStart(void* argument)
+{
+	(void)argument;
+
+	wizchip_initialize();
+
+	if (gWIZNETINFO.dhcp == NETINFO_DHCP) // DHCP
+	{
+		wizchip_dhcp_init();
+
+		while (DHCP_run() != DHCP_IP_LEASED)
+	      wiz_delay_ms(1000);
+	}
+	else // static
+	{
+		ctlnetwork(CN_SET_NETINFO, &gWIZNETINFO);
+		printf("\r\n----------STATIC Net Information--------------\r\n");
+		//print_network_information();
+	}
+
+	while (1)
+	{
+		if (gWIZNETINFO.dhcp == NETINFO_DHCP) DHCP_run();
+
+		loopback_tcps(2, dhcp_buffer, 5000U);
+
+		vTaskDelay(delay_ms);
+	}
+}
+
+//------------------------------------------------------------------------------
+
+void wizchip_reset(void)
+{
+	HAL_GPIO_WritePin(ETH_SPI_PWR_GPIO_Port, ETH_SPI_PWR_Pin, GPIO_PIN_RESET);
+	vTaskDelay(pdMS_TO_TICKS(100U));
+	HAL_GPIO_WritePin(ETH_SPI_RST_GPIO_Port, ETH_SPI_RST_Pin, GPIO_PIN_SET);
+	vTaskDelay(pdMS_TO_TICKS(65U));	  // Min 60.3ms
+}
+
+//------------------------------------------------------------------------------
+
+void wizchip_initialize(void)
+{
+	uint8_t W5100S_AdrSet[2][4]= {{2,2,2,2},{2,2,2,2}};
+    uint8_t tmp1, tmp2;
+	intr_kind temp= IK_DEST_UNREACH;
+
+	wizchip_reset();
+
+	if (ctlwizchip(CW_INIT_WIZCHIP, (void*)W5100S_AdrSet) == -1)
+		printf(">>>>W5100s memory initialization failed\r\n");
+
+	if(ctlwizchip(CW_SET_INTRMASK,&temp) == -1)
+		printf("W5100S interrupt\r\n");
+
+	wizchip_check();
+
+	while(1)
+	{
+		ctlwizchip(CW_GET_PHYLINK, &tmp1 );
+		ctlwizchip(CW_GET_PHYLINK, &tmp2 );
+		if (tmp1 == PHY_LINK_ON && tmp2 == PHY_LINK_ON) break;
+	}
+}
+
+//------------------------------------------------------------------------------
+
+static void ip_assigned(void)
+{
+	printf("IP-address was assigned.\n");
+
+	uint8_t ip[4];
+	getIPfromDHCP(ip);
+	printf("IP-address: %u.%u.%u.%u\n", ip[0], ip[1], ip[2], ip[3]);
+
+	uint8_t nm[4];
+	getSNfromDHCP(nm);
+	printf("Subnet mask: %u.%u.%u.%u\n", nm[0], nm[1], nm[2], nm[3]);
+
+	uint8_t gw[4];
+	getGWfromDHCP(gw);
+	printf("Gateway address: %u.%u.%u.%u\n", gw[0], gw[1], gw[2], gw[3]);
+
+	uint8_t dns[4];
+	getDNSfromDHCP(dns);
+	printf("DNS address: %u.%u.%u.%u\n", dns[0], dns[1], dns[2], dns[3]);
+
+	printf("Lease time: %u\n", getDHCPLeasetime());
+}
+
+//------------------------------------------------------------------------------
+
+static void ip_updated(void)
+{
+	printf("IP-address was updated.\n");
+}
+
+//------------------------------------------------------------------------------
+
+static void ip_conflict(void)
+{
+	printf("IP-address conflict!.\n");
+}
+
+//------------------------------------------------------------------------------
+
+void wizchip_check(void)
+{
+	// Read version register
+    if (getVER() != 0x51) // W5100S
+    {
+        printf(" ACCESS ERR : VERSIONR != 0x51, read value = 0x%02x\n", getVER());
+        while (1);
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void wizchip_dhcp_init(void)
+{
+    DHCP_init(SOCKET_DHCP, dhcp_buffer);
+    reg_dhcp_cbfunc(ip_assigned, ip_updated, ip_conflict);
+}
+
+//------------------------------------------------------------------------------
Index: ctrl/firmware/Main/SES/Core/Src/eth_thread.cpp
===================================================================
--- ctrl/firmware/Main/SES/Core/Src/eth_thread.cpp	(revision 78)
+++ 	(revision )
@@ -1,17 +1,0 @@
-#include <cstdio>
-#include <cstdint>
-
-
-#include "eth_thread.h"
-
-
-VOID ethThread(ULONG initial_input)
-{
-	(void)initial_input;
-
-
-	while (1)
-	{
-		tx_thread_sleep(1000U);
-	}
-}
Index: ctrl/firmware/Main/SES/Core/Src/main_task.cpp
===================================================================
--- ctrl/firmware/Main/SES/Core/Src/main_task.cpp	(revision 78)
+++ ctrl/firmware/Main/SES/Core/Src/main_task.cpp	(revision 79)
@@ -10,13 +10,9 @@
 #include "utils.h"
 
-#include "wizchip_conf.h"
-#include "dhcp.h"
-
-static constexpr unsigned ETH_MAX_BUF_SIZE = 2048U;
-static constexpr unsigned SOCKET_DHCP = 1;
 
 static const char* const TAG = "MAIN";
 
 static constexpr uint16_t delay_ms = 5000;
+
 static constexpr unsigned MAX_CHARS_IN_VOLUME_NAME = 12U;
 static uint8_t volumeName[MAX_CHARS_IN_VOLUME_NAME];
@@ -25,26 +21,7 @@
 
 static FATFS fs;// __attribute__((section(".DTCM_RAM")));     // Filesystem object
-static uint8_t dhcp_buffer[ETH_MAX_BUF_SIZE];
-
-wiz_NetInfo gWIZNETINFO = {
-		.mac = {0x00, 0x08, 0xdc, 0x6f, 0x00, 0x8a},
-		.ip = {192, 168, 11, 109},
-		.sn = {255, 255, 255, 0},
-		.gw = {192, 168, 11, 1},
-		.dns = {8, 8, 8, 8},
-		.dhcp = NETINFO_DHCP
-};
-
 
 FRESULT scan_files (TCHAR* path);
 FRESULT list_dir (const char* path);
-
-static void ip_assigned(void);
-static void ip_updated(void);
-static void ip_conflict(void);
-static void wizchip_initialize(void);
-static void wizchip_reset(void);
-static void wizchip_check(void);
-static void wizchip_dhcp_init(void);
 
 //------------------------------------------------------------------------------
@@ -53,20 +30,4 @@
 {
 	(void)argument;
-
-	wizchip_initialize();
-
-	if (gWIZNETINFO.dhcp == NETINFO_DHCP) // DHCP
-	{
-		wizchip_dhcp_init();
-
-		while (DHCP_run() != DHCP_IP_LEASED)
-	      wiz_delay_ms(1000);
-	}
-	else // static
-	{
-		ctlnetwork(CN_SET_NETINFO, &gWIZNETINFO);
-		printf("\r\n----------STATIC Net Information--------------\r\n");
-		//print_network_information();
-	}
 
 	//DHCP_init(0, dhcp_buffer);
@@ -95,100 +56,4 @@
 }
 
-//------------------------------------------------------------------------------
-
-void wizchip_reset(void)
-{
-	HAL_GPIO_WritePin(ETH_SPI_PWR_GPIO_Port, ETH_SPI_PWR_Pin, GPIO_PIN_RESET);
-	vTaskDelay(pdMS_TO_TICKS(100U));
-	HAL_GPIO_WritePin(ETH_SPI_RST_GPIO_Port, ETH_SPI_RST_Pin, GPIO_PIN_SET);
-	vTaskDelay(pdMS_TO_TICKS(65U));	  // Min 60.3ms
-}
-
-//------------------------------------------------------------------------------
-
-void wizchip_initialize(void)
-{
-	uint8_t W5100S_AdrSet[2][4]= {{2,2,2,2},{2,2,2,2}};
-    uint8_t tmp1, tmp2;
-	intr_kind temp= IK_DEST_UNREACH;
-
-	wizchip_reset();
-
-	if (ctlwizchip(CW_INIT_WIZCHIP, (void*)W5100S_AdrSet) == -1)
-		printf(">>>>W5100s memory initialization failed\r\n");
-
-	if(ctlwizchip(CW_SET_INTRMASK,&temp) == -1)
-		printf("W5100S interrupt\r\n");
-
-	wizchip_check();
-
-	while(1)
-	{
-		ctlwizchip(CW_GET_PHYLINK, &tmp1 );
-		ctlwizchip(CW_GET_PHYLINK, &tmp2 );
-		if (tmp1 == PHY_LINK_ON && tmp2 == PHY_LINK_ON) break;
-	}
-}
-
-//------------------------------------------------------------------------------
-
-static void ip_assigned(void)
-{
-	printf("IP-address was assigned.\n");
-
-	uint8_t ip[4];
-	getIPfromDHCP(ip);
-	printf("IP-address: %u.%u.%u.%u\n", ip[0], ip[1], ip[2], ip[3]);
-
-	uint8_t nm[4];
-	getSNfromDHCP(nm);
-	printf("Subnet mask: %u.%u.%u.%u\n", nm[0], nm[1], nm[2], nm[3]);
-
-	uint8_t gw[4];
-	getGWfromDHCP(gw);
-	printf("Gateway address: %u.%u.%u.%u\n", gw[0], gw[1], gw[2], gw[3]);
-
-	uint8_t dns[4];
-	getDNSfromDHCP(dns);
-	printf("DNS address: %u.%u.%u.%u\n", dns[0], dns[1], dns[2], dns[3]);
-
-	printf("Lease time: %u\n", getDHCPLeasetime());
-}
-
-//------------------------------------------------------------------------------
-
-static void ip_updated(void)
-{
-	printf("IP-address was updated.\n");
-}
-
-//------------------------------------------------------------------------------
-
-static void ip_conflict(void)
-{
-	printf("IP-address conflict!.\n");
-}
-
-//------------------------------------------------------------------------------
-
-void wizchip_check(void)
-{
-	// Read version register
-    if (getVER() != 0x51) // W5100S
-    {
-        printf(" ACCESS ERR : VERSIONR != 0x51, read value = 0x%02x\n", getVER());
-        while (1);
-    }
-}
-
-//------------------------------------------------------------------------------
-
-void wizchip_dhcp_init(void)
-{
-    DHCP_init(SOCKET_DHCP, dhcp_buffer);
-    reg_dhcp_cbfunc(ip_assigned, ip_updated, ip_conflict);
-}
-
-//------------------------------------------------------------------------------
 
 /* List contents of a directory */
Index: ctrl/firmware/Main/SES/Wiznet/Ethernet/W5100S/w5100s.c
===================================================================
--- ctrl/firmware/Main/SES/Wiznet/Ethernet/W5100S/w5100s.c	(revision 79)
+++ ctrl/firmware/Main/SES/Wiznet/Ethernet/W5100S/w5100s.c	(revision 79)
@@ -0,0 +1,514 @@
+//*****************************************************************************
+//
+//! \file w5100S.c
+//! \brief W5100S HAL Interface.
+//! \version 1.0.0
+//! \date 2018/03/29
+//! \par  Revision history
+//!       <2018/03/29> 1st Release
+//! \author Peter
+//! 
+//! Copyright (c)  2013, WIZnet Co., LTD.
+//! All rights reserved.
+//! 
+//! Redistribution and use in source and binary forms, with or without 
+//! modification, are permitted provided that the following conditions 
+//! are met: 
+//! 
+//!     * Redistributions of source code must retain the above copyright 
+//! notice, this list of conditions and the following disclaimer. 
+//!     * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution. 
+//!     * Neither the name of the <ORGANIZATION> nor the names of its 
+//! contributors may be used to endorse or promote products derived 
+//! from this software without specific prior written permission. 
+//! 
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+#include "w5100s.h"
+
+#if   (_WIZCHIP_ == W5100S)
+/**
+@brief  This function writes the data into W5100S registers.
+*/
+void     WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb )
+{
+   uint8_t spi_data[4];
+
+   WIZCHIP_CRITICAL_ENTER();
+   WIZCHIP.CS._select();
+
+#if( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_))
+   if(!WIZCHIP.IF.SPI._write_burst) 	// byte operation
+   {
+      WIZCHIP.IF.SPI._write_byte(0xF0);
+      WIZCHIP.IF.SPI._write_byte((AddrSel & 0xFF00) >>  8);
+      WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF) >>  0);
+      WIZCHIP.IF.SPI._write_byte(wb);    // Data write (write 1byte data)
+   }
+   else     // burst operation
+   {
+      spi_data[0] = 0xF0;
+		spi_data[1] = (AddrSel & 0xFF00) >>  8;
+		spi_data[2] = (AddrSel & 0x00FF) >>  0;
+		spi_data[3] = wb;
+		WIZCHIP.IF.SPI._write_burst(spi_data, 4);
+   }
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_5500_) )
+   if(!WIZCHIP.IF.SPI._write_burst) 	// byte operation
+   {
+	   WIZCHIP.IF.SPI._write_byte((AddrSel & 0xFF00) >>  8);
+	   WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF) >>  0);
+	   WIZCHIP.IF.SPI._write_byte(0xF0);
+	   WIZCHIP.IF.SPI._write_byte(wb);    // Data write (write 1byte data)
+   }
+   else     // burst operation
+   {
+      spi_data[0] = (AddrSel & 0xFF00) >>  8;
+		spi_data[1] = (AddrSel & 0x00FF) >>  0;
+		spi_data[2] = 0xF0;
+		spi_data[3] = wb;
+		WIZCHIP.IF.SPI._write_burst(spi_data, 4);
+
+   }
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) )
+
+   //add indirect bus 
+   //M20150601 : Rename the function for integrating with ioLibrary
+   //WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >>  8);
+   //WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF));	
+   //WIZCHIP.IF.BUS._write_byte(IDM_DR,wb);
+   WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >>  8);
+   WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF));	
+   WIZCHIP.IF.BUS._write_data(IDM_DR,wb);
+#else
+   #error "Unknown _WIZCHIP_IO_MODE_ in W5100. !!!"
+#endif
+
+   WIZCHIP.CS._deselect();
+   WIZCHIP_CRITICAL_EXIT();
+}
+/**
+@brief  This function reads the value from W5100S registers.
+*/
+uint8_t  WIZCHIP_READ(uint32_t AddrSel)
+{
+   uint8_t ret;
+   uint8_t spi_data[3];
+   WIZCHIP_CRITICAL_ENTER();
+   WIZCHIP.CS._select();
+
+#if( (_WIZCHIP_IO_MODE_ ==  _WIZCHIP_IO_MODE_SPI_))
+   if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) 	// byte operation
+   {
+        WIZCHIP.IF.SPI._write_byte(0x0F);
+        WIZCHIP.IF.SPI._write_byte((AddrSel & 0xFF00) >>  8);
+        WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF) >>  0);
+   }
+   else
+   {
+        spi_data[0] = 0x0F;
+        spi_data[1] = (AddrSel & 0xFF00) >>  8;
+        spi_data[2] = (AddrSel & 0x00FF) >>  0;
+        WIZCHIP.IF.SPI._write_burst(spi_data, 3);
+   }
+   ret = WIZCHIP.IF.SPI._read_byte(); 
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_5500_) )
+   if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) 	// burst operation
+	{
+        WIZCHIP.IF.SPI._write_byte((AddrSel & 0xFF00) >>  8);
+        WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF) >>  0);
+        WIZCHIP.IF.SPI._write_byte(0x0F);
+   }
+   else
+   {
+		spi_data[0] = (AddrSel & 0xFF00) >>  8;
+		spi_data[1] = (AddrSel & 0x00FF) >>  0;
+		spi_data[2] = 0x0F
+		WIZCHIP.IF.SPI._write_burst(spi_data, 3);
+   }
+   ret = WIZCHIP.IF.SPI._read_byte();
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) )
+
+   //add indirect bus
+   //M20150601 : Rename the function for integrating with ioLibrary
+   //WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >>  8);
+   //WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF));	
+   //ret = WIZCHIP.IF.BUS._read_byte(IDM_DR);
+   WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >>  8);
+   WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF));
+   ret = WIZCHIP.IF.BUS._read_data(IDM_DR);
+
+#else
+   #error "Unknown _WIZCHIP_IO_MODE_ in W5100S. !!!"   
+#endif
+
+   WIZCHIP.CS._deselect();
+   WIZCHIP_CRITICAL_EXIT();
+   return ret;
+}
+
+
+/**
+@brief  This function writes into W5100S memory(Buffer)
+*/ 
+void     WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
+{
+   uint8_t spi_data[3];
+   uint16_t i = 0;
+
+   WIZCHIP_CRITICAL_ENTER();
+   WIZCHIP.CS._select();   //M20150601 : Moved here.
+
+#if((_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_))
+
+   if(!WIZCHIP.IF.SPI._write_burst) 	// byte operation
+   {
+      WIZCHIP.IF.SPI._write_byte(0xF0);
+      WIZCHIP.IF.SPI._write_byte((((uint16_t)(AddrSel+i)) & 0xFF00) >>  8);
+      WIZCHIP.IF.SPI._write_byte((((uint16_t)(AddrSel+i)) & 0x00FF) >>  0);
+
+      for(i = 0; i < len; i++)
+      {
+         WIZCHIP.IF.SPI._write_byte(pBuf[i]);    // Data write (write 1byte data)
+      }
+   }
+   else     // burst operation
+   {
+		spi_data[0] = 0xF0;
+		spi_data[1] = (((uint16_t)(AddrSel+i)) & 0xFF00) >>  8;
+		spi_data[2] = (((uint16_t)(AddrSel+i)) & 0x00FF) >>  0;
+		WIZCHIP.IF.SPI._write_burst(spi_data, 3);
+		WIZCHIP.IF.SPI._write_burst(pBuf, len);
+   }
+
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_5500_) )
+   if(!WIZCHIP.IF.SPI._write_burst) 	// byte operation
+   {
+      WIZCHIP.IF.SPI._write_byte((((uint16_t)(AddrSel+i)) & 0xFF00) >>  8);
+      WIZCHIP.IF.SPI._write_byte((((uint16_t)(AddrSel+i)) & 0x00FF) >>  0);
+      WIZCHIP.IF.SPI._write_byte(0xF0);
+
+      for(i = 0; i < len; i++)
+      {
+         WIZCHIP.IF.SPI._write_byte(pBuf[i]);    // Data write (write 1byte data)
+      }
+   }
+   else     // burst operation
+   {
+		spi_data[0] = (((uint16_t)(AddrSel+i)) & 0xFF00) >>  8;
+		spi_data[1] = (((uint16_t)(AddrSel+i)) & 0x00FF) >>  0;
+      spi_data[2] = 0xF0;
+		WIZCHIP.IF.SPI._write_burst(spi_data, 3);
+		WIZCHIP.IF.SPI._write_burst(pBuf, len);
+   }
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) )
+   //M20150601 : Rename the function for integrating with ioLibrary  
+   /*
+   WIZCHIP_WRITE(MR,WIZCHIP_READ(MR) | MR_AI);     
+   WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >>  8);
+   WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF));
+   for(i = 0 ; i < len; i++)
+      WIZCHIP.IF.BUS._write_byte(IDM_DR,pBuf[i]);
+   WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) & ~MR_AI);   
+   */
+   setMR(getMR()|MR_AI);     
+   WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >>  8);
+   WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF));
+   for(i = 0 ; i < len; i++)
+      WIZCHIP.IF.BUS._write_data(IDM_DR,pBuf[i]);
+   setMR(getMR() & ~MR_AI);   
+
+#else
+   #error "Unknown _WIZCHIP_IO_MODE_ in W5100S. !!!!"
+#endif
+   
+   WIZCHIP.CS._deselect();  //M20150601 : Moved here.
+   WIZCHIP_CRITICAL_EXIT();
+}
+
+/**
+@brief  This function reads into W5100S memory(Buffer)
+*/ 
+
+void     WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
+{
+   uint8_t spi_data[3];
+   uint16_t i = 0;
+   WIZCHIP_CRITICAL_ENTER();
+   WIZCHIP.CS._select();   //M20150601 : Moved here.
+   
+#if( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_) )
+   if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) 	// byte operation
+   {
+      WIZCHIP.IF.SPI._write_byte(0x0F);
+      WIZCHIP.IF.SPI._write_byte((uint16_t)((AddrSel+i) & 0xFF00) >>  8);
+      WIZCHIP.IF.SPI._write_byte((uint16_t)((AddrSel+i) & 0x00FF) >>  0);
+
+      for(i = 0; i < len; i++)
+      {
+         pBuf[i] = WIZCHIP.IF.SPI._read_byte(); 
+      }
+   }           
+   else																// burst operation
+   {
+		spi_data[0] = 0x0F;
+		spi_data[1] = (uint16_t)((AddrSel+i) & 0xFF00) >>  8;
+		spi_data[2] = (uint16_t)((AddrSel+i) & 0x00FF) >>  0;
+		WIZCHIP.IF.SPI._write_burst(spi_data, 3);
+		WIZCHIP.IF.SPI._read_burst(pBuf, len);
+
+   }
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_5500_) )
+   if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) 	// byte operation
+   {
+      WIZCHIP.IF.SPI._write_byte((uint16_t)((AddrSel+i) & 0xFF00) >>  8);
+      WIZCHIP.IF.SPI._write_byte((uint16_t)((AddrSel+i) & 0x00FF) >>  0);
+      WIZCHIP.IF.SPI._write_byte(0x0F);
+   
+      for(i = 0; i < len; i++)
+      {
+         pBuf[i] = WIZCHIP.IF.SPI._read_byte();
+      }
+   }
+   else																// burst operation
+   {
+		spi_data[0] = (uint16_t)((AddrSel+i) & 0xFF00) >>  8;
+		spi_data[1] = (uint16_t)((AddrSel+i) & 0x00FF) >>  0;
+      spi_data[2] = 0x0F;
+		WIZCHIP.IF.SPI._write_burst(spi_data, 3);
+		WIZCHIP.IF.SPI._read_burst(pBuf, len);
+   }
+
+
+#elif ( (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_) )
+   //M20150601 : Rename the function for integrating with ioLibrary  
+   /*
+   WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) | MR_AI);    
+   WIZCHIP.IF.BUS._write_byte(IDM_AR0,(AddrSel & 0xFF00) >>  8);
+   WIZCHIP.IF.BUS._write_byte(IDM_AR1,(AddrSel & 0x00FF));	
+   for(i = 0 ; i < len; i++)
+      pBuf[i]	= WIZCHIP.IF.BUS._read_byte(IDM_DR);
+   WIZCHIP_WRITE(MR, WIZCHIP_READ(MR) & ~MR_AI); 
+   */
+   setMR(getMR() | MR_AI);
+   WIZCHIP.IF.BUS._write_data(IDM_AR0,(AddrSel & 0xFF00) >>  8);
+   WIZCHIP.IF.BUS._write_data(IDM_AR1,(AddrSel & 0x00FF));	
+   for(i = 0 ; i < len; i++)
+      pBuf[i]	= WIZCHIP.IF.BUS._read_data(IDM_DR);
+   setMR(getMR() & ~MR_AI); 
+   
+#else
+   #error "Unknown _WIZCHIP_IO_MODE_ in W5100S. !!!!"
+#endif
+
+   WIZCHIP.CS._deselect();    //M20150601 : Moved Here.
+   WIZCHIP_CRITICAL_EXIT();
+}
+
+///////////////////////////////////
+// Socket N regsiter IO function //
+///////////////////////////////////
+
+uint16_t getSn_TX_FSR(uint8_t sn)
+{
+   uint16_t val=0,val1=0;
+   do
+   {
+      val1 = WIZCHIP_READ(Sn_TX_FSR(sn));
+      val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
+      if (val1 != 0)
+      {
+        val = WIZCHIP_READ(Sn_TX_FSR(sn));
+        val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
+      }
+   }while (val != val1);
+   return val;
+}
+
+
+uint16_t getSn_RX_RSR(uint8_t sn)
+{
+   uint16_t val=0,val1=0;
+   do
+   {
+      val1 = WIZCHIP_READ(Sn_RX_RSR(sn));
+      val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
+      if (val1 != 0)
+      {
+        val = WIZCHIP_READ(Sn_RX_RSR(sn));
+        val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
+      }
+   }while (val != val1);
+   return val;
+}
+
+/////////////////////////////////////
+// Sn_TXBUF & Sn_RXBUF IO function //
+/////////////////////////////////////
+uint32_t getSn_RxBASE(uint8_t sn)
+{
+   int8_t  i;
+#if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_)
+   uint32_t rxbase = _W5100S_IO_BASE_ + _WIZCHIP_IO_RXBUF_;
+#else   
+   uint32_t rxbase = _WIZCHIP_IO_RXBUF_;
+#endif   
+   for(i = 0; i < sn; i++)
+      rxbase += getSn_RxMAX(i);
+
+   return rxbase;
+}
+
+uint32_t getSn_TxBASE(uint8_t sn)
+{
+   int8_t  i;
+#if ( _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_)
+   uint32_t txbase = _W5100S_IO_BASE_ + _WIZCHIP_IO_TXBUF_;
+#else   
+   uint32_t txbase = _WIZCHIP_IO_TXBUF_;
+#endif   
+   for(i = 0; i < sn; i++)
+      txbase += getSn_TxMAX(i);
+   return txbase;
+}
+
+/**
+@brief  This function is being called by send() and sendto() function also. for copy the data form application buffer to Transmite buffer of the chip.
+
+This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer
+register. User should read upper byte first and lower byte later to get proper value.
+And this function is being used for copy the data form application buffer to Transmite
+buffer of the chip. It calculate the actual physical address where one has to write
+the data in transmite buffer. Here also take care of the condition while it exceed
+the Tx memory uper-bound of socket.
+
+*/
+void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
+{
+  uint16_t ptr;
+  uint16_t size;
+  uint16_t dst_mask;
+  uint16_t dst_ptr;
+
+  ptr = getSn_TX_WR(sn);
+
+  dst_mask = ptr & getSn_TxMASK(sn);
+  dst_ptr = getSn_TxBASE(sn) + dst_mask;
+  
+  if (dst_mask + len > getSn_TxMAX(sn)) 
+  {
+    size = getSn_TxMAX(sn) - dst_mask;
+    WIZCHIP_WRITE_BUF(dst_ptr, wizdata, size);
+    wizdata += size;
+    size = len - size;
+    dst_ptr = getSn_TxBASE(sn);
+    WIZCHIP_WRITE_BUF(dst_ptr, wizdata, size);
+  } 
+  else
+  {
+    WIZCHIP_WRITE_BUF(dst_ptr, wizdata, len);
+  }
+
+  ptr += len;
+
+  setSn_TX_WR(sn, ptr);  
+}
+
+
+/**
+@brief  This function is being called by recv() also. This function is being used for copy the data form Receive buffer of the chip to application buffer.
+
+This function read the Rx read pointer register
+and after copy the data from receive buffer update the Rx write pointer register.
+User should read upper byte first and lower byte later to get proper value.
+It calculate the actual physical address where one has to read
+the data from Receive buffer. Here also take care of the condition while it exceed
+the Rx memory uper-bound of socket.
+*/
+void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
+{
+  uint16_t ptr;
+  uint16_t size;
+  uint16_t src_mask;
+  uint16_t src_ptr;
+
+  ptr = getSn_RX_RD(sn);
+  
+  src_mask = (uint32_t)ptr & getSn_RxMASK(sn);
+  src_ptr = (getSn_RxBASE(sn) + src_mask);
+
+  
+  if( (src_mask + len) > getSn_RxMAX(sn) ) 
+  {
+    size = getSn_RxMAX(sn) - src_mask;
+    WIZCHIP_READ_BUF((uint32_t)src_ptr, (uint8_t*)wizdata, size);
+    wizdata += size;
+    size = len - size;
+	src_ptr = getSn_RxBASE(sn);
+    WIZCHIP_READ_BUF(src_ptr, (uint8_t*)wizdata, size);
+  } 
+  else
+  {
+    WIZCHIP_READ_BUF(src_ptr, (uint8_t*)wizdata, len);
+  }
+    
+  ptr += len;
+  
+  setSn_RX_RD(sn, ptr);
+}
+
+void wiz_recv_ignore(uint8_t sn, uint16_t len)
+{
+  uint16_t ptr;
+
+  ptr = getSn_RX_RD(sn);
+  
+  ptr += len;
+  setSn_RX_RD(sn,ptr);
+}
+
+void wiz_mdio_write(uint8_t PHYMDIO_regadr, uint16_t var)
+{
+    WIZCHIP_WRITE(PHYRAR,PHYMDIO_regadr);
+    WIZCHIP_WRITE(PHYDIR, (uint8_t)(var >> 8));
+    WIZCHIP_WRITE(PHYDIR+1, (uint8_t)(var));
+    WIZCHIP_WRITE(PHYACR, PHYACR_WRITE);
+    while(WIZCHIP_READ(PHYACR));  //wait for command complete
+}
+
+uint16_t wiz_mdio_read(uint8_t PHYMDIO_regadr)
+{
+    WIZCHIP_WRITE(PHYRAR,PHYMDIO_regadr);
+    WIZCHIP_WRITE(PHYACR, PHYACR_READ);
+    while(WIZCHIP_READ(PHYACR));  //wait for command complete
+    return ((uint16_t)WIZCHIP_READ(PHYDOR) << 8) | WIZCHIP_READ(PHYDOR+1);
+}
+
+void wiz_delay_ms(uint32_t milliseconds)
+{
+	uint32_t i;
+	for(i = 0 ; i < milliseconds ; i++)
+	{
+		//Write any values to clear the TCNTCLKR register
+		setTCNTCLKR(0xff);
+
+		// Wait until counter register value reaches 10.(10 = 1ms : TCNTR is 100us tick counter register)
+		while(getTCNTR() < 0x0a){}
+	}
+}
+
+#endif
Index: ctrl/firmware/Main/SES/Wiznet/Ethernet/W5100S/w5100s.h
===================================================================
--- ctrl/firmware/Main/SES/Wiznet/Ethernet/W5100S/w5100s.h	(revision 79)
+++ ctrl/firmware/Main/SES/Wiznet/Ethernet/W5100S/w5100s.h	(revision 79)
@@ -0,0 +1,3322 @@
+//* ****************************************************************************
+//! \file w5100S.h
+//! \brief W5100S HAL Header File.
+//! \version 1.0.0
+//! \date 2018/03/29
+//! \par  Revision history
+//!       <2018/03/29> 1st Release
+//! \author Peter
+//! \copyright
+//!
+//! Copyright (c)  2013, WIZnet Co., LTD.
+//! All rights reserved.
+//! 
+//! Redistribution and use in source and binary forms, with or without 
+//! modification, are permitted provided that the following conditions 
+//! are met: 
+//! 
+//!     * Redistributions of source code must retain the above copyright 
+//! notice, this list of conditions and the following disclaimer. 
+//!     * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution. 
+//!     * Neither the name of the <ORGANIZATION> nor the names of its 
+//! contributors may be used to endorse or promote products derived 
+//! from this software without specific prior written permission. 
+//! 
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+
+#ifndef	_W5100S_H_
+#define	_W5100S_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include "wizchip_conf.h"
+
+/// \cond DOXY_APPLY_CODE
+#if   (_WIZCHIP_ == W5100S)
+/// \endcond
+
+#define _WIZCHIP_SN_BASE_  (0x0400)
+#define _WIZCHIP_SN_SIZE_  (0x0100)
+#define _WIZCHIP_IO_TXBUF_ (0x4000) /* Internal Tx buffer address of the iinchip */
+#define _WIZCHIP_IO_RXBUF_ (0x6000) /* Internal Rx buffer address of the iinchip */
+
+
+#define WIZCHIP_CREG_BLOCK      	      0x00   ///< Common register block
+#define WIZCHIP_SREG_BLOCK(N)    	   (_WIZCHIP_SN_BASE_+ _WIZCHIP_SN_SIZE_*N) ///< Socket N register block
+
+#define WIZCHIP_OFFSET_INC(ADDR, N)    (ADDR + N) ///< Increase offset address
+
+#if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_DIR_)
+   #define _W5100S_IO_BASE_     _WIZCHIP_IO_BASE_
+#elif (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_)
+	#define IDM_OR             ((_WIZCHIP_IO_BASE  + 0x0000))
+	#define IDM_AR0            ((_WIZCHIP_IO_BASE_ + 0x0001))
+	#define IDM_AR1            ((_WIZCHIP_IO_BASE_ + 0x0002))
+	#define IDM_DR             ((_WIZCHIP_IO_BASE_ + 0x0003))
+	#define _W5100S_IO_BASE_    0x0000
+#elif (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)
+   #define _W5100S_IO_BASE_    0x0000
+#endif
+
+///////////////////////////////////////
+// Definition For Legacy Chip Driver //
+///////////////////////////////////////
+#define IINCHIP_READ(ADDR)                WIZCHIP_READ(ADDR)               ///< The defined for legacy chip driver
+#define IINCHIP_WRITE(ADDR,VAL)           WIZCHIP_WRITE(ADDR,VAL)          ///< The defined for legacy chip driver
+#define IINCHIP_READ_BUF(ADDR,BUF,LEN)    WIZCHIP_READ_BUF(ADDR,BUF,LEN)   ///< The defined for legacy chip driver
+#define IINCHIP_WRITE_BUF(ADDR,BUF,LEN)   WIZCHIP_WRITE(ADDR,BUF,LEN)      ///< The defined for legacy chip driver
+
+
+//-----------    defgroup --------------------------------
+
+/**
+ * @defgroup W5100S W5100S
+ * @brief WHIZCHIP register defines and I/O functions of @b W5100S.
+ *
+ * - @ref WIZCHIP_register_W5100S: @ref Common_register_group_W5100S and @ref Socket_register_group_W5100S
+ * - @ref WIZCHIP_IO_Functions_W5100S: @ref Basic_IO_function_W5100S, @ref Common_register_access_function_W5100S and @ref Special_function_W5100S
+ */
+
+ /**
+ * @defgroup WIZCHIP_register_W5100S WIZCHIP register
+ * @ingroup W5100S
+ * @brief WIZCHIP register defines register group of <b> W5100S </b>.
+ *
+ * - \ref Common_register_group_W5100S : Common register group W5100S
+ * - \ref Socket_register_group_W5100S : \c SOCKET n register group W5100S
+ */
+
+
+/**
+ * @defgroup WIZCHIP_IO_Functions_W5100S WIZCHIP I/O functions
+ * @ingroup W5100S
+ * @brief This supports the basic I/O functions for \ref WIZCHIP_register_W5100S.
+ *
+ * - <b> Basic I/O function </b> \n
+ *   WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF(), wiz_recv_data(), wiz_recv_ignore(), wiz_send_data() \n\n
+ *
+ * - \ref Common_register_group_W5100S <b>access functions</b> \n
+ * 	-# @b Mode \n
+ *    getMR(), setMR()
+ * 	-# @b Interrupt \n
+ *    getIR(), setIR(), getIMR(), setIMR(),
+ * 	-# <b> Network Information </b> \n
+ *    getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), setSIPR()
+ * 	-# @b Retransmission \n
+ *    getRCR(), setRCR(), getRTR(), setRTR()
+ * 	-# @b PPPoE \n
+ *    getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC()
+ *
+ * - \ref Socket_register_group_W5100S <b>access functions</b> \n
+ *   -# <b> SOCKET control</b> \n
+ *      getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IR(), setSn_IR()
+ *   -# <b> SOCKET information</b> \n
+ *      getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT()
+ *      getSn_MSSR(), setSn_MSSR()
+ *   -# <b> SOCKET communication </b> \n
+ *      getSn_RXMEM_SIZE(), setSn_RXMEM_SIZE(), getSn_TXMEM_SIZE(), setSn_TXMEM_SIZE() \n
+ *      getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n
+ *      getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n
+ *      getSn_TX_FSR(), getSn_RX_RSR()
+ *   -# <b> IP header field </b> \n
+ *      getSn_FRAG(), setSn_FRAG(),  getSn_TOS(), setSn_TOS() \n
+ *      getSn_TTL(), setSn_TTL()
+ */
+
+/**
+ * @defgroup Common_register_group_W5100S Common register
+ * @ingroup WIZCHIP_register_W5100S
+ * @brief Common register group\n
+ * It set the basic for the networking\n
+ * It set the configuration such as interrupt, network information, ICMP, etc.
+ * @details
+ * @sa MR : Mode register.
+ * @sa GAR, SUBR, SHAR, SIPR
+ * @sa IR, Sn_IR, _IMR_  : Interrupt.
+ * @sa _RTR_, _RCR_ : Data retransmission.
+ * @sa PTIMER, PMAGIC : PPPoE.
+ */
+
+
+ /**
+ * @defgroup Socket_register_group_W5100S Socket register
+ * @ingroup WIZCHIP_register_W5100S
+ * @brief Socket register group\n
+ * Socket register configures and control SOCKETn which is necessary to data communication.
+ * @details
+ * @sa Sn_MR, Sn_CR, Sn_IR : SOCKETn Control
+ * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information
+ * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_FRAGR : Internet protocol.
+ * @sa Sn_RXMEM_SIZE, Sn_TXMEM_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, Sn_RX_RD, Sn_RX_WR : Data communication
+ */
+
+ /**
+ * @defgroup Basic_IO_function_W5100S Basic I/O function
+ * @ingroup WIZCHIP_IO_Functions_W5100S
+ * @brief These are basic input/output functions to read values from register or write values to register.
+ */
+
+/**
+ * @defgroup Common_register_access_function_W5100S Common register access functions
+ * @ingroup WIZCHIP_IO_Functions_W5100S
+ * @brief These are functions to access <b>common registers</b>.
+ */
+
+/**
+ * @defgroup Socket_register_access_function_W5100S Socket register access functions
+ * @ingroup WIZCHIP_IO_Functions_W5100S
+ * @brief These are functions to access <b>socket registers</b>.
+ */
+
+ /**
+ * @defgroup Special_function_W5100S Special functions
+ * @ingroup WIZCHIP_IO_Functions_W5100S
+ * @brief These are special functions to access to the PHY
+ */
+
+ //-----------------------------------------------------------------------------------
+
+//----------------------------- W5100S Common Registers IOMAP -----------------------------
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Mode Register address(R/W)\n
+ * \ref MR is used for S/W reset, ping block mode, PPPoE mode and etc.
+ * @details Each bit of \ref MR defined as follows.
+ * <table>
+ * 		<tr>  <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td>   </tr>
+ * 		<tr>  <td>RST</td> <td>Reserved</td> <td>WOL</td> <td>PB</td> <td>PPPoE</td> <td>Reserved</td> <td>AI</td> <td>IND</td> </tr>
+ * </table>
+ * - \ref MR_RST		 	: Reset
+ * - \ref MR_PB         	: Ping block
+ * - \ref MR_PPPOE      	: PPPoE mode
+ * - \ref MR_AI         	: Address Auto-Increment in Indirect Bus Interface
+ * - \ref MR_IND         	: Indirect Bus Interface mode
+ */
+#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_
+   #define MR					(_WIZCHIP_IO_BASE_ + (0x0000))  // Mode
+#else
+   #define MR					(_W5100S_IO_BASE_ + (0x0000))  // Mode
+#endif
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Gateway IP Register address(R/W)
+ * @details \ref GAR configures the default gateway address.
+ */
+#define GAR     			(_W5100S_IO_BASE_ + (0x0001))  // GW Address
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Subnet mask Register address(R/W)
+ * @details \ref SUBR configures the subnet mask address.
+ */
+#define SUBR    			(_W5100S_IO_BASE_ + (0x0005)) // SN Mask Address
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Source MAC Register address(R/W)
+ * @details \ref SHAR configures the source hardware address.
+ */
+#define SHAR    			(_W5100S_IO_BASE_ + (0x0009)) // Source Hardware Address
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Source IP Register address(R/W)
+ * @details \ref SIPR configures the source IP address.
+ */
+#define SIPR    			(_W5100S_IO_BASE_ + (0x000F)) // Source IP Address
+
+// Reserved					(_W5100S_IO_BASE_ + (0x0013))
+// Reserved					(_W5100S_IO_BASE_ + (0x0014))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Interrupt Register(R/W)
+ * @details \ref IR indicates the interrupt status. Each bit of \ref IR will be still until the bit will be written to by the host.
+ * If \ref IR is not equal to x00 INTn PIN is asserted to low until it is x00\n\n
+ * Each bit of \ref IR defined as follows.
+ * <table>
+ * 		<tr>  <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td>   </tr>
+ * 		<tr>  <td>CONFLICT</td> <td>UNREACH</td> <td>PPPoE</td> <td>Reserved</td> <td>S3_INT</td> <td>S2_INT</td> <td>S1_INT</td> <td>S0_INT</td> </tr>
+ * </table>
+ * - \ref IR_CONFLICT : IP conflict
+ * - \ref IR_UNREACH  : Destination unreachable
+ * - \ref IR_PPPoE	 : PPPoE connection close
+ * - \ref IR_SOCK(3)  : SOCKET 3 Interrupt
+ * - \ref IR_SOCK(2)  : SOCKET 2 Interrupt
+ * - \ref IR_SOCK(1)  : SOCKET 1 Interrupt
+ * - \ref IR_SOCK(0)  : SOCKET 0 Interrupt
+ */
+#define IR					(_W5100S_IO_BASE_ + (0x0015)) // Interrupt
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Socket Interrupt Mask Register(R/W)
+ * @details Each bit of \ref _IMR_ corresponds to each bit of \ref IR.
+ * When a bit of \ref _IMR_ is and the corresponding bit of \ref IR is set, Interrupt will be issued.
+ */
+#define _IMR_    			(_W5100S_IO_BASE_ + (0x0016)) // Socket Interrupt Mask
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Timeout register address( 1 is 100us )(R/W)
+ * @details \ref _RTR_ configures the retransmission timeout period. The unit of timeout period is 100us and the default of \ref _RTR_ is x07D0or 000
+ * And so the default timeout period is 200ms(100us X 2000). During the time configured by \ref _RTR_, W5100S waits for the peer response
+ * to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command).
+ * If the peer does not respond within the \ref _RTR_ time, W5100S retransmits the packet or issues timeout.
+ */
+#define _RTR_     			(_W5100S_IO_BASE_ + (0x0017)) // Retry Time
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Retry count register(R/W)
+ * @details \ref _RCR_ configures the number of time of retransmission.
+ * When retransmission occurs as many as ref _RCR_+1 Timeout interrupt is issued (\ref Sn_IR_TIMEOUT = '1').
+ */
+#define _RCR_				(_W5100S_IO_BASE_ + (0x0019)) // Retry Count
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Receive Memory Size Register
+ * @details \ref RMSR register configures RX bufffer Size of the SOCKET
+ * The sum of the RX buffers can not exceed 8kB.
+ * <table>
+ * 		<tr>  <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td>   </tr>
+ * 		<tr>  <td>S3-1</td> <td>S3-0</td> <td>S2-1</td> <td>S2-0</td> <td>S1-1</td> <td>S1-0</td> <td>S0-1</td> <td>S0-0</td> </tr>
+ * </table>
+ * <table>
+ * 		<tr> <td>Memory Size</td><td>Sn-1</td><td>Sn-0</td> </tr>
+ * 		<tr> <td>1KB</td><td>0</td><td>0</td> </tr>
+ * 		<tr> <td>2KB</td><td>0</td><td>1</td> </tr>
+ * 		<tr> <td>4KB</td><td>1</td><td>0</td> </tr>
+ * 		<tr> <td>8KB</td><td>1</td><td>1</td> </tr>
+ * </table>
+ */
+#define RMSR				(_W5100S_IO_BASE_ + (0x001A)) // Receive Memory Size
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Transmit Memory Size Register
+ * @details \ref TMSR register configures TX bufffer Size of the SOCKET
+ * The sum of the TX buffers can not exceed 8kB.
+ * <table>
+ * 		<tr>  <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td>   </tr>
+ * 		<tr>  <td>S3-1</td> <td>S3-0</td> <td>S2-1</td> <td>S2-0</td> <td>S1-1</td> <td>S1-0</td> <td>S0-1</td> <td>S0-0</td> </tr>
+ * </table>
+ * <table>
+ * 		<tr> <td>Memory Size</td><td>Sn-1</td><td>Sn-0</td> </tr>
+ * 		<tr> <td>1KB</td><td>0</td><td>0</td> </tr>
+ * 		<tr> <td>2KB</td><td>0</td><td>1</td> </tr>
+ * 		<tr> <td>4KB</td><td>1</td><td>0</td> </tr>
+ * 		<tr> <td>8KB</td><td>1</td><td>1</td> </tr>
+ * </table>
+ */
+#define TMSR				(_W5100S_IO_BASE_ + (0x001B)) // Transmit Memory Size
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Interrupt register 2
+ * @details \ref IR2 indicates the interrupt status.
+ * Each bit of IR2 will be still until the bit will be written to by the host.
+ * <table>
+ * 		<tr>  <td>7:1</td> <td>0</td>   </tr>
+ * 		<tr>  <td>Reserved</td> <td>WOL</td> </tr>
+ * </table>
+ * - \ref IR2_WOL : WOL MAGIC PACKET Interrupt Mask
+ */
+#define IR2					(_W5100S_IO_BASE_ + (0x0020))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Interrupt mask register 2
+ * @details \ref IMR2 Each bit of IMR2 corresponds to each bit of IR2.
+ * When a bit of IMR2 is and the corresponding bit of IR2 is set, Interrupt will be issued.
+ */
+#define IMR2				(_W5100S_IO_BASE_ + (0x0021))
+
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief PPP LCP Request Timer register  in PPPoE mode(R)
+ * @details \ref PTIMER configures the time for sending LCP echo request. The unit of time is 25ms.
+ */
+#define PTIMER				(_W5100S_IO_BASE_ + (0x0028)) // PPP LCP RequestTimer
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief PPP LCP Magic number register  in PPPoE mode(R)
+ * @details \ref PMAGIC configures the 4bytes magic number to be used in LCP negotiation.
+ */
+#define PMAGIC				(_W5100S_IO_BASE_ + (0x0029)) // PPP LCP Magic number
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Unreachable IP address register
+ * @details \ref
+ */
+#define UIPR				(_W5100S_IO_BASE_ + (0x002A))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Unreachable Port register
+ * @details \ref
+ */
+#define UPORTR				(_W5100S_IO_BASE_  + (0x002E))
+
+/* register for W5100S only */
+
+/*------------------------------------------ Common registers ------------------------------------------*/
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief MR2 Mode register 2
+ * @details \reg
+ */
+#define MR2					(_W5100S_IO_BASE_ + (0x0030))
+
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Destination Hardware address in PPPoE
+ * @details \reg
+ */
+#define PHAR				(_W5100S_IO_BASE_ + (0x0032))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Session ID in PPPoE
+ * @details \reg
+ */
+#define PSIDR				(_W5100S_IO_BASE_ + (0x0038))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Maximum receive Unit in PPPoE
+ * @details \reg
+ */
+#define PMRUR				(_W5100S_IO_BASE_ + (0x003A))
+
+
+/*------------------------------------------ PHY registers ------------------------------------------*/
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief PHY status register
+ * @details \reg
+ */
+#define PHYSR				(_W5100S_IO_BASE_ + (0x003C))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief PHY status register(hidden)
+ * @details \reg
+ */
+#define PHYSR1				(_W5100S_IO_BASE_ + (0x003D))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief PHY Address value
+ * @details \reg
+ */
+#define PHYAR				(_W5100S_IO_BASE_ + (0x003E))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief PHY Register address
+ * @details \reg
+ */
+#define PHYRAR				(_W5100S_IO_BASE_ + (0x003F))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief PHY Data input register
+ * @details \reg
+ */
+#define PHYDIR				(_W5100S_IO_BASE_ + (0x0040))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief PHY data output register
+ * @details \reg
+ */
+#define PHYDOR				(_W5100S_IO_BASE_ + (0x0042))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief PHY Action register
+ * @details \reg
+ */
+#define PHYACR				(_W5100S_IO_BASE_ + (0x0044))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief PHY Division register
+ * @details \reg
+ */
+#define PHYDIVR				(_W5100S_IO_BASE_ + (0x0045))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief PHY Control register 0
+ * @details \reg
+ */
+#define PHYCR0					(_W5100S_IO_BASE_ + (0x0046))
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief PHY Control register 1
+ * @details \reg
+ */
+#define PHYCR1					(_W5100S_IO_BASE_ + (0x0047))
+
+/*------------------------------------------ Socket Less registers ------------------------------------------*/
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Socket-less control register
+ * @details \reg
+ */
+#define SLCR				(_W5100S_IO_BASE_ + (0x004C))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Socket-less retry time register
+ * @details \reg
+ */
+#define SLRTR				(_W5100S_IO_BASE_ + (0x004D))
+
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Socket-less retry count register
+ * @details \reg
+ */
+#define SLRCR				(_W5100S_IO_BASE_ + (0x004F))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Socket-less peer IP address register
+ * @details \reg
+ */
+#define SLPIPR				(_W5100S_IO_BASE_ + (0x0050))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Socket-less peer hardware address register
+ * @details \reg
+ */
+#define SLPHAR				(_W5100S_IO_BASE_ + (0x0054))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Ping sequence number register
+ * @details \reg
+ */
+#define PINGSEQR				(_W5100S_IO_BASE_ + (0x005A))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Ping ID register
+ * @details \reg
+ */
+#define PINGIDR				(_W5100S_IO_BASE_ + (0x005C))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Socket-less interrupt mask register
+ * @details \reg
+ */
+#define SLIMR				(_W5100S_IO_BASE_ + (0x005E))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief  Socket-less interrupt register
+ * @details \reg
+ */
+#define SLIR				(_W5100S_IO_BASE_ + (0x005F))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief DBGOUT(hidden)
+ * @details \reg
+ */
+#define DBGOUT				(_W5100S_IO_BASE_ + (0x0060))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief NICMAXCOLR(hidden)
+ * @details \reg
+ */
+#define NICMAXCOLR			(_W5100S_IO_BASE_ + (0x0063))
+/*------------------------------------------ CFG registers ------------------------------------------*/
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Chip Configuration locking register
+ * @details \reg
+ */
+#define CHIPLCKR				(_W5100S_IO_BASE_ + (0x0070))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Network Configuration locking register
+ * @details \reg
+ */
+#define NETLCKR				(_W5100S_IO_BASE_ + (0x0071))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief PHY Configuration locking register
+ * @details \reg
+ */
+#define PHYLCKR				(_W5100S_IO_BASE_ + (0x0072))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief version register
+ * @details \reg
+ */
+#define VERR				(_W5100S_IO_BASE_ + (0x0080))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Core 100us Counter register
+ * @details \reg
+ */
+#define TCNTR				(_W5100S_IO_BASE_ + (0x0082))
+
+/**
+ * @ingroup Common_register_group_W5100S
+ * @brief Core 100us Counter clear register
+ * @details \reg
+ */
+#define TCNTCLKR			(_W5100S_IO_BASE_ + (0x0088))
+
+//----------------------------- W5100S Socket Registers -----------------------------
+
+//--------------------------- For Backward Compatibility ---------------------------
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief socket Mode register(R/W)
+ * @details \ref Sn_MR configures the option or protocol type of Socket n.\n\n
+ * Each bit of \ref Sn_MR defined as the following.
+ * <table>
+ * 		<tr>  <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td>   </tr>
+ * 		<tr>  <td>MULTI</td> <td>MF</td> <td>ND/MC</td> <td>Reserved</td> <td>Protocol[3]</td> <td>Protocol[2]</td> <td>Protocol[1]</td> <td>Protocol[0]</td> </tr>
+ * </table>
+ * - \ref Sn_MR_MULTI	: Support UDP Multicasting
+ * - \ref Sn_MR_MF	   : Support MACRAW
+ * - \ref Sn_MR_ND		: No Delayed Ack(TCP) flag
+ * - \ref Sn_MR_MC   	: IGMP version used <b>in UDP mulitcasting</b>
+ * - <b>Protocol</b>
+ * <table>
+ * 		<tr>   <td><b>Protocol[3]</b></td> <td><b>Protocol[2]</b></td> <td><b>Protocol[1]</b></td> <td><b>Protocol[0]</b></td> <td>@b Meaning</td>   </tr>
+ * 		<tr>   <td>0</td> <td>0</td> <td>0</td> <td>0</td> <td>Closed</td>   </tr>
+ * 		<tr>   <td>0</td> <td>0</td> <td>0</td> <td>1</td> <td>TCP</td>   </tr>
+ * 		<tr>   <td>0</td> <td>0</td> <td>1</td> <td>0</td> <td>UDP</td>   </tr>
+ * 		<tr>   <td>0</td> <td>1</td> <td>0</td> <td>0</td> <td>MACRAW</td>   </tr>
+ * </table>
+ * - <b>In case of Socket 0</b>
+ *  <table>
+ * 		<tr>   <td><b>Protocol[3]</b></td> <td><b>Protocol[2]</b></td> <td><b>Protocol[1]</b></td> <td><b>Protocol[0]</b></td> <td>@b Meaning</td>   </tr>
+ * 		<tr>   <td>0</td> <td>1</td> <td>0</td> <td>0</td> <td>MACRAW</td>   </tr>
+ * 		<tr>   <td>0</td> <td>1</td> <td>0</td> <td>1</td> <td>PPPoE</td>   </tr>
+ * </table>
+ *	 - \ref Sn_MR_MACRAW	: MAC LAYER RAW SOCK \n
+ *  - \ref Sn_MR_UDP		: UDP
+ *  - \ref Sn_MR_TCP		: TCP
+ *  - \ref Sn_MR_CLOSE	: Unused socket
+ *  @note MACRAW mode should be only used in Socket 0.
+ */
+#define Sn_MR(sn)			(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0000)) // socket Mode register
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Socket command register(R/W)
+ * @details This is used to set the command for Socket n such as OPEN, CLOSE, CONNECT, LISTEN, SEND, and RECEIVE.\n
+ * After W5100S accepts the command, the \ref Sn_CR register is automatically cleared to 0x00.
+ * Even though \ref Sn_CR is cleared to 0x00, the command is still being processed.\n
+ * To check whether the command is completed or not, please check the \ref Sn_IR or \ref Sn_SR.
+ * - \ref Sn_CR_OPEN 		: Initialize or open socket.
+ * - \ref Sn_CR_LISTEN 		: Wait connection request in TCP mode(<b>Server mode</b>)
+ * - \ref Sn_CR_CONNECT 	: Send connection request in TCP mode(<b>Client mode</b>)
+ * - \ref Sn_CR_DISCON 		: Send closing request in TCP mode.
+ * - \ref Sn_CR_CLOSE   	: Close socket.
+ * - \ref Sn_CR_SEND    	: Update TX buffer pointer and send data.
+ * - \ref Sn_CR_SEND_MAC	: Send data with MAC address, so without ARP process.
+ * - \ref Sn_CR_SEND_KEEP 	: Send keep alive message.
+ * - \ref Sn_CR_RECV		: Update RX buffer pointer and receive data.
+ * - <b>In case of S0_MR(P3:P0) = S0_MR_PPPoE</b>
+ *  <table>
+ * 		<tr>   <td><b>Value</b></td> <td><b>Symbol</b></td> <td><b>Description</b></td></tr>
+ * 		<tr>   <td>0x23</td> <td>PCON</td> <td>PPPoE connection begins by transmitting PPPoE discovery packet</td>  </tr>
+ * 		<tr>   <td>0x24</td> <td>PDISCON</td> <td>Closes PPPoE connection</td>  </tr>
+ * 		<tr>   <td>0x25</td> <td>PCR</td> <td>In each phase, it transmits REQ message.</td> </tr>
+ * 		<tr>   <td>0x26</td> <td>PCN</td> <td>In each phase, it transmits NAK message.</td> </tr>
+ * 		<tr>   <td>0x27</td> <td>PCJ</td> <td>In each phase, it transmits REJECT message.</td> </tr>
+ * </table>
+ */
+#define Sn_CR(sn)			(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0001)) // channel Sn_CR register
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Socket interrupt register(R)
+ * @details \ref Sn_IR indicates the status of Socket Interrupt such as establishment, termination, receiving data, timeout).\n
+ * When an interrupt occurs and the corresponding bit \ref IR_SOCK(N) in \ref _IMR_ are set, \ref IR_SOCK(N) in \ref IR becomes '1'.\n
+ * In order to clear the \ref Sn_IR bit, the host should write the bit to \n
+ * <table>
+ * 		<tr>  <td>7</td> <td>6</td> <td>5</td> <td>4</td> <td>3</td> <td>2</td> <td>1</td> <td>0</td>   </tr>
+ * 		<tr>  <td>PRECV</td> <td>PFAIL</td> <td>PNEXT</td> <td>SEND_OK</td> <td>TIMEOUT</td> <td>RECV</td> <td>DISCON</td> <td>CON</td> </tr>
+ * </table>
+ * - \ref Sn_IR_PRECV : <b>PPP Receive Interrupt</b>
+ * - \ref Sn_IR_PFAIL : <b>PPP Fail Interrupt</b>
+ * - \ref Sn_IR_PNEXT : <b>PPP Next Phase Interrupt</b>
+ * - \ref Sn_IR_SENDOK : <b>SEND_OK Interrupt</b>
+ * - \ref Sn_IR_TIMEOUT : <b>TIMEOUT Interrupt</b>
+ * - \ref Sn_IR_RECV : <b>RECV Interrupt</b>
+ * - \ref Sn_IR_DISCON : <b>DISCON Interrupt</b>
+ * - \ref Sn_IR_CON : <b>CON Interrupt</b>
+ */
+#define Sn_IR(sn)			(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0002)) // channel interrupt register
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Socket status register(R)
+ * @details \ref Sn_SR indicates the status of Socket n.\n
+ * The status of Socket n is changed by \ref Sn_CR or some special control packet as SYN, FIN packet in TCP.
+ * @par Normal status
+ * - \ref SOCK_CLOSED 		: Closed
+ * - \ref SOCK_INIT   		: Initiate state
+ * - \ref SOCK_LISTEN    	: Listen state
+ * - \ref SOCK_ESTABLISHED 	: Success to connect
+ * - \ref SOCK_CLOSE_WAIT   : Closing state
+ * - \ref SOCK_UDP   		: UDP socket
+ * - \ref SOCK_MACRAW  		: MAC raw mode socket
+ *@par Temporary status during changing the status of Socket n.
+ * - \ref SOCK_SYNSENT   	: This indicates Socket n sent the connect-request packet (SYN packet) to a peer.
+ * - \ref SOCK_SYNRECV    	: It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.
+ * - \ref SOCK_FIN_WAIT		: Connection state
+ * - \ref SOCK_CLOSING		: Closing state
+ * - \ref SOCK_TIME_WAIT	: Closing state
+ * - \ref SOCK_LAST_ACK 	: Closing state
+ */
+#define Sn_SR(sn)			(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0003)) // channel status register
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief source port register(R/W)
+ * @details \ref Sn_PORT configures the source port number of Socket n.
+ * It is valid when Socket n is used in TCP/UDP mode. It should be set before OPEN command is ordered.
+*/
+#define Sn_PORT(sn)		(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0004)) // source port register
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Peer MAC register address(R/W)
+ * @details \ref Sn_DHAR configures the destination hardware address of Socket n when using SEND_MAC command in UDP mode or
+ * it indicates that it is acquired in ARP-process by CONNECT/SEND command.
+ */
+#define Sn_DHAR(sn)     (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0006)) // Peer MAC register address
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Peer IP register address(R/W)
+ * @details \ref Sn_DIPR configures or indicates the destination IP address of Socket n. It is valid when Socket n is used in TCP/UDP mode.
+ * In TCP client mode, it configures an IP address of TCP server before CONNECT command.
+ * In TCP server mode, it indicates an IP address of TCP client after successfully establishing connection.
+ * In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command.
+ */
+#define Sn_DIPR(sn)		(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x000C)) // Peer IP register address
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Peer port register address(R/W)
+ * @details \ref Sn_DPORT configures or indicates the destination port number of Socket n. It is valid when Socket n is used in TCP/UDP mode.
+ * In TCP clientmode, it configures the listen port number of TCP server before CONNECT command.
+ * In TCP Servermode, it indicates the port number of TCP client after successfully establishing connection.
+ * In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command.
+ */
+#define Sn_DPORT(sn)    (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0010)) // Peer port register address
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W)
+ * @details \ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) of Socket n.
+ */
+#define Sn_MSSR(sn)	   (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0012)) // Maximum Segment Size(Sn_MSSR0) register address
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief IP Protocol(PROTO) Register(R/W)
+ * @details \ref Sn_PROTO that sets the protocol number field of the IP header at the IP layer. It is
+ * valid only in IPRAW mode, and ignored in other modes.
+ */
+#define Sn_PROTO(sn)	   (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0014)) // Protocol of IP Header field register in IP raw mode
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief IP Type of Service(TOS) Register(R/W)
+ * @details \ref Sn_TOS configures the TOS(Type Of Service field in IP Header) of Socket n.
+ * It is set before OPEN command.
+ */
+#define Sn_TOS(sn)			(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + 0x0015) // IP Type of Service(TOS) Register
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief IP Time to live(TTL) Register(R/W)
+ * @details \ref Sn_TTL configures the TTL(Time To Live field in IP header) of Socket n.
+ * It is set before OPEN command.
+ */
+#define Sn_TTL(sn)		(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0016)) // IP Time to live(TTL) Register
+
+// Reserved					(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0017))
+// Reserved					(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0018))
+// Reserved					(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0019))
+// Reserved					(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001A))
+// Reserved					(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001B))
+// Reserved					(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001C))
+// Reserved					(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001D))
+
+
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Receive memory size register(R/W)
+ * @details @ref Sn_RXBUF_SIZE configures the RX buffer block size of Socket n.
+ * Socket n RX Buffer Block size can be configured with 1,2,4 and 8Kbytes.
+ * If a different size is configured, the data cannot be normally received from a peer.
+ * Although Socket n RX Buffer Block size is initially configured to 2Kbytes,
+ * user can re-configure its size using @ref Sn_RXBUF_SIZE. The total sum of @ref Sn_RXBUF_SIZE can not be exceed 8Kbytes.
+ * When exceeded, the data reception error is occurred.
+ */
+#define Sn_RXBUF_SIZE(sn)   (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001E))
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Transmit memory size register(R/W)
+ * @details @ref Sn_TXBUF_SIZE configures the TX buffer block size of Socket n. Socket n TX Buffer Block size can be configured with 1,2,4 and 8Kbytes.
+ * If a different size is configured, the data cannot be normally transmitted to a peer.
+ * Although Socket n TX Buffer Block size is initially configured to 2Kbytes,
+ * user can be re-configure its size using @ref Sn_TXBUF_SIZE. The total sum of @ref Sn_TXBUF_SIZE can not be exceed 8Kbytes.
+ * When exceeded, the data transmission error is occurred.
+ */
+#define Sn_TXBUF_SIZE(sn)   (_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x001F))
+
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Transmit free memory size register(R)
+ * @details \ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. It is initialized to the configured size by \ref Sn_TXMEM_SIZE.
+ * Data bigger than \ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the bigger data overwrites the previous saved data not yet sent.
+ * Therefore, check before saving the data to the Socket n TX Buffer, and if data is equal or smaller than its checked size,
+ * transmit the data with SEND/SEND_MAC command after saving the data in Socket n TX buffer. But, if data is bigger than its checked size,
+ * transmit the data after dividing into the checked size and saving in the Socket n TX buffer.
+ */
+#define Sn_TX_FSR(sn)	(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0020)) // Transmit free memory size register
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Transmit memory read pointer register address(R)
+ * @details \ref Sn_TX_RD is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001), it is re-initialized while connecting with TCP.
+ * After its initialization, it is auto-increased by SEND command.
+ * SEND command transmits the saved data from the current \ref Sn_TX_RD to the \ref Sn_TX_WR in the Socket n TX Buffer.
+ * After transmitting the saved data, the SEND command increases the \ref Sn_TX_RD as same as the \ref Sn_TX_WR.
+ * If its increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs),
+ * then the carry bit is ignored and will automatically update with the lower 16bits value.
+ */
+#define Sn_TX_RD(sn)		(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0022)) // Transmit memory read pointer register address
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Transmit memory write pointer register address(R/W)
+ * @details \ref Sn_TX_WR is initialized by OPEN command. However, if Sn_MR(P[3:0]) is TCP mode(001), it is re-initialized while connecting with TCP.\n
+ * It should be read or be updated like as follows.\n
+ * 1. Read the starting address for saving the transmitting data.\n
+ * 2. Save the transmitting data from the starting address of Socket n TX buffer.\n
+ * 3. After saving the transmitting data, update \ref Sn_TX_WR to the increased value as many as transmitting data size.
+ * If the increment value exceeds the maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs),
+ * then the carry bit is ignored and will automatically update with the lower 16bits value.\n
+ * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command
+ */
+#define Sn_TX_WR(sn)		(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0024)) // Transmit memory write pointer register address
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Received data size register(R)
+ * @details \ref Sn_RX_RSR indicates the data size received and saved in Socket n RX Buffer.
+ * \ref Sn_RX_RSR does not exceed the \ref Sn_RXMEM_SIZE and is calculated as the difference between
+ * Socket n RX Write Pointer (\ref Sn_RX_WR)and Socket n RX Read Pointer (\ref Sn_RX_RD)
+ */
+#define Sn_RX_RSR(sn)	(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0026)) // Received data size register
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Read point of Receive memory(R/W)
+ * @details \ref Sn_RX_RD is initialized by OPEN command. Make sure to be read or updated as follows.\n
+ * 1. Read the starting save address of the received data.\n
+ * 2. Read data from the starting address of Socket n RX Buffer.\n
+ * 3. After reading the received data, Update \ref Sn_RX_RD to the increased value as many as the reading size.
+ * If the increment value exceeds the maximum value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs,
+ * update with the lower 16bits value ignored the carry bit.\n
+ * 4. Order RECV command is for notifying the updated \ref Sn_RX_RD to W5100S.
+ */
+#define Sn_RX_RD(sn)		(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0028)) // Read point of Receive memory
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Write point of Receive memory(R)
+ * @details \ref Sn_RX_WR is initialized by OPEN command and it is auto-increased by the data reception.
+ * If the increased value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs),
+ * then the carry bit is ignored and will automatically update with the lower 16bits value.
+ */
+#define Sn_RX_WR(sn)		(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x002A)) // Write point of Receive memory
+
+
+//todo
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Socket interrupt mask register
+ * @details Register address to configure the interrupt mask of the socket
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b> expect <b>bit 4</b>.
+ *
+ */
+#define Sn_IMR(sn)			(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x002C))
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Socket fragment field register
+ * @details Register to configure the Fragment field of IP Header
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b> expect <b>bit 4</b>.
+ */
+#define Sn_FRAGR(sn)		(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x002D)) // and +1
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Socket Mode register 2
+ * @details Register to set mode 2
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b> expect <b>bit 4</b>.
+ */
+#define Sn_MR2(sn)			(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x002F))
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Socket n Keep Alive Timer Register
+ * @details Register to set the transmission period of keep alive packet.
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b> expect <b>bit 4</b>.
+ */
+#define Sn_KPALVTR(sn)		(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0030))
+
+/** todo delete
+ * @ingroup Socket_register_group_W5100S
+ * @brief Socket n Timer Status Register
+ * @details
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b> expect <b>bit 4</b>.
+ */
+//#define Sn_TSR(sn)			(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0031))
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Socket n Retry Time-value Register
+ * @details Register to set the retry time value
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b> expect <b>bit 4</b>.
+ */
+#define Sn_RTR(sn)			(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0032))
+
+/**
+ * @ingroup Socket_register_group_W5100S
+ * @brief Socket n Retry Count-value Register
+ * @details Register to set the retry count value
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b> expect <b>bit 4</b>.
+ */
+#define Sn_RCR(sn)			(_W5100S_IO_BASE_ + WIZCHIP_SREG_BLOCK(sn) + (0x0034))
+
+
+/*----------------------------- W5100S Register values  -----------------------------*/
+
+/* MODE register values */
+/**
+ * @brief Reset
+ * @details If this bit is  All internal registers will be initialized. It will be automatically cleared as after S/W reset.
+ */
+#define MR_RST				0x80 ///< reset
+
+
+/**
+ * @brief Ping block
+ * @details 0 : Disable Ping block\n
+ * 1 : Enable Ping block\n
+ * If the bit is  it blocks the response to a ping request.
+ */
+#define MR_PB				0x10 ///< ping block
+
+/**
+ * @brief Enable PPPoE
+ * @details 0 : DisablePPPoE mode\n
+ * 1 : EnablePPPoE mode\n
+ * If you use ADSL, this bit should be '1'.
+ */
+#define MR_PPPOE			0x08 ///< enable pppoe
+
+/**
+ * @brief Address Auto-Increment in Indirect Bus Interface
+ * @details 0 : Disable auto-increment \n
+ * 1 : Enable auto-incremente \n
+ * At the Indirect Bus Interface mode, if this bit is set as the address will
+ * be automatically increased by 1 whenever read and write are performed.
+ */
+#define MR_AI				0x02 ///< auto-increment in indirect mode
+
+/**
+ * @brief Indirect Bus Interface mode
+ * @details 0 : Disable Indirect bus Interface mode \n
+ * 1 : Enable Indirect bus Interface mode \n
+ * If this bit is set as Indirect Bus Interface mode is set.
+ */
+#define MR_IND				0x01 ///< enable indirect mode
+
+/* IR register values */
+/**
+ * @brief Check IP conflict.
+ * @details Bit is set as when own source IP address is same with the sender IP address in the received ARP request.
+ */
+#define IR_CONFLICT			0x80 ///< check ip confict
+
+/**
+ * @brief Get the destination unreachable message in UDP sending.
+ * @details When receiving the ICMP (Destination port unreachable) packet, this bit is set as
+ * When this bit is  Destination Information such as IP address and Port number may be checked with the corresponding @ref UIPR & @ref UPORTR.
+ */
+#define IR_UNREACH			0x40 ///< check destination unreachable
+
+/**
+ * @brief Get the PPPoE close message.
+ * @details When PPPoE is disconnected during PPPoE mode, this bit is set.
+ */
+#define IR_PPPoE			0x20 ///< get the PPPoE close message
+
+/**
+ * @brief Socket interrupt bit
+ * @details Indicates whether each socket interrupt has occured.
+ */
+#define IR_SOCK(sn)		(0x01 << sn)	///< check socket interrupt
+
+/**
+ * @brief IP conflict interrupt mask bit
+ * @details If this bit is set, IP conflict interrupt is enabled.
+ */
+#define IMR_CONFLICT		0x80
+
+/**
+ * @brief Destination port unreachable interrupt mask bit
+ * @details If this bit is set, destination port unreachable interrupt is enabled.
+ */
+#define IMR_UNREACH			0x40
+
+/**
+ * @brief PADT/LCPT interrupt mask bit(PPPoE)
+ * @details If this bit is set, PADT/LCPT interrupt is enabled.
+ */
+#define IMR_PPPoE			0x20
+
+/**
+ * @brief Socket interrupt mask bit
+ * @details If this bit is set, each socket interrupt is enabled.
+ */
+#define IMR_SOCK(sn)		(0x01 << sn)
+
+/**
+ * @brief Socket-less command register bit
+ * @details ARP command
+ */
+#define SLCMD_ARP		(1<<1)
+
+/**
+ * @brief Socket-less command register bit
+ * @details ARP command
+ */
+#define SLCMD_PING		(1<<0)
+
+/**
+ * @brief Socket-less command interrupt and interrupt mask register bit
+ * @details Request command time out interrupt and interrupt mask
+ */
+#define SLIR_TIMEOUT		(1<<2)
+
+/**
+* @brief Socket less command interrupt and interrupt mask register bit
+* @details Socket less command ARP interrupt and interrupt mask
+*/
+#define SLIR_ARP (1<<1)
+
+/**
+* @brief Socket less command interrupt and interrupt mask register bit
+* @details Socket less command PING interrupt and interruptmask
+*/
+#define SLIR_PING (1<<0)
+
+
+
+// Sn_MR values
+/* Sn_MR Default values */
+/**
+ * @brief Unused socket
+ * @details This configures the protocol mode of Socket n.
+ */
+#define Sn_MR_CLOSE			0x00 ///< unused socket
+
+/**
+ * @brief TCP
+ * @details This configures the protocol mode of Socket n.
+ */
+#define Sn_MR_TCP			0x01 ///< TCP
+
+/**
+ * @brief UDP
+ * @details This configures the protocol mode of Socket n.
+ */
+#define Sn_MR_UDP       0x02 ///< UDP
+#define Sn_MR_IPRAW     0x03 ///< IP LAYER RAW SOCK
+
+/**
+ * @brief MAC LAYER RAW SOCK
+ * @details This configures the protocol mode of Socket n.
+ * @note MACRAW mode should be only used in Socket 0.
+ */
+#define Sn_MR_MACRAW		0x04 ///< MAC LAYER RAW SOCK
+
+/**
+ * @brief PPPoE
+ * @details This configures the protocol mode of Socket n.
+ * @note PPPoE mode should be only used in Socket 0.
+ */
+#define Sn_MR_PPPoE			0x05 ///< PPPoE
+
+/**
+ * @brief No Delayed Ack(TCP), Multicast flag
+ * @details 0 : Disable No Delayed ACK option\n
+ * 1 : Enable No Delayed ACK option\n
+ * This bit is applied only during TCP mode (P[3:0] = 001).\n
+ * When this bit is  It sends the ACK packet without delay as soon as a Data packet is received from a peer.\n
+ * When this bit is  It sends the ACK packet after waiting for the timeout time configured by \ref _RTR_.
+ */
+#define Sn_MR_ND			0x20 ///< No Delayed Ack(TCP) flag
+
+/**
+ * @brief Support UDP Multicasting
+ * @details 0 : using IGMP version 2\n
+ * 1 : using IGMP version 1\n
+ * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI = '1')
+ * It configures the version for IGMP messages (Join/Leave/Report).
+ */
+#define Sn_MR_MC			Sn_MR_ND ///< Select IGMP version 1(0) or 2(1)
+
+/**
+ * @brief MAC filter enable in @ref Sn_MR_MACRAW mode
+ * @details 0 : disable MAC Filtering\n
+ * 1 : enable MAC Filtering\n
+ * This bit is applied only during MACRAW mode(P[3:0] = 100.\n
+ * When set as  W5100S can only receive broadcasting packet or packet sent to itself.
+ * When this bit is  W5100S can receive all packets on Ethernet.
+ * If user wants to implement Hybrid TCP/IP stack,
+ * it is recommended that this bit is set as for reducing host overhead to process the all received packets.
+ */
+#define Sn_MR_MF			0x40 ///< Use MAC filter
+#define Sn_MR_MFEN      Sn_MR_MF
+
+
+/* Sn_MR Default values */
+/**
+ * @brief Support UDP Multicasting
+ * @details 0 : disable Multicasting\n
+ * 1 : enable Multicasting\n
+ * This bit is applied only during UDP mode(P[3:0] = 010).\n
+ * To use multicasting, \ref Sn_DIPR & \ref Sn_DPORT should be respectively configured with the multicast group IP address & port number
+ * before Socket n is opened by OPEN command of \ref Sn_CR.
+ */
+#define Sn_MR_MULTI			0x80 ///< support multicating
+
+/* Sn_CR values */
+/**
+ * @brief Initialize or open socket
+ * @details Socket n is initialized and opened according to the protocol selected in Sn_MR(P3:P0).
+ * The table below shows the value of \ref Sn_SR corresponding to \ref Sn_MR.\n
+ * <table>
+ *   <tr>  <td>\b Sn_MR (P[3:0])</td> <td>\b Sn_SR</td>            		 </tr>
+ *   <tr>  <td>Sn_MR_CLOSE  (000)</td> <td>--</td>         	   		 </tr>
+ *   <tr>  <td>Sn_MR_TCP  (001)</td> <td>SOCK_INIT (0x13)</td>  		 </tr>
+ *   <tr>  <td>Sn_MR_UDP  (010)</td>  <td>SOCK_UDP (0x22)</td>  		 </tr>
+ *   <tr>  <td>S0_MR_IPRAW  (011)</td>  <td>SOCK_IPRAW (0x32)</td>  </tr>
+ *   <tr>  <td>S0_MR_MACRAW  (100)</td>  <td>SOCK_MACRAW (0x42)</td>  </tr>
+ *   <tr>  <td>S0_MR_PPPoE  (101)</td>  <td>SOCK_PPPoE (0x5F)</td>  </tr>
+ * </table>
+ */
+#define Sn_CR_OPEN			0x01 ///< initialize or open socket
+
+/**
+ * @brief Wait connection request in TCP mode(Server mode)
+ * @details This is valid only in TCP mode (Sn_MR(P3:P0) = \ref Sn_MR_TCP).//
+ * In this mode, Socket n operates as a 'TCP server' and waits for connection-request (SYN packet) from any 'TCP client'.//
+ * The \ref Sn_SR changes the state from SOCK_INIT to SOCKET_LISTEN.//
+ * When a 'TCP client' connection request is successfully established,
+ * the \ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the Sn_IR(0) becomes
+ * But when a 'TCP client' connection request is failed, Sn_IR(3) becomes and the status of \ref Sn_SR changes to SOCK_CLOSED.
+ */
+#define Sn_CR_LISTEN		0x02 ///< wait connection request in tcp mode(Server mode)
+
+/**
+ * @brief Send connection request in TCP mode(Client mode)
+ * @details  To connect, a connect-request (SYN packet) is sent to <b>TCP server</b>configured by \ref Sn_DIPR & Sn_DPORT(destination address & port).
+ * If the connect-request is successful, the \ref Sn_SR is changed to \ref SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n
+ * The connect-request fails in the following three cases.\n
+ * 1. When a @b ARPTO occurs (\ref Sn_IR[3] = '1') because destination hardware address is not acquired through the ARP-process.\n
+ * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) ='1')\n
+ * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, \ref Sn_SR is changed to \ref SOCK_CLOSED.
+ * @note This is valid only in TCP mode and operates when Socket n acts as <b>TCP client</b>
+ */
+#define Sn_CR_CONNECT		0x04 ///< send connection request in tcp mode(Client mode)
+
+/**
+ * @brief Send closing request in TCP mode
+ * @details Regardless of <b>TCP server</b>or <b>TCP client</b> the DISCON command processes the disconnect-process (<b>Active close</b>or <b>Passive close</b>.\n
+ * @par Active close
+ * it transmits disconnect-request(FIN packet) to the connected peer\n
+ * @par Passive close
+ * When FIN packet is received from peer, a FIN packet is replied back to the peer.\n
+ * @details When the disconnect-process is successful (that is, FIN/ACK packet is received successfully), \ref Sn_SR is changed to \ref SOCK_CLOSED.\n
+ * Otherwise, TCPTO occurs (Sn_IR(3)='1') and then \ref Sn_SR is changed to \ref SOCK_CLOSED.
+ * @note Valid only in TCP mode.
+ */
+#define Sn_CR_DISCON		0x08 ///< send closing reqeuset in tcp mode
+
+/**
+ * @brief Close socket
+ * @details Sn_SR is changed to \ref SOCK_CLOSED.
+ */
+#define Sn_CR_CLOSE         0x10
+
+/**
+ * @brief Update TX buffer pointer and send data
+ * @details SEND transmits all the data in the Socket n TX buffer.\n
+ * For more details, please refer to Socket n TX Free Size Register (\ref Sn_TX_FSR), Socket n,
+ * TX Write Pointer Register(\ref Sn_TX_WR), and Socket n TX Read Pointer Register(\ref Sn_TX_RD).
+ */
+#define Sn_CR_SEND          0x20
+
+/**
+ * @brief Send data with MAC address, so without ARP process
+ * @details The basic operation is same as SEND.\n
+ * Normally SEND transmits data after destination hardware address is acquired by the automatic ARP-process(Address Resolution Protocol).\n
+ * But SEND_MAC transmits data without the automatic ARP-process.\n
+ * In this case, the destination hardware address is acquired from \ref Sn_DHAR configured by host, instead of APR-process.
+ * @note Valid only in UDP mode.
+ */
+#define Sn_CR_SEND_MAC      0x21
+
+/**
+ * @brief Send keep alive message
+ * @details It checks the connection status by sending 1byte keep-alive packet.\n
+ * If the peer can not respond to the keep-alive packet during timeout time, the connection is terminated and the timeout interrupt will occur.
+ * @note Valid only in TCP mode.
+ */
+#define Sn_CR_SEND_KEEP     0x22
+
+/**
+ * @brief Update RX buffer pointer and receive data
+ * @details RECV completes the processing of the received data in Socket n RX Buffer by using a RX read pointer register (\ref Sn_RX_RD).\n
+ * For more details, refer to Socket n RX Received Size Register (\ref Sn_RX_RSR), Socket n RX Write Pointer Register (\ref Sn_RX_WR),
+ * and Socket n RX Read Pointer Register (\ref Sn_RX_RD).
+ */
+#define Sn_CR_RECV          0x40
+
+/**
+ * @brief
+ * @details
+ */
+#define Sn_CR_IGMP_JOIN			0x23
+
+/**
+ * @brief
+ * @details
+ */
+#define Sn_CR_IGMP_LEAVE		0x24
+
+
+/* Sn_IR values */
+
+/**
+ * @brief SEND_OK Interrupt
+ * @details This is issued when SEND command is completed.
+ */
+#define Sn_IR_SENDOK		0x10 ///< complete sending
+
+/**
+ * @brief TIMEOUT Interrupt
+ * @details This is issued when ARPTO or TCPTO occurs.
+ */
+#define Sn_IR_TIMEOUT		0x08 ///< assert timeout
+
+/**
+ * @brief RECV Interrupt
+ * @details This is issued whenever data is received from a peer.
+ */
+#define Sn_IR_RECV          0x04
+
+/**
+ * @brief DISCON Interrupt
+ * @details This is issued when FIN or FIN/ACK packet is received from a peer.
+ */
+#define Sn_IR_DISCON        0x02
+
+/**
+ * @brief CON Interrupt
+ * @details This is issued one time when the connection with peer is successful and then \ref Sn_SR is changed to \ref SOCK_ESTABLISHED.
+ */
+#define Sn_IR_CON           0x01
+
+/* Sn_SR values */
+/**
+ * @brief Closed
+ * @details This indicates that Socket n is released.\n
+ * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to \ref SOCK_CLOSED regardless of previous status.
+ */
+#define SOCK_CLOSED			0x00 ///< closed
+
+/**
+ * @brief Initiate state
+ * @details This indicates Socket n is opened with TCP mode.\n
+ * It is changed to \ref SOCK_INIT when Sn_MR(P[3:0]) = 001)and OPEN command is ordered.\n
+ * After \ref SOCK_INIT, user can use LISTEN /CONNECT command.
+ */
+#define SOCK_INIT 			0x13 ///< init state
+
+/**
+ * @brief Listen state
+ * @details This indicates Socket n is operating as <b>TCP server</b>mode and waiting for connection-request (SYN packet) from a peer (<b>TCP client</b>).\n
+ * It will change to \ref SOCK_ESTABLISHED when the connection-request is successfully accepted.\n
+ * Otherwise it will change to \ref SOCK_CLOSED after TCPTO occurred (Sn_IR(TIMEOUT) = '1').
+ */
+#define SOCK_LISTEN         0x14
+
+/**
+ * @brief Connection state
+ * @details This indicates Socket n sent the connect-request packet (SYN packet) to a peer.\n
+ * It is temporarily shown when \ref Sn_SR is changed from \ref SOCK_INIT to \ref SOCK_ESTABLISHED by CONNECT command.\n
+ * If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to \ref SOCK_ESTABLISHED.\n
+ * Otherwise, it changes to \ref SOCK_CLOSED after TCPTO (\ref Sn_IR[TIMEOUT] = '1') is occurred.
+ */
+#define SOCK_SYNSENT        0x15
+
+/**
+ * @brief Connection state
+ * @details It indicates Socket n successfully received the connect-request packet (SYN packet) from a peer.\n
+ * If socket n sends the response (SYN/ACK  packet) to the peer successfully,  it changes to \ref SOCK_ESTABLISHED. \n
+ * If not, it changes to \ref SOCK_CLOSED after timeout occurs (\ref Sn_IR[TIMEOUT] = '1').
+ */
+#define SOCK_SYNRECV        0x16
+
+/**
+ * @brief Success to connect
+ * @details This indicates the status of the connection of Socket n.\n
+ * It changes to \ref SOCK_ESTABLISHED when the <b>TCP SERVER</b>processed the SYN packet from the <b>TCP CLIENT</b>during \ref SOCK_LISTEN, or
+ * when the CONNECT command is successful.\n
+ * During \ref SOCK_ESTABLISHED, DATA packet can be transferred using SEND or RECV command.
+ */
+#define SOCK_ESTABLISHED    0x17
+
+/**
+ * @brief Closing state
+ * @details These indicate Socket n is closing.\n
+ * These are shown in disconnect-process such as active-close and passive-close.\n
+ * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED.
+ */
+#define SOCK_FIN_WAIT       0x18
+
+/**
+ * @brief Closing state
+ * @details These indicate Socket n is closing.\n
+ * These are shown in disconnect-process such as active-close and passive-close.\n
+ * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED.
+ */
+#define SOCK_CLOSING        0x1A
+
+/**
+ * @brief Closing state
+ * @details These indicate Socket n is closing.\n
+ * These are shown in disconnect-process such as active-close and passive-close.\n
+ * When Disconnect-process is successfully completed, or when timeout occurs, these change to \ref SOCK_CLOSED.
+ */
+#define SOCK_TIME_WAIT      0x1B
+
+/**
+ * @brief Closing state
+ * @details This indicates Socket n received the disconnect-request (FIN packet) from the connected peer.\n
+ * This is half-closing status, and data can be transferred.\n
+ * For full-closing, DISCON command is used. But For just-closing, @ref Sn_CR_CLOSE command is used.
+ */
+#define SOCK_CLOSE_WAIT     0x1C
+
+/**
+ * @brief Closing state
+ * @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n
+ * It changes to \ref SOCK_CLOSED when Socket n received the response successfully, or when timeout occurs  (\ref Sn_IR[TIMEOUT] = '1').
+ */
+#define SOCK_LAST_ACK       0x1D
+
+/**
+ * @brief UDP socket
+ * @details This indicates Socket n is opened in UDP mode(Sn_MR(P[3:0]) = 010).\n
+ * It changes to SOCK_UDP when Sn_MR(P[3:0]) = 010 and @ref Sn_CR_OPEN command is ordered.\n
+ * Unlike TCP mode, data can be transfered without the connection-process.
+ */
+#define SOCK_UDP			0x22 ///< udp socket
+
+/**
+ * @brief IP raw mode socket
+ * @details TThe socket is opened in IPRAW mode. The SOCKET status is change to SOCK_IPRAW when @ref Sn_MR (P3:P0) is
+ * Sn_MR_IPRAW and @ref Sn_CR_OPEN command is used.\n
+ * IP Packet can be transferred without a connection similar to the UDP mode.
+*/
+#define SOCK_IPRAW			0x32 ///< ip raw mode socket
+
+/**
+ * @brief MAC raw mode socket
+ * @details This indicates Socket 0 is opened in MACRAW mode (@ref Sn_MR(P[3:0]) = '100' and n=0) and is valid only in Socket 0.\n
+ * It changes to SOCK_MACRAW when @ref Sn_MR(P[3:0]) = '100' and @ref Sn_CR_OPEN command is ordered.\n
+ * Like UDP mode socket, MACRAW mode Socket 0 can transfer a MAC packet (Ethernet frame) without the connection-process.
+ */
+#define SOCK_MACRAW			0x42 ///< mac raw mode socket
+
+/**
+ * @brief PPPoE mode socket
+ * @details It is the status that SOCKET0 is open as PPPoE mode. It is changed to SOCK_PPPoE in case of S0_CR=OPEN and S0_MR
+ * (P3:P0)=S0_MR_PPPoE.\n
+ * It is temporarily used at the PPPoE
+connection.
+ */
+#define SOCK_PPPOE			0x5F ///< pppoe socket
+
+// IP PROTOCOL
+#define IPPROTO_IP			0 ///< Dummy for IP
+#define IPPROTO_ICMP		   1 ///< Control message protocol
+#define IPPROTO_IGMP		   2 ///< Internet group management protocol
+#define IPPROTO_GGP			3 ///< GW^2 (deprecated)
+#define IPPROTO_TCP			6 ///< TCP
+#define IPPROTO_PUP			12 ///< PUP
+#define IPPROTO_UDP			17 ///< UDP
+#define IPPROTO_IDP			22 ///< XNS idp
+#define IPPROTO_ND			77 ///< UNOFFICIAL net disk protocol
+#define IPPROTO_RAW			255 ///< Raw IP packet
+
+
+
+/*----------------------------- W5100S !!Only!! Register values  -----------------------------*/
+
+//todo
+/* MODE2 register values */
+
+/**
+ * @brief	Clock select bit
+ * @details	With this bit, system clock can be selected to be 25Mhz or 100Mhz
+ * 1: 25Mhz
+ * 0: 100Mhz (default)
+ */
+#define MR2_CLKSEL				(1<<7)
+
+/**
+ * @brief	Interrupt pin enable bit
+ * @details	This bit enables interrupt.
+ * 1: Enable interrupt
+ * 0: Disable interrupt
+ */
+#define MR2_G_IEN				(1<<6)
+
+
+/**
+ * @brief	No TCP Reset Packet send
+ * @details This bit prevents sending reset packet.
+ * 1: Block TCP reset packet send
+ * 0: TCP Reset packet send
+ */
+#define MR2_NOTCPRST			(1<<5)
+
+/**
+ * @brief	Unreachable Packet Send Block bit
+ * @details	This bit prevents sending Destination Port Unreachable Packet.
+ * 1: Block Destination Port Unreachable Packet Send
+ * 0: Destination Port Unreachable Packet Send
+ */
+#define MR2_UDPURB				(1<<4)
+
+/**
+ * @brief Wake On LAN
+ * @details This bit enables WOL packet to be received.
+ * 1: WOL packet can be received.
+ * 0: WOL packet cannot be received.
+ */
+#define MR2_WOL					(1<<3)
+
+/**todo
+ * @brief MACRAW No Size Check
+ * @details
+ */
+#define MR2_MNOSCHK				(1<<2)
+
+/**
+ * @brief	UDP force ARP
+ * @details This bit can enables to force ARP for each send command.
+ * 1: UDP Force ARP Enable
+ * 0: UDP Force ARP Disable.
+ *
+ */
+#define MR2_UDPFARP				(1<<1)
+
+/**todo
+ * @brief	Skip SRC Hardware Address
+ * @details	This bit can enables to receive without checking the hardware address of the peer.
+ * 1:
+ */
+#define MR2_SSRCHA				(1<<0)
+
+
+
+/* Common interrupt register 2 values */
+
+/**todo
+ * @brief magic packet
+ * @details
+ */
+#define IR2_MGC				(1<<1)
+
+/**todo
+ * @brief Magic packet interrupt mask bit
+ * @details If this bit is set, each socket interrupt is enabled.
+ */
+#define IMR2_MGC			(1<<1)
+
+/**todo
+ * @brief
+ * @details
+ */
+//#define IR2_MGD				(1<<1) /* Reserved */
+
+
+/* PHY status register 0 values */
+
+/**todo
+ * @brief Ethernet CABLE OFF Signal
+ * @details
+ */
+#define PHYSR_CABOFF				(1<<7)
+
+/**todo
+ * @brief
+ * @details
+ */
+#define PHYSR_MD2				(1<<5)
+
+/**todo
+ * @brief
+ * @details
+ */
+#define PHYSR_MD1				(1<<4)
+
+/**todo
+ * @brief
+ * @details
+ */
+#define PHYSR_MD0				(1<<3)
+
+/**todo
+ * @brief
+ * @details
+ */
+#define PHYSR_DUP				(1<<2)
+
+/**todo
+ * @brief
+ * @details
+ */
+#define PHYSR_SPD				(1<<1)
+
+/**todo
+ * @brief LINKDONE register
+ * @details If 1 Linked successfully, if 0 no link
+ */
+#define PHYSR_LNK				(1<<0)
+
+
+/* PHY status register 10 values */
+
+/**
+ * @brieftodo
+ * @details
+ */
+#define PHYSR1_RXPG				(1<<2)
+
+/**
+ * @brieftodo
+ * @details
+ */
+#define PHYSR1_LPI				(1<<1)
+
+/**
+ * @brieftodo
+ * @details
+ */
+#define PHYSR1_CLDN				(1<<0)
+
+#define PHYCR_AUTONEGO_ENABLE	(0<<2)
+#define PHYCR_AUTONEGO_DISABLE	(1<<2)
+
+#define PHYCR_SPD_10			(1<<1)
+#define PHYCR_SPD_100			(0<<1)
+
+#define PHYCR_HALF_DUP			(1<<0)
+#define PHYCR_FULL_DUP			(0<<0)
+
+#define PHYCR1_RST				(0<<0)
+
+#define	PHYCR1_PWDN_ENABLE		(1<<5)
+#define	PHYCR1_PWDN_DISABLE		(0<<5)
+
+
+/* Socket n MODE register 2 values */
+
+/**
+ * @brief Broadcast Blocking bit in MACRAW mode
+ * @details In MACRAW mode, this bit is set to ????to block the broadcast packet.
+ */
+#define Sn_MR2_MBBLK  			(1<<6)
+
+/**
+ * @brief Multicast Blocking bit in MACRAW mode
+ * @details In MACRAW mode, this bit is set to ????to block the multicast packet.
+ */
+#define Sn_MR2_MMBLK  			(1<<5)
+
+/**
+ * @brief IPv6 packet Blocking bit in MACRAW mode
+ * @details In MACRAW mode, this bit is set to ????to block the IPv6 packet.
+ */
+#define Sn_MR2_IPV6BLK  		(1<<4)
+
+
+/**
+ * @brief Broadcast Blocking bit in UDP mode
+ * @details In UDP mode, this bit is set to ????to block the broadcast packet.
+ */
+#define Sn_MR2_UBBLK			(1<<1)
+
+
+/**
+ * @brief TCP Force PSH bit
+ * @details When the SOCKET transmits data in TCP mode, PSH Flag is set to all packets.
+ */
+#define Sn_MR2_FPSH			Sn_MR2_UBBLK
+
+/**
+ * @brief Unicast Blocking bit in UDP mode
+ * @details In UDP mode, this bit is set to ????to block the Unicast packet.
+ */
+#define Sn_MR2_UUBLK			(1<<0)
+
+/*----------------------------For PHY Control-------------------------------*/
+
+/********************/
+/* Register Address */
+/********************/
+
+//Basic mode control register, basic register
+#define PHYMDIO_BMCR				0x00
+
+//Basic mode status register, basic register
+#define PHYMDIO_BMSR				0x01
+
+//--------------------------------------Not used-------------------------------------------//
+////PHY identifier register 1, extended register
+//#define PHY_IDR1				0x02	//not used
+//
+////PHY identifier register 2, extended register
+//#define PHY_IDR2				0x03	//not used
+//
+////Auto-negotiation advertisement register, extended register
+//#define PHY_ANAR				0x04	//not used
+//
+////Auto-negotiation link partner ability register, extended register
+//#define PHY_ANLPAR				0x05	//not used
+//
+////Auto-negotiation expansion register, extended register
+//#define PHY_ANER				0x06	//not used
+//
+////Auto-negotiation next page transmit
+//#define PHY_ANNP				0x07	//not used
+//
+////Auto-negotiation link partner of the next page receive
+//#define PHY_ANLPNP				0x08	//not used
+//
+////MMD access control register
+//#define PHY_REGCR				0x09	//not used
+//
+////MMD access address data register
+//#define PHY_ADDAR				0x0e	//not used
+//--------------------------------------Not used-------------------------------------------//
+
+/********************/
+/* Bit definitions  */
+/********************/
+
+//For BMCR register
+#define BMCR_RESET				(1<<15)
+#define BMCR_MLOOPBACK			(1<<14)
+#define BMCR_SPEED				(1<<13)
+#define BMCR_AUTONEGO			(1<<12)
+#define BMCR_PWDN				(1<<11)
+#define BMCR_ISOLATE			(1<<10)
+#define BMCR_RSTNEGO			(1<<9)
+#define BMCR_DUP				(1<<8)
+#define BMCR_COLTEST			(1<<7)
+
+//For BMSR register
+#define BMSR_AUTONEGO_COMPL		(1<<5)
+#define BMSR_REMOTE_FAULT		(1<<4)
+#define BMSR_LINK_STATUS		(1<<2)
+#define BMSR_JAB_DETECT			(1<<1)
+#define EXTENDED_CAPA			(1<<0)
+
+//--------------------------------------Not used-------------------------------------------//
+////For ANAR register
+//#define ANAR_NP					(1<<15)
+//#define ANAR_ACK				(1<<14)
+//#define ANAR_RF					(1<<13)
+//#define ANAR_ASM				(3<<10)
+//#define ANAR_T4					(1<<9)
+//#define ANAR_TX_FD				(1<<8)
+//#define ANAR_TX_HD				(1<<7)
+//#define ANAR_10_FD				(1<<6)
+//#define ANAR_10_HD				(1<<5)
+//#define ANAR_SELECTOR			(0x1F<<0)
+//
+////For ANAR register
+//#define ANLPAR_NP				(1<<15)
+//#define ANLPAR_ACK				(1<<14)
+//#define ANLPAR_RF				(1<<13)
+//#define ANLPAR_LP_DIR			(1<<11)
+//#define ANLPAR_PAUSE			(1<<10)
+//#define ANLPAR_T4				(1<<9)
+//#define ANLPAR_TX_FD			(1<<8)
+//#define ANLPAR_TX_HD			(1<<7)
+//#define ANLPAR_10_FD			(1<<6)
+//#define ANLPAR_10_HD			(1<<5)
+//#define ANLPAR_SELECTOR			(0x1F<<0)
+
+/**/
+/* MDIO register*/
+//PCS_CTL_1			|		PCS control 1 register
+//PCS_STS_1			|		PCS status 1 register
+//EEE_ABILITY  		|		EEE capability register
+//WAKE_ER_CNTR		|		EEE wake error counter
+//EEE_ADVR 			|		EEE Advertisement register
+//EEE_LPAR 			|		EEE link partner ability register
+
+//--------------------------------------Not used-------------------------------------------//
+
+/********************/
+/*Functions for PHY */
+/********************/
+//todo move this definition to bit area
+#define PHYACR_READ			0x02
+#define PHYACR_WRITE		0x01
+
+
+
+
+/**
+ * @brief Enter a critical section
+ *
+ * @details It is provided to protect your shared code which are executed without distribution. \n \n
+ *
+ * In non-OS environment, It can be just implemented by disabling whole interrupt.\n
+ * In OS environment, You can replace it to critical section api supported by OS.
+ *
+ * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF()
+ * \sa WIZCHIP_CRITICAL_EXIT()
+ */
+#define WIZCHIP_CRITICAL_ENTER()    WIZCHIP.CRIS._enter()
+
+#ifdef _exit
+#undef _exit
+#endif
+
+/**
+ * @brief Exit a critical section
+ *
+ * @details It is provided to protect your shared code which are executed without distribution. \n\n
+ *
+ * In non-OS environment, It can be just implemented by disabling whole interrupt. \n
+ * In OS environment, You can replace it to critical section api supported by OS.
+ *
+ * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF()
+ * @sa WIZCHIP_CRITICAL_ENTER()
+ */
+#define WIZCHIP_CRITICAL_EXIT()     WIZCHIP.CRIS._exit()
+
+
+
+////////////////////////
+// Basic I/O Function //
+////////////////////////
+//
+//M20150601 :  uint16_t AddrSel --> uint32_t AddrSel
+//
+/**
+ * @ingroup Basic_IO_function_W5100S 
+ * @brief It reads 1 byte value from a register.
+ * @param AddrSel Register address
+ * @return The value of register
+ */
+uint8_t  WIZCHIP_READ (uint32_t AddrSel);
+
+/**
+ * @ingroup Basic_IO_function_W5100S
+ * @brief It writes 1 byte value to a register.
+ * @param AddrSel Register address
+ * @param wb Write data
+ * @return void
+ */
+void     WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb );
+
+/**
+ * @ingroup Basic_IO_function_W5100S
+ * @brief It reads sequence data from registers.
+ * @param AddrSel Register address
+ * @param pBuf Pointer buffer to read data
+ * @param len Data length
+ */
+void     WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
+
+/**
+ * @ingroup Basic_IO_function_W5100S
+ * @brief It writes sequence data to registers.
+ * @param AddrSel Register address
+ * @param pBuf Pointer buffer to write data
+ * @param len Data length
+ */
+void     WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
+
+
+/////////////////////////////////
+// Common Register IO function //
+/////////////////////////////////
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set Mode Register
+ * @param (uint8_t)mr The value to be set.
+ * @sa getMR()
+ */
+#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)
+   #define setMR(mr) 	WIZCHIP_WRITE(MR,mr)
+#else
+   #define setMR(mr)    (*((uint8_t*)MR) = mr)
+#endif
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get @ref MR.
+ * @return uint8_t. The value of Mode register.
+ * @sa setMR()
+ */
+#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_)
+   #define getMR() 		WIZCHIP_READ(MR)
+#else
+   #define getMR()      (*(uint8_t*)MR)
+#endif
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set @ref GAR.
+ * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be allocated 4 bytes.
+ * @sa getGAR()
+ */
+#define setGAR(gar) \
+		WIZCHIP_WRITE_BUF(GAR,gar,4)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get @ref GAR.
+ * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be allocated 4 bytes.
+ * @sa setGAR()
+ */
+#define getGAR(gar) \
+		WIZCHIP_READ_BUF(GAR,gar,4)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set @ref SUBR.
+ * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should be allocated 4 bytes.
+ * @note If subr is null pointer, set the backup subnet to SUBR. \n
+ *       If subr is 0.0.0.0, back up SUBR and clear it. \n
+ *       Otherwize, set subr to SUBR
+ * @sa getSUBR()
+ */
+#define setSUBR(subr) \
+      WIZCHIP_WRITE_BUF(SUBR,subr,4)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get @ref SUBR.
+ * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should be allocated 4 bytes.
+ * @sa setSUBR()
+ */
+#define getSUBR(subr) \
+		WIZCHIP_READ_BUF(SUBR, subr, 4)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set @ref SHAR.
+ * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be allocated 6 bytes.
+ * @sa getSHAR()
+ */
+#define setSHAR(shar) \
+		WIZCHIP_WRITE_BUF(SHAR, shar, 6)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get @ref SHAR.
+ * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be allocated 6 bytes.
+ * @sa setSHAR()
+ */
+#define getSHAR(shar) \
+		WIZCHIP_READ_BUF(SHAR, shar, 6)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set @ref SIPR.
+ * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be allocated 4 bytes.
+ * @sa getSIPR()
+*/
+#define setSIPR(sipr) \
+		WIZCHIP_WRITE_BUF(SIPR, sipr, 4)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get @ref SIPR.
+ * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be allocated 4 bytes.
+ * @sa setSIPR()
+ */
+#define getSIPR(sipr) \
+		WIZCHIP_READ_BUF(SIPR, sipr, 4)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref IR register
+ * @param (uint8_t)ir Value to set \ref IR register.
+ * @sa getIR()
+ */
+#define setIR(ir) \
+		WIZCHIP_WRITE(IR, (ir & 0xE0)) //peter 2016.11.07 unreachable interrupt bit added
+		//WIZCHIP_WRITE(IR, (ir & 0xA0))
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref IR register
+ * @return uint8_t. Value of \ref IR register.
+ * @sa setIR()
+ */
+#define getIR() \
+		WIZCHIP_READ(IR)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref _IMR_ register
+ * @param (uint8_t)imr Value to set @ref _IMR_ register.
+ * @sa getIMR()
+ */
+#define setIMR(imr) \
+		WIZCHIP_WRITE(_IMR_, imr)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref _IMR_ register
+ * @return uint8_t. Value of @ref _IMR_ register.
+ * @sa setIMR()
+ */
+#define getIMR() \
+		WIZCHIP_READ(_IMR_)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref _RTR_ register
+ * @param (uint16_t)rtr Value to set @ref _RTR_ register.
+ * @sa getRTR()
+ */
+#define setRTR(rtr)   {\
+		WIZCHIP_WRITE(_RTR_,   (uint8_t)(rtr >> 8)); \
+		WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_RTR_,1), (uint8_t) rtr); \
+	}
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref _RTR_ register
+ * @return uint16_t. Value of @ref _RTR_ register.
+ * @sa setRTR()
+ */
+#define getRTR() \
+		(((uint16_t)WIZCHIP_READ(_RTR_) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1)))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref _RCR_ register
+ * @param (uint8_t)rcr Value to set @ref _RCR_ register.
+ * @sa getRCR()
+ */
+#define setRCR(rcr) \
+		WIZCHIP_WRITE(_RCR_, rcr)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref _RCR_ register
+ * @return uint8_t. Value of @ref _RCR_ register.
+ * @sa setRCR()
+ */
+#define getRCR() \
+		WIZCHIP_READ(_RCR_)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref RMSR register
+ * @sa getRMSR()
+ */
+#define setRMSR(rmsr)   \
+      WIZCHIP_WRITE(RMSR,rmsr) // Receicve Memory Size
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref RMSR register
+ * @return uint8_t. Value of @ref RMSR register.
+ * @sa setRMSR()
+ */
+ #define getRMSR()   \
+      WIZCHIP_READ(RMSR) // Receicve Memory Size
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref TMSR register
+ * @sa getTMSR()
+ */
+#define setTMSR(tmsr)   \
+      WIZCHIP_WRITE(TMSR,tmsr) // Receicve Memory Size
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref TMSR register
+ * @return uint8_t. Value of @ref TMSR register.
+ * @sa setTMSR()
+ */
+#define getTMSR()	\
+	WIZCHIP_READ(TMSR)
+
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PATR register
+ * @return uint16_t. Value to set \ref PATR register
+ */
+#define getPATR() \
+		(((uint16_t)WIZCHIP_READ(PATR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PATR,1)))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PPPALGO register
+ * @return uint8_t. Value to set \ref PPPALGO register
+ */
+#define getPPPALGO() \
+		WIZCHIP_READ(PPPALGO)
+
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PTIMER register
+ * @param (uint8_t)ptimer Value to set \ref PTIMER register.
+ * @sa getPTIMER()
+ */
+#define setPTIMER(ptimer) \
+		WIZCHIP_WRITE(PTIMER, ptimer)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PTIMER register
+ * @return uint8_t. Value of @ref PTIMER register.
+ * @sa setPTIMER()
+ */
+#define getPTIMER() \
+		WIZCHIP_READ(PTIMER)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PMAGIC register
+ * @param (uint8_t)pmagic Value to set @ref PMAGIC register.
+ * @sa getPMAGIC()
+ */
+#define setPMAGIC(pmagic) \
+		WIZCHIP_WRITE(PMAGIC, pmagic)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PMAGIC register
+ * @return uint8_t. Value of @ref PMAGIC register.
+ * @sa setPMAGIC()
+ */
+#define getPMAGIC() \
+		WIZCHIP_READ(PMAGIC)
+
+
+//todo Functions for W5100S
+
+/*----------------------------------------------------------------------*/
+/*								W5100S only								*/
+/*----------------------------------------------------------------------*/
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref IR2 register
+ * @param (uint8_t)ir2 Value to set @ref IR2 register.
+ * @sa getIR2()
+ */
+#define setIR2(ir2) \
+		WIZCHIP_WRITE(IR2, ir2)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref IR2 register
+ * @return uint8_t. Value of @ref IR2 register.
+ * @sa setIR2()
+ */
+#define getIR2() \
+		WIZCHIP_READ(IR2)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref IMR2 register
+ * @param (uint8_t)imr2 Value to set @ref IMR2 register.
+ * @sa setIMR2()
+ */
+#define setIMR2(imr2) \
+		WIZCHIP_WRITE(IMR2,imr2)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref IMR2 register
+ * @return uint8_t. Value of @ref IMR2 register.
+ * @sa getIMR2()
+ */
+#define getIMR2() \
+		WIZCHIP_READ(IMR2)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref UIPR(Unreachable IP Address Register) registers
+ * @param (uint8_t*)uipr Value to set @ref UIPR registers.
+ * @sa setUIPR()
+ */
+#define setUIPR(uipr) \
+		WIZCHIP_WRITE_BUF(UIPR,uipr,4)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref UIPR(Unreachable IP Address Register) registers
+ * @param (uint8_t*)uipr Value to get @ref UIPR registers
+ * @sa setUIPR()
+ */
+#define getUIPR(uipr) \
+		WIZCHIP_READ_BUF(UIPR,uipr,4)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref UPORTR(Unreachable Port Address Register) register
+ * @param (uint16_t)uportr Value to set @ref UPORTR register.
+ * @sa getUPORTR()
+ */
+#define	setUPORTR(uportr) {\
+		WIZCHIP_WRITE(UPORTR, (uint8_t)(uportr >> 8)); \
+		WIZCHIP_WRITE(UPORTR+1, (uint8_t) uportr); \
+	}
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref UPORTR(Unreachable Port Address Register) register
+ * @return uint16_t. Value of @ref UPORTR register.
+ * @sa setUPORTR()
+ */
+#define getUPORTR() \
+		(((uint16_t)WIZCHIP_READ(UPORTR) << 8) + WIZCHIP_READ(UPORTR+1))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref MR2 register
+ * @param (uint8_t)mr2 Value to set @ref MR2 registers.
+ * @sa getMR2()
+ */
+#define setMR2(mr2) \
+		WIZCHIP_WRITE(MR2,mr2)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref MR2 register
+ * @return uint8_t. Value of @ref MR2 register.
+ * @sa setMR2()
+ */
+#define getMR2() \
+		WIZCHIP_READ(MR2)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PHAR registers
+ * @param (uint8_t*)phar Value to set @ref PHAR registers.
+ * @sa getPHAR()
+ */
+#define setPHAR(phar) \
+		WIZCHIP_WRITE_BUF(PHAR,phar,6)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PHAR registers
+ * @param (uint8_t*)phar Pointer variable to get @ref PHAR registers.
+ * @sa setPHAR()
+ */
+#define getPHAR(phar) \
+		WIZCHIP_READ_BUF(PHAR,phar,6)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PSIDR register
+ * @param (uint16_t)psidr Value to set @ref PSIDR register.
+ * @sa getPSIDR()
+ */
+#define setPSIDR(psidr) {\
+		WIZCHIP_WRITE(PSIDR, (uint8_t)(psidr >> 8)); \
+		WIZCHIP_WRITE(PSIDR+1, (uint8_t) psidr); \
+	}
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PSIDR register
+ * @return uint16_t. Value of @ref PSIDR register.
+ * @sa setPSIDR()
+ */
+#define getPSIDR() \
+		(((uint16_t)WIZCHIP_READ(PSIDR) << 8) + WIZCHIP_READ(PSIDR+1))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PMRUR register
+ * @param (uint16_t)pmrur Value to set @ref PMRUR register.
+ * @sa getPMRUR()
+ */
+#define setPMRUR(pmrur) {\
+		WIZCHIP_WRITE(PMRUR, (uint8_t)(pmrur >> 8)); \
+		WIZCHIP_WRITE(PMRUR+1, (uint8_t) pmrur); \
+	}
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PMRUR register
+ * @return uint16_t. Value of @ref PMRUR register.
+ * @sa setPMRUR()
+ */
+#define getPMRUR() \
+		(((uint16_t)WIZCHIP_READ(PMRUR) << 8) + WIZCHIP_READ(PMRUR+1))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PHYSR register
+ * @return uint8_t. Value of @ref PHYSR register.
+ * @sa setPHYSR()
+ */
+#define getPHYSR()	\
+		WIZCHIP_READ(PHYSR)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PHYSR1 register
+ * @return uint8_t. Value of @ref PHYSR1 register.
+ * @sa setPHYSR1()
+ */
+#define getPHYSR1()	\
+		WIZCHIP_READ(PHYSR1)
+
+/**
+ * For internal uses
+ * The address of the PHY is fixed as "0x0A".
+ */
+#define getPHYAR() \
+		WIZCHIP_READ(PHYAR)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PHYRAR register
+ * @return uint8_t. Value of @ref PHYRAR register.
+ * @sa setPHYRAR()
+ */
+#define getPHYRAR() \
+		WIZCHIP_READ(PHYRAR)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PHYRR register
+ * @param (uint8_t)phyrar Value to set @ref PHYRR register.
+ * @sa getPHYRR()
+ */
+#define setPHYRR(phyrar) \
+		WIZCHIP_WRITE(PHYRAR, phyrar)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PHYDIR register
+ * @return uint16_t. Value of @ref PHYDIR register.
+ * @sa setPHYRAR()
+ */
+//read the value of the phy data input register
+#define getPHYDIR() \
+		(((uint16_t)WIZCHIP_READ(PHYDIR+1) << 8) + WIZCHIP_READ(PHYDIR))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PHYDIR register
+ * @param (uint16_t)phydir Value to set @ref PHYDIR register.
+ * @sa getPHYDIR()
+ */
+//write the value of the phy data input register
+#define setPHYDIR(phydir) {\
+		WIZCHIP_WRITE(PHYDIR+1, (uint8_t)(phydir >> 8)); \
+		WIZCHIP_WRITE(PHYDIR, (uint8_t) phydir); \
+	}
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PHYDOR register
+ * @return uint16_t. Value of @ref PHYDOR register.
+ * @sa setPHYDOR()
+ */
+//read the value of the phy data output register
+#define getPHYDOR()	\
+		(((uint16_t)WIZCHIP_READ(PHYDOR+1) << 8) + WIZCHIP_READ(PHYDOR))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PHYDOR register
+ * @param (uint16_t)phydor Value to set @ref PHYDOR register.
+ * @sa getPHYDOR()
+ */
+//write the value of the phy data output register
+#define setPHYDOR(phydor) {\
+		WIZCHIP_WRITE(PHYDOR, (uint8_t)(phydor >> 8)); \
+		WIZCHIP_WRITE(PHYDOR+1, (uint8_t) phydor); \
+	}
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PHYACR register
+ * @return uint8_t. Value of @ref PHYACR register.
+ * @sa setPHYACR()
+ */
+//read the value of the phy action register ***This register will be cleared automatically***
+#define getPHYACR() \
+		WIZCHIP_READ(PHYACR)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PHYACR register
+ * @param (uint8_t)phyacr Value to set @ref PHYACR register.
+ * @sa getPHYACR()
+ */
+//write the value of the phy action register
+#define setPHYACR(phyacr)	\
+		WIZCHIP_WRITE(PHYACR,phyacr)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PHYDIVR register
+ * @param (uint8_t)phydivr Value to set @ref PHYDIVR register.
+ * @sa getPHYDIVR()
+ */
+#define setPHYDIVR(phydivr)	\
+		WIZCHIP_WRITE(PHYDIVR, phydivr)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PHYDIVR register
+ * @return uint8_t. Value of @ref PHYDIVR register.
+ * @sa setPHYDIVR()
+ */
+#define getPHYDIVR()	\
+		WIZCHIP_READ(PHYDIVR)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PHYCR0 register
+ * @param (uint8_t)phych0 Value to set @ref PHYCR0 register.
+ * @sa getPHYCR0()
+ */
+#define setPHYCR0(phych0)		\
+		WIZCHIP_WRITE(PHYCR0,phych0)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PHYCR0 register
+ * @return uint8_t. Value of @ref PHYCR0 register.
+ * @sa setPHYCR0()
+ */
+#define getPHYCR0()	\
+		WIZCHIP_READ(PHYCR0)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PHYCR1 register
+ * @param (uint8_t)phycr1 Value to set @ref PHYCR1 register.
+ * @sa getPHYCR1()
+ */
+#define setPHYCR1(phycr1)	\
+		WIZCHIP_WRITE(PHYCR1,phycr1)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PHYCR1 register
+ * @return uint8_t. Value of @ref PHYCR1 register.
+ * @sa setPHYCR1()
+ */
+#define getPHYCR1() \
+		WIZCHIP_READ(PHYCR1)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref SLCR register
+ * @param (uint8_t)rqcr Value to set @ref SLCR register.
+ * @sa getSLCR()
+ */
+#define setSLCR(rqcr)	\
+		WIZCHIP_WRITE(SLCR, rqcr)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref SLCR register
+ * @return uint8_t. Value of @ref SLCR register.
+ * @sa setSLCR()
+ */
+#define getSLCR()	\
+		WIZCHIP_READ(SLCR)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref SLRTR register
+ * @param (uint16_t)slrtr Value to set @ref SLRTR register.
+ * @sa getSLRTR()
+ */
+#define setSLRTR(slrtr)	\
+		WIZCHIP_WRITE(SLRTR, (uint8_t)(slrtr >> 8)); \
+		WIZCHIP_WRITE(SLRTR+1, (uint8_t) slrtr); \
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref SLRTR register
+ * @return uint16_t. Value of @ref SLRTR register.
+ * @sa setSLRTR()
+ */
+#define getSLRTR()	\
+		(((uint16_t)WIZCHIP_READ(SLRTR) << 8) + WIZCHIP_READ(SLRTR+1))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref SLRCR register
+ * @param (uint8_t)slrcr Value to set @ref SLRCR register.
+ * @sa getSLRCR()
+ */
+#define setSLRCR(slrcr)	\
+		WIZCHIP_WRITE(SLRCR,slrcr)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref SLRCR register
+ * @return uint8_t. Value of @ref SLRCR register.
+ * @sa setSLRCR()
+ */
+#define getSLRCR()	\
+		WIZCHIP_READ(SLRCR)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref SLPIPR registers
+ * @param (uint8_t*)slpipr Values to set @ref SLPIPR registers.
+ * @sa getSLPIPR()
+ */
+#define setSLPIPR(slpipr)	\
+		WIZCHIP_WRITE_BUF(SLPIPR,slpipr,4)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref SLPIPR registers
+ * @param (uint8_t*)slpipr Values to get @ref SLPIPR registers.
+ * @sa getSLPIPR()
+ */
+#define getSLPIPR(slpipr)	\
+		WIZCHIP_READ_BUF(SLPIPR,slpipr,4)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref SLPHAR registers
+ * @param (uint8_t*)slphar Values to set @ref SLPHAR registers.
+ * @sa getSLPHAR()
+ */
+#define setSLPHAR(slphar) \
+		WIZCHIP_WRITE_BUF(SLPHAR,slphar,6)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref SLPHAR registers
+ * @param (uint8_t*)slphar Values to get @ref SLPHAR registers.
+ * @sa getSLPHAR()
+ */
+#define getSLPHAR(slphar) \
+		WIZCHIP_READ_BUF(SLPHAR,slphar,6)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PINGSEQR register
+ * @param (uint16_t)pingseqr Value to set @ref PINGSEQR register.
+ * @sa getPINGSEQR()
+ */
+#define setPINGSEQR(pingseqr) {\
+		WIZCHIP_WRITE(PINGSEQR, (uint8_t)(pingseqr >> 8)); \
+		WIZCHIP_WRITE(PINGSEQR+1, (uint8_t) pingseqr); \
+	}
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PINGSEQR register
+ * @return uint16_t. Value of @ref PINGSEQR register.
+ * @sa setPINGSEQR()
+ */
+#define getPINGSEQR() \
+		(((uint16_t)WIZCHIP_READ(PINGSEQR) << 8) + WIZCHIP_READ(PINGSEQR+1))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref PINGIDR register
+ * @param (uint16_t)pingidr Value to set @ref PINGIDR register.
+ * @sa getPINGIDR()
+ */
+#define setPINGIDR(pingidr) {\
+		WIZCHIP_WRITE(PINGIDR, (uint8_t)(pingidr >> 8)); \
+		WIZCHIP_WRITE(PINGIDR+1, (uint8_t) pingidr); \
+	}
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref PINGIDR register
+ * @return uint16_t. Value of @ref PINGIDR register.
+ * @sa setPINGIDR()
+ */
+#define getPINGIDR()	\
+		(((uint16_t)WIZCHIP_READ(PINGIDR) << 8) + WIZCHIP_READ(PINGIDR+1))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref SLIMR register
+ * @param (uint8_t)slimr Value to set @ref SLIMR register.
+ * @sa getSLIMR()
+ */
+#define setSLIMR(slimr)	\
+		WIZCHIP_WRITE(SLIMR, slimr)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref SLIMR register
+ * @return uint8_t. Value of @ref SLIMR register.
+ * @sa setSLIMR()
+ */
+#define getSLIMR()	\
+		WIZCHIP_READ(SLIMR)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref SLIR register
+ * @param (uint8_t)slir Value to set @ref SLIR register.
+ * @sa getSLIMR()
+ */
+#define setSLIR(slir)	\
+		WIZCHIP_WRITE(SLIR, slir)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref SLIMR register
+ * @return uint8_t. Value of @ref SLIMR register.
+ * @sa setSLIMR()
+ */
+#define getSLIR()	\
+		WIZCHIP_READ(SLIR)
+
+/*Hidden functions for W5100S*/
+#define setDBGOUT(dbgout) 	{\
+		WIZCHIP_WRITE(DBGOUT,(uint8_t)(dbgout >> 16));	\
+		WIZCHIP_WRITE(DBGOUT,(uint8_t)(dbgout >> 8));	\
+		WIZCHIP_WRITE(DBGOUT,(uint8_t)(dbgout));		\
+	}
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref NICMAXCOLR register
+ * @param (uint8_t)nicmaxcolr Value to set @ref NICMAXCOLR register.
+ * @sa getNICMAXCOLR()
+ */
+#define setNICMAXCOLR(nicmaxcolr)	\
+		WIZCHIP_WRITE(NICMAXCOLR,nicmaxcolr)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref NICMAXCOLR register
+ * @return uint8_t. Value of @ref NICMAXCOLR register.
+ * @sa setNICMAXCOLR()
+ */
+#define getNICMAXCOLR()	\
+		WIZCHIP_READ(NICMAXCOLR)
+
+/*Clock lock/unlock*/
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief LOCK Chip Information
+ * @sa CHIPULLOCK()
+ */
+#define CHIPLOCK()	\
+		WIZCHIP_WRITE(CHIPLCKR,0xff)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Unlock Chip Information
+ * @sa CHIPLOCK()
+ */
+#define CHIPUNLOCK()	\
+		WIZCHIP_WRITE(CHIPLCKR,0xCE)
+
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief LOCK Chip Information
+ * @sa CHIPULLOCK()
+ */
+/*Network information lock/unlock*/
+#define NETLOCK()	\
+		WIZCHIP_WRITE(NETLCKR,0x3A)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Unlock Chip Information
+ * @sa CHIPLOCK()
+ */
+#define NETUNLOCK()	\
+		WIZCHIP_WRITE(NETLCKR,0xC5)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Lock PHYCR0,CR1 Information
+ * @sa CHIPULLOCK()
+ */
+/*PHY CR0,CR1 lock/unlock*/
+#define PHYLOCK()	\
+		WIZCHIP_WRITE(PHYLCKR,0xff)
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Lock PHYCR0,CR1 Information
+ * @sa CHIPULLOCK()
+ */
+#define PHYUNLOCK()	\
+		WIZCHIP_WRITE(PHYLCKR,0x53)
+
+/**
+ * @ingroup Version register_access_function_W5100SS
+ * @brief Get version information.
+ * @return uint16_t. It must be "0x51"
+ */
+#define getVER() \
+		(WIZCHIP_READ(VERR))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Get \ref TCNTR register
+ * @return uint16_t. Value of @ref TCNTR register.
+ * @sa setNTCNTR()
+ */
+/*Get 100us internal counter*/
+#define getTCNTR()	\
+		(((uint16_t)WIZCHIP_READ(TCNTR) << 8) + WIZCHIP_READ(TCNTR+1))
+
+/**
+ * @ingroup Common_register_access_function_W5100S
+ * @brief Set \ref TCNTR register
+ * @param (uint8_t)
+  Value to set @ref TCNTR register.
+ * @sa getTCNTCLKR()
+ */
+/*Reset 100us internal counter(TCNTR)*/
+#define setTCNTCLKR(var)	\
+		WIZCHIP_WRITE(TCNTCLKR, var)
+
+/*w5100s only end*/
+
+
+
+
+
+///////////////////////////////////
+// Socket N register I/O function //
+///////////////////////////////////
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_MR register
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b> expect <b>bit 4</b>.
+ * @param mr Value to set @ref Sn_MR
+ * @sa getSn_MR()
+ */
+#define setSn_MR(sn, mr) \
+		WIZCHIP_WRITE(Sn_MR(sn),mr)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_MR register
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b> expect <b>bit 4</b>.
+ * @return Value of @ref Sn_MR.
+ * @sa setSn_MR()
+ */
+#define getSn_MR(sn) \
+	WIZCHIP_READ(Sn_MR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_CR register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param (uint8_t)cr Value to set @ref Sn_CR
+ * @sa getSn_CR()
+ */
+#define setSn_CR(sn, cr) \
+		WIZCHIP_WRITE(Sn_CR(sn), cr)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_CR register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint8_t. Value of @ref Sn_CR.
+ * @sa setSn_CR()
+ */
+#define getSn_CR(sn) \
+		WIZCHIP_READ(Sn_CR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_IR register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param (uint8_t)ir Value to set @ref Sn_IR
+ * @sa getSn_IR()
+ */
+#define setSn_IR(sn, ir) \
+		WIZCHIP_WRITE(Sn_IR(sn), ir)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_IR register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint8_t. Value of @ref Sn_IR.
+ * @sa setSn_IR()
+ */
+#define getSn_IR(sn) \
+		WIZCHIP_READ(Sn_IR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_SR register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint8_t. Value of @ref Sn_SR.
+ */
+#define getSn_SR(sn) \
+		WIZCHIP_READ(Sn_SR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_PORT register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param (uint16_t)port Value to set @ref Sn_PORT.
+ * @sa getSn_PORT()
+ */
+#define setSn_PORT(sn, port)  { \
+		WIZCHIP_WRITE(Sn_PORT(sn),   (uint8_t)(port >> 8)); \
+		WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1), (uint8_t) port); \
+	}
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_PORT register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint16_t. Value of @ref Sn_PORT.
+ * @sa setSn_PORT()
+ */
+#define getSn_PORT(sn) \
+		(((uint16_t)WIZCHIP_READ(Sn_PORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_DHAR register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware address. It should be allocated 6 bytes.
+ * @sa getSn_DHAR()
+ */
+#define setSn_DHAR(sn, dhar) \
+		WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_DHAR register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware address. It should be allocated 6 bytes.
+ * @sa setSn_DHAR()
+ */
+#define getSn_DHAR(sn, dhar) \
+		WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_DIPR register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param (uint8_t*)dipr Pointer variable to set socket n destination IP address. It should be allocated 4 bytes.
+ * @sa getSn_DIPR()
+ */
+#define setSn_DIPR(sn, dipr) \
+		WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_DIPR register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes.
+ * @sa SetSn_DIPR()
+ */
+#define getSn_DIPR(sn, dipr) \
+		WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_DPORT register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param (uint16_t)dport Value to set @ref Sn_DPORT
+ * @sa getSn_DPORT()
+ */
+#define setSn_DPORT(sn, dport) { \
+		WIZCHIP_WRITE(Sn_DPORT(sn),   (uint8_t) (dport>>8)); \
+		WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1), (uint8_t)  dport); \
+	}
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_DPORT register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint16_t. Value of @ref Sn_DPORT.
+ * @sa setSn_DPORT()
+ */
+#define getSn_DPORT(sn) \
+		(((uint16_t)WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_MSSR register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param (uint16_t)mss Value to set @ref Sn_MSSR
+ * @sa setSn_MSSR()
+ */
+#define setSn_MSSR(sn, mss) { \
+		WIZCHIP_WRITE(Sn_MSSR(sn),   (uint8_t)(mss>>8)); \
+		WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1), (uint8_t) mss); \
+	}
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_MSSR register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint16_t. Value of @ref Sn_MSSR.
+ * @sa setSn_MSSR()
+ */
+#define getSn_MSSR(sn) \
+		(((uint16_t)WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_PROTO register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param (uint8_t)proto Value to set \ref Sn_PROTO
+ * @sa getSn_PROTO()
+ */
+#define setSn_PROTO(sn, proto) \
+		WIZCHIP_WRITE(Sn_PROTO(sn), proto)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_PROTO register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint8_t. Value of @ref Sn_PROTO.
+ * @sa setSn_PROTO()
+ */
+#define getSn_PROTO(sn) \
+		WIZCHIP_READ(Sn_PROTO(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_TOS register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param (uint8_t)tos Value to set @ref Sn_TOS
+ * @sa getSn_TOS()
+ */
+#define setSn_TOS(sn, tos) \
+		WIZCHIP_WRITE(Sn_TOS(sn), tos)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_TOS register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_ </b>.
+ * @return uint8_t. Value of Sn_TOS.
+ * @sa setSn_TOS()
+ */
+#define getSn_TOS(sn) \
+		WIZCHIP_READ(Sn_TOS(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_TTL register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_ </b>.
+ * @param (uint8_t)ttl Value to set @ref Sn_TTL
+ * @sa getSn_TTL()
+ */
+#define setSn_TTL(sn, ttl) \
+		WIZCHIP_WRITE(Sn_TTL(sn), ttl)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_TTL register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_ </b>.
+ * @return uint8_t. Value of @ref Sn_TTL.
+ * @sa setSn_TTL()
+ */
+#define getSn_TTL(sn) \
+		WIZCHIP_READ(Sn_TTL(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_RXMEM_SIZE register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_ </b>.
+ * @param (uint8_t)rxmemsize Value to set \ref Sn_RXMEM_SIZE
+ * @sa getSn_RXMEM_SIZE()
+ */
+#define  setSn_RXMEM_SIZE(sn, rxmemsize) \
+      WIZCHIP_WRITE(RMSR, (WIZCHIP_READ(RMSR) & ~(0x03 << (2*sn))) | (rxmemsize << (2*sn)))
+#define setSn_RXBUF_SIZE(sn,rxmemsize) setSn_RXMEM_SIZE(sn,rxmemsize)
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_RXMEM_SIZE register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint8_t. Value of @ref Sn_RXMEM.
+ * @sa setSn_RXMEM_SIZE()
+ */
+#define  getSn_RXMEM_SIZE(sn) \
+      ((WIZCHIP_READ(RMSR) & (0x03 << (2*sn))) >> (2*sn))
+#define  getSn_RXBUF_SIZE(sn) getSn_RXMEM_SIZE(sn)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_TXMEM_SIZE register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param (uint8_t)txmemsize Value to set \ref Sn_TXMEM_SIZE
+ * @sa getSn_TXMEM_SIZE()
+ */
+#define setSn_TXMEM_SIZE(sn, txmemsize) \
+      WIZCHIP_WRITE(TMSR, (WIZCHIP_READ(TMSR) & ~(0x03 << (2*sn))) | (txmemsize << (2*sn)))
+#define  setSn_TXBUF_SIZE(sn, txmemsize) setSn_TXMEM_SIZE(sn,txmemsize)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_TXMEM_SIZE register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint8_t. Value of @ref Sn_TXMEM_SIZE.
+ * @sa setSn_TXMEM_SIZE()
+ */
+#define  getSn_TXMEM_SIZE(sn) \
+      ((WIZCHIP_READ(TMSR) & (0x03 << (2*sn))) >> (2*sn))
+#define  getSn_TXBUF_SIZE(sn) getSn_TXMEM_SIZE(sn)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_TX_FSR register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint16_t. Value of @ref Sn_TX_FSR.
+ */
+uint16_t getSn_TX_FSR(uint8_t sn);
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_TX_RD register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint16_t. Value of @ref Sn_TX_RD.
+ */
+#define getSn_TX_RD(sn) \
+		(((uint16_t)WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_TX_WR register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param (uint16_t)txwr Value to set @ref Sn_TX_WR
+ * @sa GetSn_TX_WR()
+ */
+#define setSn_TX_WR(sn, txwr) { \
+		WIZCHIP_WRITE(Sn_TX_WR(sn),   (uint8_t)(txwr>>8)); \
+		WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1), (uint8_t) txwr); \
+		}
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_TX_WR register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint16_t. Value of @ref Sn_TX_WR.
+ * @sa setSn_TX_WR()
+ */
+#define getSn_TX_WR(sn) \
+		(((uint16_t)WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_RX_RSR register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint16_t. Value of @ref Sn_RX_RSR.
+ */
+uint16_t getSn_RX_RSR(uint8_t sn);
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_RX_RD register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD
+ * @sa getSn_RX_RD()
+ */
+#define setSn_RX_RD(sn, rxrd) { \
+		WIZCHIP_WRITE(Sn_RX_RD(sn),   (uint8_t)(rxrd>>8)); \
+		WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1), (uint8_t) rxrd); \
+	}
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_RX_RD register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @regurn uint16_t. Value of @ref Sn_RX_RD.
+ * @sa setSn_RX_RD()
+ */
+#define getSn_RX_RD(sn) \
+		(((uint16_t)WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_RX_WR register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param (uint16_t)rxwr Value to set \ref Sn_RX_WR
+ * @sa getSn_RX_WR()
+ */
+#define setSn_RX_WR(sn, rxwr) { \
+		WIZCHIP_WRITE(Sn_RX_WR(sn),   (uint8_t)(rxwr>>8)); \
+	   WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1), (uint8_t) rxwr); \
+	}
+
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_RX_WR register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint16_t. Value of @ref Sn_RX_WR.
+ */
+#define getSn_RX_WR(sn) \
+		(((uint16_t)WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set @ref Sn_FRAGR register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param (uint16_t)frag Value to set \ref Sn_FRAGR
+ * @sa getSn_FRAG()
+ */
+#define setSn_FRAGR(sn, fragr) { \
+		WIZCHIP_WRITE(Sn_FRAGR(sn),  (uint8_t)(fragr >>8)); \
+		WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAGR(sn),1), (uint8_t) fragr); \
+	}
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get @ref Sn_FRAGR register
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint16_t. Value of @ref Sn_FRAGR.
+ * @sa setSn_FRAG()
+ */
+#define getSn_FRAGR(sn) \
+		(((uint16_t)WIZCHIP_READ(Sn_FRAGR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAGR(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the max RX buffer size of socket sn
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint16_t. Max buffer size
+ */
+#define getSn_RxMAX(sn) \
+		((uint16_t)(0x0001 << getSn_RXMEM_SIZE(sn)) << 10)
+
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the max TX buffer size of socket sn
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint16_t. Max buffer size
+ */
+#define getSn_TxMAX(sn) \
+		((uint16_t)(0x0001 << getSn_TXMEM_SIZE(sn)) << 10)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the mask of socket sn RX buffer.
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint16_t. Mask value
+ */
+#define getSn_RxMASK(sn) \
+		(getSn_RxMAX(sn) - 1)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the mask of socket sn TX buffer
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint16_t. Mask value
+ */
+#define getSn_TxMASK(sn) \
+		(getSn_TxMAX(sn) - 1)
+
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the base address of socket sn RX buffer.
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint16_t. Value of Socket n RX buffer base address.
+ */
+uint32_t getSn_RxBASE(uint8_t sn);
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the base address of socket sn TX buffer.
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint16_t. Value of Socket n TX buffer base address.
+ */
+uint32_t getSn_TxBASE(uint8_t sn);
+
+
+/*socket register W5100S only*/
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set the interrupt mask register of socket sn.
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param (uint16_t)imr Value to set \ref Sn_IMR
+ * @sa getSn_IMR(sn)
+ */
+#define setSn_IMR(sn,imr)	\
+		WIZCHIP_WRITE(Sn_IMR(sn),imr)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the interrupt mask register of socket sn.
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint16_t. Value of Socket n interrupt mask register.
+ */
+#define getSn_IMR(sn)	\
+		WIZCHIP_READ(Sn_IMR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set the Sn_MR2 value of socket sn.
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param mr2 Value of Sn_MR2 register to set.
+ */
+#define setSn_MR2(sn,mr2)	\
+		WIZCHIP_WRITE(Sn_MR2(sn), mr2)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the Sn_MR2 value of socket sn.
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint16_t. Value of Socket n Sn_MR2 register.
+ */
+#define getSn_MR2(sn)	\
+		WIZCHIP_READ(Sn_MR2(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set the Sn_KPALVTR value of socket sn.
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param kpalvtr Value of the Sn_KPALVTR register to set.
+ */
+#define setSn_KPALVTR(sn,kpalvtr)	\
+		WIZCHIP_WRITE(Sn_KPALVTR(sn), kpalvtr)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the Sn_KPALVTR value of socket sn
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint8_t. Value of the Sn_KPALVTR register.
+ */
+#define getSn_KPALVTR(sn)	\
+		WIZCHIP_READ(Sn_KPALVTR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the Sn_TSR register of socket sn.
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint8_t. Value of the Socket n Sn_TSR register.
+ */
+#define	getSn_TSR(sn)	\
+		WIZCHIP_READ(Sn_TSR(sn))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set the Sn_RTR register of socket sn.
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param (uint16_t)rtr Value of the Socket n Sn_RTR register to set.
+ */
+#define	setSn_RTR(sn,rtr)	{ \
+		WIZCHIP_WRITE(Sn_RTR(sn),   (uint8_t)(rtr >> 8)); \
+		WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RTR(sn),1), (uint8_t) rtr); \
+		}
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the Sn_RTR register of socket sn.
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint16_t. Value of the Socket n Sn_RTR register.
+ */
+#define getSn_RTR(sn)	\
+		(((uint16_t)WIZCHIP_READ(Sn_RTR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RTR(sn),1)))
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Set the Sn_RCR register of socket sn.
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint8_t. Value of the Socket n Sn_RCR register to set.
+ */
+#define setSn_RCR(sn,rcr)	\
+		WIZCHIP_WRITE(Sn_RCR(sn),rcr)
+
+/**
+ * @ingroup Socket_register_access_function_W5100S
+ * @brief Get the Sn_RCR of socket sn.
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return uint8_t. Value of the Socket n Sn_RCR.
+ */
+#define getSn_RCR(sn)	\
+		WIZCHIP_READ(Sn_RCR(sn))
+
+/////////////////////////////////////
+// Sn_TXBUF & Sn_RXBUF IO function //
+/////////////////////////////////////
+/**
+ * @ingroup Basic_IO_function_W5100S
+ * @brief It copies data to internal TX memory
+ *
+ * @details This function reads the Tx write pointer register and after that,
+ * it copies the <i>wizdata(pointer buffer)</i> of the length of <i>len(variable)</i> bytes to internal TX memory
+ * and updates the Tx write pointer register.
+ * This function is being called by send() and sendto() function also.
+ *
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param wizdata Pointer buffer to write data
+ * @param len Data length
+ * @sa wiz_recv_data()
+ */
+void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len);
+
+/**
+ * @ingroup Basic_IO_function_W5100S
+ * @brief It copies data to your buffer from internal RX memory
+ *
+ * @details This function read the Rx read pointer register and after that,
+ * it copies the received data from internal RX memory
+ * to <i>wizdata(pointer variable)</i> of the length of <i>len(variable)</i> bytes.
+ * This function is being called by recv() also.
+ *
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param wizdata Pointer buffer to read data
+ * @param len Data length
+ * @sa wiz_send_data()
+ */
+void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len);
+
+/**
+ * @ingroup Basic_IO_function_W5100S
+ * @brief It discard the received data in RX memory.
+ * @details It discards the data of the length of <i>len(variable)</i> bytes in internal RX memory.
+ * @param (uint8_t)sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param len Data length
+ */
+void wiz_recv_ignore(uint8_t sn, uint16_t len);
+
+/**
+ * @ingroup Special_function_W5100S
+ * @brief Write data to the PHY via MDC/MDIO interface.
+ * @details Write command data to the PHY via MDC/MDIO interface.
+ * @param (uint8_t)PHYMDIO_regadr Address of the PHY register. It should be PHYMDIO_BMCR or PHYMDIO_BMSR.
+ * @param (uint16_t)var Data to write to the PHY register. Please refer to the bit definitions of the BMCR and BMSR register.
+ */
+void wiz_mdio_write(uint8_t PHYMDIO_regadr, uint16_t var);
+
+/**
+ * @ingroup Special_function_W5100S
+ * @brief Read data from the PHY via MDC/MDIO interface.
+ * @details Read command or status data from the PHY via MDC/MDIO interface.
+ * @param (uint8_t)PHYMDIO_regadr Address of the PHY register. It should be PHYMDIO_BMCR or PHYMDIO_BMSR.
+ * @return The value of the PHY register
+ */
+uint16_t wiz_mdio_read(uint8_t PHYMDIO_regadr);
+
+/**
+ * @ingroup Special_function_W5100S
+ * @brief Delay function
+ * @details Delay function using internal 100us timer of the W5100S
+ * @param (uint32_t)ms Time to delay in milliseconds.
+ */
+void wiz_delay_ms(uint32_t ms);
+
+/// @cond DOXY_APPLY_CODE
+#endif
+/// @endcond
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_W5100S_H_
+
+
+
Index: ctrl/firmware/Main/SES/Wiznet/Ethernet/socket.c
===================================================================
--- ctrl/firmware/Main/SES/Wiznet/Ethernet/socket.c	(revision 79)
+++ ctrl/firmware/Main/SES/Wiznet/Ethernet/socket.c	(revision 79)
@@ -0,0 +1,937 @@
+//*****************************************************************************
+//
+//! \file socket.c
+//! \brief SOCKET APIs Implements file.
+//! \details SOCKET APIs like as Berkeley Socket APIs.
+//! \version 1.0.3
+//! \date 2013/10/21
+//! \par  Revision history
+//!       <2015/02/05> Notice
+//!        The version history is not updated after this point.
+//!        Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
+//!        >> https://github.com/Wiznet/ioLibrary_Driver
+//!       <2014/05/01> V1.0.3. Refer to M20140501
+//!         1. Implicit type casting -> Explicit type casting.
+//!         2. replace 0x01 with PACK_REMAINED in recvfrom()
+//!         3. Validation a destination ip in connect() & sendto():
+//!            It occurs a fatal error on converting unint32 address if uint8* addr parameter is not aligned by 4byte address.
+//!            Copy 4 byte addr value into temporary uint32 variable and then compares it.
+//!       <2013/12/20> V1.0.2 Refer to M20131220
+//!                    Remove Warning.
+//!       <2013/11/04> V1.0.1 2nd Release. Refer to "20131104".
+//!                    In sendto(), Add to clear timeout interrupt status (Sn_IR_TIMEOUT)
+//!       <2013/10/21> 1st Release
+//! \author MidnightCow
+//! \copyright
+//!
+//! Copyright (c)  2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//!     * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//!     * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//!     * Neither the name of the <ORGANIZATION> nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+#include "socket.h"
+
+//M20150401 : Typing Error
+//#define SOCK_ANY_PORT_NUM  0xC000;
+#define SOCK_ANY_PORT_NUM  0xC000
+
+static uint16_t sock_any_port = SOCK_ANY_PORT_NUM;
+static uint16_t sock_io_mode = 0;
+static uint16_t sock_is_sending = 0;
+
+static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,};
+
+//M20150601 : For extern decleation
+//static uint8_t  sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,};
+uint8_t  sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,};
+//
+
+#if _WIZCHIP_ == 5200
+   static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] ={0,};
+#endif
+
+//A20150601 : For integrating with W5300
+#if _WIZCHIP_ == 5300
+   uint8_t sock_remained_byte[_WIZCHIP_SOCK_NUM_] = {0,}; // set by wiz_recv_data()
+#endif
+
+
+#define CHECK_SOCKNUM()   \
+   do{                    \
+      if(sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM;   \
+   }while(0);             \
+
+#define CHECK_SOCKMODE(mode)  \
+   do{                     \
+      if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE;  \
+   }while(0);              \
+
+#define CHECK_SOCKINIT()   \
+   do{                     \
+      if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \
+   }while(0);              \
+
+#define CHECK_SOCKDATA()   \
+   do{                     \
+      if(len == 0) return SOCKERR_DATALEN;   \
+   }while(0);              \
+
+
+
+int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
+{
+	CHECK_SOCKNUM();
+	switch(protocol)
+	{
+		case Sn_MR_TCP :
+			{
+				//M20150601 : Fixed the warning - taddr will never be NULL
+				/*
+				uint8_t taddr[4];
+				getSIPR(taddr);
+				*/
+				uint32_t taddr;
+				getSIPR((uint8_t*)&taddr);
+				if(taddr == 0) return SOCKERR_SOCKINIT;
+				break;
+			}
+		case Sn_MR_UDP :
+		case Sn_MR_MACRAW :
+		case Sn_MR_IPRAW :
+			break;
+#if ( _WIZCHIP_ < 5200 )
+		case Sn_MR_PPPoE :
+			break;
+#endif
+		default :
+			return SOCKERR_SOCKMODE;
+	}
+	//M20150601 : For SF_TCP_ALIGN & W5300
+	//if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG;
+	if((flag & 0x04) != 0) return SOCKERR_SOCKFLAG;
+#if _WIZCHIP_ == 5200
+	if(flag & 0x10) return SOCKERR_SOCKFLAG;
+#endif
+
+	if(flag != 0)
+	{
+		switch(protocol)
+		{
+			case Sn_MR_TCP:
+				//M20150601 :  For SF_TCP_ALIGN & W5300
+#if _WIZCHIP_ == 5300
+				if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK|SF_TCP_ALIGN))==0) return SOCKERR_SOCKFLAG;
+#else
+				if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK))==0) return SOCKERR_SOCKFLAG;
+#endif
+
+				break;
+			case Sn_MR_UDP:
+				if(flag & SF_IGMP_VER2)
+				{
+					if((flag & SF_MULTI_ENABLE)==0) return SOCKERR_SOCKFLAG;
+				}
+#if _WIZCHIP_ == 5500
+				if(flag & SF_UNI_BLOCK)
+				{
+					if((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG;
+				}
+#endif
+				break;
+			default:
+				break;
+		}
+	}
+	close(sn);
+	//M20150601
+#if _WIZCHIP_ == 5300
+	setSn_MR(sn, ((uint16_t)(protocol | (flag & 0xF0))) | (((uint16_t)(flag & 0x02)) << 7) );
+#else
+	setSn_MR(sn, (protocol | (flag & 0xF0)));
+#endif
+	if(!port)
+	{
+		port = sock_any_port++;
+		if(sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM;
+	}
+	setSn_PORT(sn,port);
+	setSn_CR(sn,Sn_CR_OPEN);
+	while(getSn_CR(sn));
+	//A20150401 : For release the previous sock_io_mode
+	sock_io_mode &= ~(1 <<sn);
+	//
+	sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn);
+	sock_is_sending &= ~(1<<sn);
+	sock_remained_size[sn] = 0;
+	//M20150601 : repalce 0 with PACK_COMPLETED
+	//sock_pack_info[sn] = 0;
+	sock_pack_info[sn] = PACK_COMPLETED;
+	//
+	while(getSn_SR(sn) == SOCK_CLOSED);
+	return (int8_t)sn;
+}
+
+int8_t close(uint8_t sn)
+{
+	CHECK_SOCKNUM();
+//A20160426 : Applied the erratum 1 of W5300
+#if   (_WIZCHIP_ == 5300)
+   //M20160503 : Wrong socket parameter. s -> sn
+   //if( ((getSn_MR(s)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(s) != getSn_TxMAX(s)) )
+   if( ((getSn_MR(sn)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(sn) != getSn_TxMAX(sn)) )
+   {
+      uint8_t destip[4] = {0, 0, 0, 1};
+      // TODO
+      // You can wait for completing to sending data;
+      // wait about 1 second;
+      // if you have completed to send data, skip the code of erratum 1
+      // ex> wait_1s();
+      //     if (getSn_TX_FSR(s) == getSn_TxMAX(s)) continue;
+      //
+      //M20160503 : The socket() of close() calls close() itself again. It occures a infinite loop - close()->socket()->close()->socket()-> ~
+      //socket(s,Sn_MR_UDP,0x3000,0);
+      //sendto(s,destip,1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
+      setSn_MR(sn,Sn_MR_UDP);
+      setSn_PORTR(sn, 0x3000);
+      setSn_CR(sn,Sn_CR_OPEN);
+      while(getSn_CR(sn) != 0);
+      while(getSn_SR(sn) != SOCK_UDP);
+      sendto(sn,destip,1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
+   };
+#endif
+	setSn_CR(sn,Sn_CR_CLOSE);
+   /* wait to process the command... */
+	while( getSn_CR(sn) );
+	/* clear all interrupt of the socket. */
+	setSn_IR(sn, 0xFF);
+	//A20150401 : Release the sock_io_mode of socket n.
+	sock_io_mode &= ~(1<<sn);
+	//
+	sock_is_sending &= ~(1<<sn);
+	sock_remained_size[sn] = 0;
+	sock_pack_info[sn] = 0;
+	while(getSn_SR(sn) != SOCK_CLOSED);
+	return SOCK_OK;
+}
+
+int8_t listen(uint8_t sn)
+{
+	CHECK_SOCKNUM();
+   CHECK_SOCKMODE(Sn_MR_TCP);
+	CHECK_SOCKINIT();
+	setSn_CR(sn,Sn_CR_LISTEN);
+	while(getSn_CR(sn));
+   while(getSn_SR(sn) != SOCK_LISTEN)
+   {
+         close(sn);
+         return SOCKERR_SOCKCLOSED;
+   }
+   return SOCK_OK;
+}
+
+
+int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port)
+{
+   CHECK_SOCKNUM();
+   CHECK_SOCKMODE(Sn_MR_TCP);
+   CHECK_SOCKINIT();
+   //M20140501 : For avoiding fatal error on memory align mismatched
+   //if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
+   {
+      uint32_t taddr;
+      taddr = ((uint32_t)addr[0] & 0x000000FF);
+      taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF);
+      taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF);
+      taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF);
+      if( taddr == 0xFFFFFFFF || taddr == 0) return SOCKERR_IPINVALID;
+   }
+   //
+
+	if(port == 0) return SOCKERR_PORTZERO;
+	setSn_DIPR(sn,addr);
+	setSn_DPORT(sn,port);
+	setSn_CR(sn,Sn_CR_CONNECT);
+   while(getSn_CR(sn));
+   if(sock_io_mode & (1<<sn)) return SOCK_BUSY;
+   while(getSn_SR(sn) != SOCK_ESTABLISHED)
+   {
+		if (getSn_IR(sn) & Sn_IR_TIMEOUT)
+		{
+			setSn_IR(sn, Sn_IR_TIMEOUT);
+            return SOCKERR_TIMEOUT;
+		}
+
+		if (getSn_SR(sn) == SOCK_CLOSED)
+		{
+			return SOCKERR_SOCKCLOSED;
+		}
+	}
+
+   return SOCK_OK;
+}
+
+int8_t disconnect(uint8_t sn)
+{
+   CHECK_SOCKNUM();
+   CHECK_SOCKMODE(Sn_MR_TCP);
+	setSn_CR(sn,Sn_CR_DISCON);
+	/* wait to process the command... */
+	while(getSn_CR(sn));
+	sock_is_sending &= ~(1<<sn);
+   if(sock_io_mode & (1<<sn)) return SOCK_BUSY;
+	while(getSn_SR(sn) != SOCK_CLOSED)
+	{
+	   if(getSn_IR(sn) & Sn_IR_TIMEOUT)
+	   {
+	      close(sn);
+	      return SOCKERR_TIMEOUT;
+	   }
+	}
+	return SOCK_OK;
+}
+
+int32_t send(uint8_t sn, uint8_t * buf, uint16_t len)
+{
+   uint8_t tmp=0;
+   uint16_t freesize=0;
+
+   CHECK_SOCKNUM();
+   CHECK_SOCKMODE(Sn_MR_TCP);
+   CHECK_SOCKDATA();
+   tmp = getSn_SR(sn);
+   if(tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) return SOCKERR_SOCKSTATUS;
+   if( sock_is_sending & (1<<sn) )
+   {
+      tmp = getSn_IR(sn);
+      if(tmp & Sn_IR_SENDOK)
+      {
+         setSn_IR(sn, Sn_IR_SENDOK);
+         //M20150401 : Typing Error
+         //#if _WZICHIP_ == 5200
+         #if _WIZCHIP_ == 5200
+            if(getSn_TX_RD(sn) != sock_next_rd[sn])
+            {
+               setSn_CR(sn,Sn_CR_SEND);
+               while(getSn_CR(sn));
+               return SOCK_BUSY;
+            }
+         #endif
+         sock_is_sending &= ~(1<<sn);
+      }
+      else if(tmp & Sn_IR_TIMEOUT)
+      {
+         close(sn);
+         return SOCKERR_TIMEOUT;
+      }
+      else return SOCK_BUSY;
+   }
+   freesize = getSn_TxMAX(sn);
+   if (len > freesize) len = freesize; // check size not to exceed MAX size.
+   while(1)
+   {
+      freesize = getSn_TX_FSR(sn);
+      tmp = getSn_SR(sn);
+      if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT))
+      {
+         close(sn);
+         return SOCKERR_SOCKSTATUS;
+      }
+      if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
+      if(len <= freesize) break;
+   }
+   wiz_send_data(sn, buf, len);
+   #if _WIZCHIP_ == 5200
+      sock_next_rd[sn] = getSn_TX_RD(sn) + len;
+   #endif
+
+   #if _WIZCHIP_ == 5300
+      setSn_TX_WRSR(sn,len);
+   #endif
+
+   setSn_CR(sn,Sn_CR_SEND);
+   /* wait to process the command... */
+   while(getSn_CR(sn));
+   sock_is_sending |= (1 << sn);
+   //M20150409 : Explicit Type Casting
+   //return len;
+   return (int32_t)len;
+}
+
+
+int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len)
+{
+   uint8_t  tmp = 0;
+   uint16_t recvsize = 0;
+//A20150601 : For integarating with W5300
+#if   _WIZCHIP_ == 5300
+   uint8_t head[2];
+   uint16_t mr;
+#endif
+//
+   CHECK_SOCKNUM();
+   CHECK_SOCKMODE(Sn_MR_TCP);
+   CHECK_SOCKDATA();
+
+   recvsize = getSn_RxMAX(sn);
+   if(recvsize < len) len = recvsize;
+
+//A20150601 : For Integrating with W5300
+#if _WIZCHIP_ == 5300
+   //sock_pack_info[sn] = PACK_COMPLETED;    // for clear
+   if(sock_remained_size[sn] == 0)
+   {
+#endif
+//
+      while(1)
+      {
+         recvsize = getSn_RX_RSR(sn);
+         tmp = getSn_SR(sn);
+         if (tmp != SOCK_ESTABLISHED)
+         {
+            if(tmp == SOCK_CLOSE_WAIT)
+            {
+               if(recvsize != 0) break;
+               else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn))
+               {
+                  close(sn);
+                  return SOCKERR_SOCKSTATUS;
+               }
+            }
+            else
+            {
+               close(sn);
+               return SOCKERR_SOCKSTATUS;
+            }
+         }
+         if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY;
+         if(recvsize != 0) break;
+      };
+#if _WIZCHIP_ == 5300
+   }
+#endif
+
+//A20150601 : For integrating with W5300
+#if _WIZCHIP_ == 5300
+   if((sock_remained_size[sn] == 0) || (getSn_MR(sn) & Sn_MR_ALIGN))
+   {
+      mr = getMR();
+      if((getSn_MR(sn) & Sn_MR_ALIGN)==0)
+      {
+         wiz_recv_data(sn,head,2);
+         if(mr & MR_FS)
+            recvsize = (((uint16_t)head[1]) << 8) | ((uint16_t)head[0]);
+         else
+            recvsize = (((uint16_t)head[0]) << 8) | ((uint16_t)head[1]);
+         sock_pack_info[sn] = PACK_FIRST;
+      }
+      sock_remained_size[sn] = recvsize;
+   }
+   if(len > sock_remained_size[sn]) len = sock_remained_size[sn];
+   recvsize = len;
+   if(sock_pack_info[sn] & PACK_FIFOBYTE)
+   {
+      *buf = sock_remained_byte[sn];
+      buf++;
+      sock_pack_info[sn] &= ~(PACK_FIFOBYTE);
+      recvsize -= 1;
+      sock_remained_size[sn] -= 1;
+   }
+   if(recvsize != 0)
+   {
+      wiz_recv_data(sn, buf, recvsize);
+      setSn_CR(sn,Sn_CR_RECV);
+      while(getSn_CR(sn));
+   }
+   sock_remained_size[sn] -= recvsize;
+   if(sock_remained_size[sn] != 0)
+   {
+      sock_pack_info[sn] |= PACK_REMAINED;
+      if(recvsize & 0x1) sock_pack_info[sn] |= PACK_FIFOBYTE;
+   }
+   else sock_pack_info[sn] = PACK_COMPLETED;
+   if(getSn_MR(sn) & Sn_MR_ALIGN) sock_remained_size[sn] = 0;
+   //len = recvsize;
+#else
+   if(recvsize < len) len = recvsize;
+   wiz_recv_data(sn, buf, len);
+   setSn_CR(sn,Sn_CR_RECV);
+   while(getSn_CR(sn));
+#endif
+
+   //M20150409 : Explicit Type Casting
+   //return len;
+   return (int32_t)len;
+}
+
+int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port)
+{
+   uint8_t tmp = 0;
+   uint16_t freesize = 0;
+   uint32_t taddr;
+
+   CHECK_SOCKNUM();
+   switch(getSn_MR(sn) & 0x0F)
+   {
+      case Sn_MR_UDP:
+      case Sn_MR_MACRAW:
+//         break;
+//   #if ( _WIZCHIP_ < 5200 )
+      case Sn_MR_IPRAW:
+         break;
+//   #endif
+      default:
+         return SOCKERR_SOCKMODE;
+   }
+   CHECK_SOCKDATA();
+   //M20140501 : For avoiding fatal error on memory align mismatched
+   //if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
+   //{
+      //uint32_t taddr;
+      taddr = ((uint32_t)addr[0]) & 0x000000FF;
+      taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF);
+      taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF);
+      taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF);
+   //}
+   //
+   //if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
+   if((taddr == 0) && ((getSn_MR(sn)&Sn_MR_MACRAW) != Sn_MR_MACRAW)) return SOCKERR_IPINVALID;
+   if((port  == 0) && ((getSn_MR(sn)&Sn_MR_MACRAW) != Sn_MR_MACRAW)) return SOCKERR_PORTZERO;
+   tmp = getSn_SR(sn);
+//#if ( _WIZCHIP_ < 5200 )
+   if((tmp != SOCK_MACRAW) && (tmp != SOCK_UDP) && (tmp != SOCK_IPRAW)) return SOCKERR_SOCKSTATUS;
+//#else
+//   if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS;
+//#endif
+
+   setSn_DIPR(sn,addr);
+   setSn_DPORT(sn,port);
+   freesize = getSn_TxMAX(sn);
+   if (len > freesize) len = freesize; // check size not to exceed MAX size.
+   while(1)
+   {
+      freesize = getSn_TX_FSR(sn);
+      if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
+      if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
+      if(len <= freesize) break;
+   };
+	wiz_send_data(sn, buf, len);
+
+   #if _WIZCHIP_ < 5500   //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
+      getSIPR((uint8_t*)&taddr);
+      if(taddr == 0)
+      {
+         getSUBR((uint8_t*)&taddr);
+         setSUBR((uint8_t*)"\x00\x00\x00\x00");
+      }
+      else taddr = 0;
+   #endif
+
+//A20150601 : For W5300
+#if _WIZCHIP_ == 5300
+   setSn_TX_WRSR(sn, len);
+#endif
+//
+	setSn_CR(sn,Sn_CR_SEND);
+	/* wait to process the command... */
+	while(getSn_CR(sn));
+   while(1)
+   {
+      tmp = getSn_IR(sn);
+      if(tmp & Sn_IR_SENDOK)
+      {
+         setSn_IR(sn, Sn_IR_SENDOK);
+         break;
+      }
+      //M:20131104
+      //else if(tmp & Sn_IR_TIMEOUT) return SOCKERR_TIMEOUT;
+      else if(tmp & Sn_IR_TIMEOUT)
+      {
+         setSn_IR(sn, Sn_IR_TIMEOUT);
+         //M20150409 : Fixed the lost of sign bits by type casting.
+         //len = (uint16_t)SOCKERR_TIMEOUT;
+         //break;
+         #if _WIZCHIP_ < 5500   //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
+            if(taddr) setSUBR((uint8_t*)&taddr);
+         #endif
+         return SOCKERR_TIMEOUT;
+      }
+      ////////////
+   }
+   #if _WIZCHIP_ < 5500   //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
+      if(taddr) setSUBR((uint8_t*)&taddr);
+   #endif
+   //M20150409 : Explicit Type Casting
+   //return len;
+   return (int32_t)len;
+}
+
+
+
+int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port)
+{
+//M20150601 : For W5300
+#if _WIZCHIP_ == 5300
+	uint16_t mr;
+	uint16_t mr1;
+#else
+	uint8_t  mr;
+#endif
+//
+	uint8_t  head[8];
+	uint16_t pack_len=0;
+
+	CHECK_SOCKNUM();
+	//CHECK_SOCKMODE(Sn_MR_UDP);
+//A20150601
+#if _WIZCHIP_ == 5300
+	mr1 = getMR();
+#endif
+
+	switch((mr = getSn_MR(sn)) & 0x0F)
+	{
+		case Sn_MR_UDP:
+		case Sn_MR_IPRAW:
+		case Sn_MR_MACRAW:
+			break;
+#if ( _WIZCHIP_ < 5200 )
+		case Sn_MR_PPPoE:
+			break;
+#endif
+		default:
+			return SOCKERR_SOCKMODE;
+	}
+
+	CHECK_SOCKDATA();
+
+	if(sock_remained_size[sn] == 0)
+	{
+		while(1)
+		{
+			pack_len = getSn_RX_RSR(sn);
+			if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
+			if( (sock_io_mode & (1<<sn)) && (pack_len == 0) ) return SOCK_BUSY;
+			if(pack_len != 0) break;
+		};
+	}
+
+//D20150601 : Move it to bottom
+// sock_pack_info[sn] = PACK_COMPLETED;
+
+	switch (mr & 0x07)
+	{
+		case Sn_MR_UDP :
+			if(sock_remained_size[sn] == 0)
+			{
+				wiz_recv_data(sn, head, 8);
+				setSn_CR(sn,Sn_CR_RECV);
+				while(getSn_CR(sn));
+				// read peer's IP address, port number & packet length
+				//A20150601 : For W5300
+#if _WIZCHIP_ == 5300
+				if(mr1 & MR_FS)
+				{
+					addr[0] = head[1];
+         		    addr[1] = head[0];
+         		    addr[2] = head[3];
+         		    addr[3] = head[2];
+         		    *port = head[5];
+         		    *port = (*port << 8) + head[4];
+					sock_remained_size[sn] = head[7];
+					sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[6];
+				}
+				else
+				{
+#endif
+					addr[0] = head[0];
+					addr[1] = head[1];
+					addr[2] = head[2];
+					addr[3] = head[3];
+					*port = head[4];
+					*port = (*port << 8) + head[5];
+					sock_remained_size[sn] = head[6];
+					sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7];
+#if _WIZCHIP_ == 5300
+				}
+#endif
+				sock_pack_info[sn] = PACK_FIRST;
+			}
+
+			if(len < sock_remained_size[sn]) pack_len = len;
+			else pack_len = sock_remained_size[sn];
+			//A20150601 : For W5300
+			len = pack_len;
+#if _WIZCHIP_ == 5300
+			if(sock_pack_info[sn] & PACK_FIFOBYTE)
+			{
+				*buf++ = sock_remained_byte[sn];
+			    pack_len -= 1;
+			    sock_remained_size[sn] -= 1;
+			    sock_pack_info[sn] &= ~PACK_FIFOBYTE;
+			}
+#endif
+			//
+			// Need to packet length check (default 1472)
+			//
+			wiz_recv_data(sn, buf, pack_len); // data copy.
+			break;
+
+		case Sn_MR_MACRAW :
+			if(sock_remained_size[sn] == 0)
+			{
+				wiz_recv_data(sn, head, 2);
+				setSn_CR(sn,Sn_CR_RECV);
+				while(getSn_CR(sn));
+				// read peer's IP address, port number & packet length
+    			sock_remained_size[sn] = head[0];
+				sock_remained_size[sn] = (sock_remained_size[sn] <<8) + head[1] -2;
+#if _WIZCHIP_ == W5300
+				if(sock_remained_size[sn] & 0x01)
+					sock_remained_size[sn] = sock_remained_size[sn] + 1 - 4;
+				else
+					sock_remained_size[sn] -= 4;
+#endif
+				if(sock_remained_size[sn] > 1514)
+				{
+					close(sn);
+					return SOCKFATAL_PACKLEN;
+				}
+				sock_pack_info[sn] = PACK_FIRST;
+			}
+			if(len < sock_remained_size[sn]) pack_len = len;
+			else pack_len = sock_remained_size[sn];
+			wiz_recv_data(sn,buf,pack_len);
+			break;
+//#if ( _WIZCHIP_ < 5200 )
+		case Sn_MR_IPRAW:
+			if(sock_remained_size[sn] == 0)
+			{
+				wiz_recv_data(sn, head, 6);
+				setSn_CR(sn,Sn_CR_RECV);
+				while(getSn_CR(sn));
+				addr[0] = head[0];
+				addr[1] = head[1];
+				addr[2] = head[2];
+				addr[3] = head[3];
+				sock_remained_size[sn] = head[4];
+				//M20150401 : For Typing Error
+				//sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5];
+				sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[5];
+				sock_pack_info[sn] = PACK_FIRST;
+			}
+			//
+			// Need to packet length check
+			//
+			if(len < sock_remained_size[sn]) pack_len = len;
+			else pack_len = sock_remained_size[sn];
+			wiz_recv_data(sn, buf, pack_len); // data copy.
+			break;
+//#endif
+		default:
+			wiz_recv_ignore(sn, pack_len); // data copy.
+			sock_remained_size[sn] = pack_len;
+			break;
+	}
+	setSn_CR(sn,Sn_CR_RECV);
+	/* wait to process the command... */
+	while(getSn_CR(sn)) ;
+	sock_remained_size[sn] -= pack_len;
+	//M20150601 :
+	//if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01;
+	if(sock_remained_size[sn] != 0)
+	{
+		sock_pack_info[sn] |= PACK_REMAINED;
+#if _WIZCHIP_ == 5300
+		if(pack_len & 0x01) sock_pack_info[sn] |= PACK_FIFOBYTE;
+#endif
+	}
+	else sock_pack_info[sn] = PACK_COMPLETED;
+#if _WIZCHIP_ == 5300
+	pack_len = len;
+#endif
+	//
+	//M20150409 : Explicit Type Casting
+	//return pack_len;
+	return (int32_t)pack_len;
+}
+
+
+int8_t  ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg)
+{
+   uint8_t tmp = 0;
+   CHECK_SOCKNUM();
+   switch(cstype)
+   {
+      case CS_SET_IOMODE:
+         tmp = *((uint8_t*)arg);
+         if(tmp == SOCK_IO_NONBLOCK)  sock_io_mode |= (1<<sn);
+         else if(tmp == SOCK_IO_BLOCK) sock_io_mode &= ~(1<<sn);
+         else return SOCKERR_ARG;
+         break;
+      case CS_GET_IOMODE:
+         //M20140501 : implict type casting -> explict type casting
+         //*((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001;
+         *((uint8_t*)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001);
+         //
+         break;
+      case CS_GET_MAXTXBUF:
+         *((uint16_t*)arg) = getSn_TxMAX(sn);
+         break;
+      case CS_GET_MAXRXBUF:
+         *((uint16_t*)arg) = getSn_RxMAX(sn);
+         break;
+      case CS_CLR_INTERRUPT:
+         if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG;
+         setSn_IR(sn,*(uint8_t*)arg);
+         break;
+      case CS_GET_INTERRUPT:
+         *((uint8_t*)arg) = getSn_IR(sn);
+         break;
+   #if _WIZCHIP_ != 5100
+      case CS_SET_INTMASK:
+         if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG;
+         setSn_IMR(sn,*(uint8_t*)arg);
+         break;
+      case CS_GET_INTMASK:
+         *((uint8_t*)arg) = getSn_IMR(sn);
+         break;
+   #endif
+      default:
+         return SOCKERR_ARG;
+   }
+   return SOCK_OK;
+}
+
+int8_t  setsockopt(uint8_t sn, sockopt_type sotype, void* arg)
+{
+ // M20131220 : Remove warning
+ //uint8_t tmp;
+   CHECK_SOCKNUM();
+   switch(sotype)
+   {
+      case SO_TTL:
+         setSn_TTL(sn,*(uint8_t*)arg);
+         break;
+      case SO_TOS:
+         setSn_TOS(sn,*(uint8_t*)arg);
+         break;
+      case SO_MSS:
+         setSn_MSSR(sn,*(uint16_t*)arg);
+         break;
+      case SO_DESTIP:
+         setSn_DIPR(sn, (uint8_t*)arg);
+         break;
+      case SO_DESTPORT:
+         setSn_DPORT(sn, *(uint16_t*)arg);
+         break;
+#if _WIZCHIP_ != 5100
+      case SO_KEEPALIVESEND:
+         CHECK_SOCKMODE(Sn_MR_TCP);
+         #if _WIZCHIP_ > 5200
+            if(getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT;
+         #endif
+            setSn_CR(sn,Sn_CR_SEND_KEEP);
+            while(getSn_CR(sn) != 0)
+            {
+               // M20131220
+         		//if ((tmp = getSn_IR(sn)) & Sn_IR_TIMEOUT)
+               if (getSn_IR(sn) & Sn_IR_TIMEOUT)
+         		{
+         			setSn_IR(sn, Sn_IR_TIMEOUT);
+                  return SOCKERR_TIMEOUT;
+         		}
+            }
+         break;
+   #if !( (_WIZCHIP_ == 5100) || (_WIZCHIP_ == 5200) )
+      case SO_KEEPALIVEAUTO:
+         CHECK_SOCKMODE(Sn_MR_TCP);
+         setSn_KPALVTR(sn,*(uint8_t*)arg);
+         break;
+   #endif
+#endif
+      default:
+         return SOCKERR_ARG;
+   }
+   return SOCK_OK;
+}
+
+int8_t  getsockopt(uint8_t sn, sockopt_type sotype, void* arg)
+{
+   CHECK_SOCKNUM();
+   switch(sotype)
+   {
+      case SO_FLAG:
+         *(uint8_t*)arg = getSn_MR(sn) & 0xF0;
+         break;
+      case SO_TTL:
+         *(uint8_t*) arg = getSn_TTL(sn);
+         break;
+      case SO_TOS:
+         *(uint8_t*) arg = getSn_TOS(sn);
+         break;
+      case SO_MSS:
+         *(uint16_t*) arg = getSn_MSSR(sn);
+         break;
+      case SO_DESTIP:
+         getSn_DIPR(sn, (uint8_t*)arg);
+         break;
+      case SO_DESTPORT:
+         *(uint16_t*) arg = getSn_DPORT(sn);
+         break;
+   #if _WIZCHIP_ > 5200
+      case SO_KEEPALIVEAUTO:
+         CHECK_SOCKMODE(Sn_MR_TCP);
+         *(uint16_t*) arg = getSn_KPALVTR(sn);
+         break;
+   #endif
+      case SO_SENDBUF:
+         *(uint16_t*) arg = getSn_TX_FSR(sn);
+         break;
+      case SO_RECVBUF:
+         *(uint16_t*) arg = getSn_RX_RSR(sn);
+         break;
+      case SO_STATUS:
+         *(uint8_t*) arg = getSn_SR(sn);
+         break;
+      case SO_REMAINSIZE:
+         if(getSn_MR(sn) & Sn_MR_TCP)
+            *(uint16_t*)arg = getSn_RX_RSR(sn);
+         else
+            *(uint16_t*)arg = sock_remained_size[sn];
+         break;
+      case SO_PACKINFO:
+         //CHECK_SOCKMODE(Sn_MR_TCP);
+#if _WIZCHIP_ != 5300
+         if((getSn_MR(sn) == Sn_MR_TCP))
+             return SOCKERR_SOCKMODE;
+#endif
+         *(uint8_t*)arg = sock_pack_info[sn];
+         break;
+      default:
+         return SOCKERR_SOCKOPT;
+   }
+   return SOCK_OK;
+}
Index: ctrl/firmware/Main/SES/Wiznet/Ethernet/socket.h
===================================================================
--- ctrl/firmware/Main/SES/Wiznet/Ethernet/socket.h	(revision 79)
+++ ctrl/firmware/Main/SES/Wiznet/Ethernet/socket.h	(revision 79)
@@ -0,0 +1,489 @@
+//*****************************************************************************
+//
+//! \file socket.h
+//! \brief SOCKET APIs Header file.
+//! \details SOCKET APIs like as berkeley socket api. 
+//! \version 1.0.2
+//! \date 2013/10/21
+//! \par  Revision history
+//!       <2015/02/05> Notice
+//!        The version history is not updated after this point.
+//!        Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
+//!        >> https://github.com/Wiznet/ioLibrary_Driver
+//!       <2014/05/01> V1.0.2. Refer to M20140501
+//!         1. Modify the comment : SO_REMAINED -> PACK_REMAINED
+//!         2. Add the comment as zero byte udp data reception in getsockopt(). 
+//!       <2013/10/21> 1st Release
+//! \author MidnightCow
+//! \copyright
+//!
+//! Copyright (c)  2013, WIZnet Co., LTD.
+//! All rights reserved.
+//! 
+//! Redistribution and use in source and binary forms, with or without 
+//! modification, are permitted provided that the following conditions 
+//! are met: 
+//! 
+//!     * Redistributions of source code must retain the above copyright 
+//! notice, this list of conditions and the following disclaimer. 
+//!     * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution. 
+//!     * Neither the name of the <ORGANIZATION> nor the names of its 
+//! contributors may be used to endorse or promote products derived 
+//! from this software without specific prior written permission. 
+//! 
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+/**
+ * @defgroup WIZnet_socket_APIs 1. WIZnet socket APIs
+ * @brief WIZnet socket APIs are based on Berkeley socket APIs,  thus it has much similar name and interface.
+ *        But there is a little bit of difference.
+ * @details
+ * <b> Comparison between WIZnet and Berkeley SOCKET APIs </b>
+ * <table>
+ *    <tr>   <td><b>API</b></td> <td><b>WIZnet</b></td> <td><b>Berkeley</b></td>   </tr>
+ *    <tr>   <td>socket()</td> <td>O</td> <td>O</td>   </tr>
+ *    <tr>   <td><b>bind()</b></td> <td>X</td> <td>O</td>   </tr>
+ *    <tr>   <td><b>listen()</b></td> <td>O</td> <td>O</td>   </tr>
+ *    <tr>   <td><b>connect()</b></td> <td>O</td> <td>O</td>   </tr>
+ *    <tr>   <td><b>accept()</b></td> <td>X</td> <td>O</td>   </tr>
+ *    <tr>   <td><b>recv()</b></td> <td>O</td> <td>O</td>    </tr>
+ *    <tr>   <td><b>send()</b></td> <td>O</td> <td>O</td>   </tr>
+ *    <tr>   <td><b>recvfrom()</b></td> <td>O</td> <td>O</td>   </tr>
+ *    <tr>   <td><b>sendto()</b></td> <td>O</td> <td>O</td>    </tr>
+ *    <tr>   <td><b>closesocket()</b></td> <td>O<br>close() & disconnect()</td> <td>O</td>   </tr>
+ * </table>
+ * There are @b bind() and @b accept() functions in @b Berkeley SOCKET API but,
+ * not in @b WIZnet SOCKET API. Because socket() of WIZnet is not only creating a SOCKET but also binding a local port number,
+ * and listen() of WIZnet is not only listening to connection request from client but also accepting the connection request. \n
+ * When you program "TCP SERVER" with Berkeley SOCKET API, you can use only one listen port.
+ * When the listen SOCKET accepts a connection request from a client, it keeps listening.
+ * After accepting the connection request, a new SOCKET is created and the new SOCKET is used in communication with the client. \n
+ * Following figure shows network flow diagram by Berkeley SOCKET API.
+ * @image html Berkeley_SOCKET.jpg "<Berkeley SOCKET API>"
+ * But, When you program "TCP SERVER" with WIZnet SOCKET API, you can use as many as 8 listen SOCKET with same port number. \n
+ * Because there's no accept() in WIZnet SOCKET APIs, when the listen SOCKET accepts a connection request from a client,
+ * it is changed in order to communicate with the client.
+ * And the changed SOCKET is not listening any more and is dedicated for communicating with the client. \n
+ * If there're many listen SOCKET with same listen port number and a client requests a connection,
+ * the SOCKET which has the smallest SOCKET number accepts the request and is changed as communication SOCKET. \n
+ * Following figure shows network flow diagram by WIZnet SOCKET API.
+ * @image html WIZnet_SOCKET.jpg "<WIZnet SOCKET API>"
+ */
+#ifndef _SOCKET_H_
+#define _SOCKET_H_
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "wizchip_conf.h"
+
+#define SOCKET                uint8_t  ///< SOCKET type define for legacy driver
+
+#define SOCK_OK               1        ///< Result is OK about socket process.
+#define SOCK_BUSY             0        ///< Socket is busy on processing the operation. Valid only Non-block IO Mode.
+#define SOCK_FATAL            -1000    ///< Result is fatal error about socket process.
+
+#define SOCK_ERROR            0        
+#define SOCKERR_SOCKNUM       (SOCK_ERROR - 1)     ///< Invalid socket number
+#define SOCKERR_SOCKOPT       (SOCK_ERROR - 2)     ///< Invalid socket option
+#define SOCKERR_SOCKINIT      (SOCK_ERROR - 3)     ///< Socket is not initialized or SIPR is Zero IP address when Sn_MR_TCP
+#define SOCKERR_SOCKCLOSED    (SOCK_ERROR - 4)     ///< Socket unexpectedly closed.
+#define SOCKERR_SOCKMODE      (SOCK_ERROR - 5)     ///< Invalid socket mode for socket operation.
+#define SOCKERR_SOCKFLAG      (SOCK_ERROR - 6)     ///< Invalid socket flag
+#define SOCKERR_SOCKSTATUS    (SOCK_ERROR - 7)     ///< Invalid socket status for socket operation.
+#define SOCKERR_ARG           (SOCK_ERROR - 10)    ///< Invalid argument.
+#define SOCKERR_PORTZERO      (SOCK_ERROR - 11)    ///< Port number is zero
+#define SOCKERR_IPINVALID     (SOCK_ERROR - 12)    ///< Invalid IP address
+#define SOCKERR_TIMEOUT       (SOCK_ERROR - 13)    ///< Timeout occurred
+#define SOCKERR_DATALEN       (SOCK_ERROR - 14)    ///< Data length is zero or greater than buffer max size.
+#define SOCKERR_BUFFER        (SOCK_ERROR - 15)    ///< Socket buffer is not enough for data communication.
+
+#define SOCKFATAL_PACKLEN     (SOCK_FATAL - 1)     ///< Invalid packet length. Fatal Error.
+
+/*
+ * SOCKET FLAG
+ */
+#define SF_ETHER_OWN           (Sn_MR_MFEN)        ///< In @ref Sn_MR_MACRAW, Receive only the packet as broadcast, multicast and own packet
+#define SF_IGMP_VER2           (Sn_MR_MC)          ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE, Select IGMP version 2.   
+#define SF_TCP_NODELAY         (Sn_MR_ND)          ///< In @ref Sn_MR_TCP, Use to nodelayed ack.
+#define SF_MULTI_ENABLE        (Sn_MR_MULTI)       ///< In @ref Sn_MR_UDP, Enable multicast mode.
+
+#if _WIZCHIP_ == 5500
+   #define SF_BROAD_BLOCK         (Sn_MR_BCASTB)   ///< In @ref Sn_MR_UDP or @ref Sn_MR_MACRAW, Block broadcast packet. Valid only in W5500
+   #define SF_MULTI_BLOCK         (Sn_MR_MMB)      ///< In @ref Sn_MR_MACRAW, Block multicast packet. Valid only in W5500
+   #define SF_IPv6_BLOCK          (Sn_MR_MIP6B)    ///< In @ref Sn_MR_MACRAW, Block IPv6 packet. Valid only in W5500
+   #define SF_UNI_BLOCK           (Sn_MR_UCASTB)   ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE. Valid only in W5500
+#endif
+
+//A201505 : For W5300
+#if _WIZCHIP_ == 5300
+   #define SF_TCP_ALIGN		     0x02			   ///< Valid only \ref Sn_MR_TCP and W5300, refer to \ref Sn_MR_ALIGN
+#endif
+
+#define SF_IO_NONBLOCK           0x01              ///< Socket nonblock io mode. It used parameter in \ref socket().
+
+/*
+ * UDP & MACRAW Packet Infomation
+ */
+#define PACK_FIRST               0x80              ///< In Non-TCP packet, It indicates to start receiving a packet. (When W5300, This flag can be applied)
+#define PACK_REMAINED            0x01              ///< In Non-TCP packet, It indicates to remain a packet to be received. (When W5300, This flag can be applied)
+#define PACK_COMPLETED           0x00              ///< In Non-TCP packet, It indicates to complete to receive a packet. (When W5300, This flag can be applied)
+//A20150601 : For Integrating with W5300
+#define PACK_FIFOBYTE            0x02              ///< Valid only W5300, It indicate to have read already the Sn_RX_FIFOR.
+//
+
+/**
+ * @ingroup WIZnet_socket_APIs
+ * @brief Open a socket.
+ * @details Initializes the socket with 'sn' passed as parameter and open.
+ *
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param protocol Protocol type to operate such as TCP, UDP and MACRAW.
+ * @param port Port number to be bined.
+ * @param flag Socket flags as \ref SF_ETHER_OWN, \ref SF_IGMP_VER2, \ref SF_TCP_NODELAY, \ref SF_MULTI_ENABLE, \ref SF_IO_NONBLOCK and so on.\n
+ *             Valid flags only in W5500 : @ref SF_BROAD_BLOCK, @ref SF_MULTI_BLOCK, @ref SF_IPv6_BLOCK, and @ref SF_UNI_BLOCK.
+ * @sa Sn_MR
+ *
+ * @return @b Success : The socket number @b 'sn' passed as parameter\n
+ *         @b Fail    :\n @ref SOCKERR_SOCKNUM     - Invalid socket number\n
+ *                        @ref SOCKERR_SOCKMODE    - Not support socket mode as TCP, UDP, and so on. \n
+ *                        @ref SOCKERR_SOCKFLAG    - Invaild socket flag.
+ */
+int8_t  socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag);
+
+/**
+ * @ingroup WIZnet_socket_APIs
+ * @brief Close a socket.
+ * @details It closes the socket  with @b'sn' passed as parameter.
+ *
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ *
+ * @return @b Success : @ref SOCK_OK \n
+ *         @b Fail    : @ref SOCKERR_SOCKNUM - Invalid socket number
+ */
+int8_t  close(uint8_t sn);
+
+/**
+ * @ingroup WIZnet_socket_APIs
+ * @brief Listen to a connection request from a client.
+ * @details It is listening to a connection request from a client.
+ * If connection request is accepted successfully, the connection is established. Socket sn is used in passive(server) mode.
+ *
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return @b Success : @ref SOCK_OK \n
+ *         @b Fail    :\n @ref SOCKERR_SOCKINIT   - Socket is not initialized \n
+ *                        @ref SOCKERR_SOCKCLOSED - Socket closed unexpectedly.
+ */
+int8_t  listen(uint8_t sn);
+
+/**
+ * @ingroup WIZnet_socket_APIs
+ * @brief Try to connect a server.
+ * @details It requests connection to the server with destination IP address and port number passed as parameter.\n
+ * @note It is valid only in TCP client mode. 
+ *       In block io mode, it does not return until connection is completed.
+ *       In Non-block io mode, it return @ref SOCK_BUSY immediately.
+ *
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes.
+ * @param port Destination port number.
+ *
+ * @return @b Success : @ref SOCK_OK \n
+ * @b Fail    :\n @ref SOCKERR_SOCKNUM   - Invalid socket number\n
+ *                @ref SOCKERR_SOCKMODE  - Invalid socket mode\n
+ *                @ref SOCKERR_SOCKINIT  - Socket is not initialized\n
+ *                @ref SOCKERR_IPINVALID - Wrong server IP address\n
+ *                @ref SOCKERR_PORTZERO  - Server port zero\n
+ *                @ref SOCKERR_TIMEOUT   - Timeout occurred during request connection\n
+ *                @ref SOCK_BUSY         - In non-block io mode, it returned immediately\n
+ */
+int8_t  connect(uint8_t sn, uint8_t * addr, uint16_t port);
+
+/**
+ * @ingroup WIZnet_socket_APIs
+ * @brief Try to disconnect a connection socket.
+ * @details It sends request message to disconnect the TCP socket 'sn' passed as parameter to the server or client.
+ * @note It is valid only in TCP server or client mode. \n
+ *       In block io mode, it does not return until disconnection is completed. \n
+ *       In Non-block io mode, it return @ref SOCK_BUSY immediately. \n
+
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @return @b Success :   @ref SOCK_OK \n
+ *         @b Fail    :\n @ref SOCKERR_SOCKNUM  - Invalid socket number \n
+ *                        @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n
+ *                        @ref SOCKERR_TIMEOUT  - Timeout occurred \n
+ *                        @ref SOCK_BUSY        - Socket is busy.
+ */
+int8_t  disconnect(uint8_t sn);
+
+/**
+ * @ingroup WIZnet_socket_APIs
+ * @brief	Send data to the connected peer in TCP socket.
+ * @details It is used to send outgoing data to the connected socket.
+ * @note    It is valid only in TCP server or client mode. It can't send data greater than socket buffer size. \n
+ *          In block io mode, It doesn't return until data send is completed - socket buffer size is greater than data. \n
+ *          In non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is not enough. \n
+ * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param buf Pointer buffer containing data to be sent.
+ * @param len The byte length of data in buf.
+ * @return	@b Success : The sent data size \n
+ *          @b Fail    : \n @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n
+ *                          @ref SOCKERR_TIMEOUT    - Timeout occurred \n
+ *                          @ref SOCKERR_SOCKMODE 	- Invalid operation in the socket \n
+ *                          @ref SOCKERR_SOCKNUM    - Invalid socket number \n
+ *                          @ref SOCKERR_DATALEN    - zero data length \n
+ *                          @ref SOCK_BUSY          - Socket is busy.
+ */
+int32_t send(uint8_t sn, uint8_t * buf, uint16_t len);
+
+/**
+ * @ingroup WIZnet_socket_APIs
+ * @brief	Receive data from the connected peer.
+ * @details It is used to read incoming data from the connected socket.\n
+ *          It waits for data as much as the application wants to receive.
+ * @note    It is valid only in TCP server or client mode. It can't receive data greater than socket buffer size. \n
+ *          In block io mode, it doesn't return until data reception is completed - data is filled as <I>len</I> in socket buffer. \n
+ *          In non-block io mode, it return @ref SOCK_BUSY immediately when <I>len</I> is greater than data size in socket buffer. \n
+ *
+ * @param sn  Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param buf Pointer buffer to read incoming data.
+ * @param len The max data length of data in buf.
+ * @return	@b Success : The real received data size \n
+ *          @b Fail    :\n
+ *                     @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n
+ *                     @ref SOCKERR_SOCKMODE   - Invalid operation in the socket \n
+ *                     @ref SOCKERR_SOCKNUM    - Invalid socket number \n
+ *                     @ref SOCKERR_DATALEN    - zero data length \n
+ *                     @ref SOCK_BUSY          - Socket is busy.
+ */
+int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len);
+
+/**
+ * @ingroup WIZnet_socket_APIs
+ * @brief	Sends datagram to the peer with destination IP address and port number passed as parameter.
+ * @details It sends datagram of UDP or MACRAW to the peer with destination IP address and port number passed as parameter.\n
+ *          Even if the connectionless socket has been previously connected to a specific address,
+ *          the address and port number parameters override the destination address for that particular datagram only.
+ * @note    In block io mode, It doesn't return until data send is completed - socket buffer size is greater than <I>len</I>.
+ *          In non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is not enough.
+ *
+ * @param sn    Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param buf   Pointer buffer to send outgoing data.
+ * @param len   The byte length of data in buf.
+ * @param addr  Pointer variable of destination IP address. It should be allocated 4 bytes.
+ * @param port  Destination port number.
+ *
+ * @return @b Success : The sent data size \n
+ *         @b Fail    :\n @ref SOCKERR_SOCKNUM     - Invalid socket number \n
+ *                        @ref SOCKERR_SOCKMODE    - Invalid operation in the socket \n
+ *                        @ref SOCKERR_SOCKSTATUS  - Invalid socket status for socket operation \n
+ *                        @ref SOCKERR_DATALEN     - zero data length \n
+ *                        @ref SOCKERR_IPINVALID   - Wrong server IP address\n
+ *                        @ref SOCKERR_PORTZERO    - Server port zero\n
+ *                        @ref SOCKERR_SOCKCLOSED  - Socket unexpectedly closed \n
+ *                        @ref SOCKERR_TIMEOUT     - Timeout occurred \n
+ *                        @ref SOCK_BUSY           - Socket is busy. 
+ */
+int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port);
+
+/**
+ * @ingroup WIZnet_socket_APIs
+ * @brief Receive datagram of UDP or MACRAW
+ * @details This function is an application I/F function which is used to receive the data in other then TCP mode. \n
+ *          This function is used to receive UDP and MAC_RAW mode, and handle the header as well. 
+ *          This function can divide to received the packet data.
+ *          On the MACRAW SOCKET, the addr and port parameters are ignored.
+ * @note    In block io mode, it doesn't return until data reception is completed - data is filled as <I>len</I> in socket buffer
+ *          In non-block io mode, it return @ref SOCK_BUSY immediately when <I>len</I> is greater than data size in socket buffer.
+ *
+ * @param sn   Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
+ * @param buf  Pointer buffer to read incoming data.
+ * @param len  The max data length of data in buf. 
+ *             When the received packet size <= len, receives data as packet sized.
+ *             When others, receives data as len.
+ * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes.
+ *             It is valid only when the first call recvfrom for receiving the packet.
+ *             When it is valid, @ref  packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo).
+ * @param port Pointer variable of destination port number.
+ *             It is valid only when the first call recvform for receiving the packet.
+*             When it is valid, @ref  packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo).
+ *
+ * @return	@b Success : This function return real received data size for success.\n
+ *          @b Fail    : @ref SOCKERR_DATALEN    - zero data length \n
+ *                       @ref SOCKERR_SOCKMODE   - Invalid operation in the socket \n
+ *                       @ref SOCKERR_SOCKNUM    - Invalid socket number \n
+ *                       @ref SOCKBUSY           - Socket is busy.
+ */
+int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port);
+
+
+/////////////////////////////
+// SOCKET CONTROL & OPTION //
+/////////////////////////////
+#define SOCK_IO_BLOCK         0  ///< Socket Block IO Mode in @ref setsockopt().
+#define SOCK_IO_NONBLOCK      1  ///< Socket Non-block IO Mode in @ref setsockopt().
+
+/**
+ * @defgroup DATA_TYPE DATA TYPE
+ */
+
+/**
+ * @ingroup DATA_TYPE
+ * @brief The kind of Socket Interrupt.
+ * @sa Sn_IR, Sn_IMR, setSn_IR(), getSn_IR(), setSn_IMR(), getSn_IMR()
+ */
+typedef enum
+{
+   SIK_CONNECTED     = (1 << 0),    ///< connected
+   SIK_DISCONNECTED  = (1 << 1),    ///< disconnected
+   SIK_RECEIVED      = (1 << 2),    ///< data received
+   SIK_TIMEOUT       = (1 << 3),    ///< timeout occurred
+   SIK_SENT          = (1 << 4),    ///< send ok
+   //M20150410 : Remove the comma of last member
+   //SIK_ALL           = 0x1F,        ///< all interrupt
+   SIK_ALL           = 0x1F         ///< all interrupt
+}sockint_kind;
+
+/**
+ * @ingroup DATA_TYPE
+ * @brief The type of @ref ctlsocket().
+ */
+typedef enum
+{
+   CS_SET_IOMODE,          ///< set socket IO mode with @ref SOCK_IO_BLOCK or @ref SOCK_IO_NONBLOCK
+   CS_GET_IOMODE,          ///< get socket IO mode
+   CS_GET_MAXTXBUF,        ///< get the size of socket buffer allocated in TX memory
+   CS_GET_MAXRXBUF,        ///< get the size of socket buffer allocated in RX memory
+   CS_CLR_INTERRUPT,       ///< clear the interrupt of socket with @ref sockint_kind
+   CS_GET_INTERRUPT,       ///< get the socket interrupt. refer to @ref sockint_kind
+#if _WIZCHIP_ > 5100
+   CS_SET_INTMASK,         ///< set the interrupt mask of socket with @ref sockint_kind, Not supported in W5100
+   CS_GET_INTMASK          ///< get the masked interrupt of socket. refer to @ref sockint_kind, Not supported in W5100
+#endif
+}ctlsock_type;
+
+
+/**
+ * @ingroup DATA_TYPE
+ * @brief The type of socket option in @ref setsockopt() or @ref getsockopt()
+ */ 
+typedef enum
+{
+   SO_FLAG,           ///< Valid only in getsockopt(), For set flag of socket refer to <I>flag</I> in @ref socket().
+   SO_TTL,              ///< Set TTL. @ref Sn_TTL  ( @ref setSn_TTL(), @ref getSn_TTL() )
+   SO_TOS,              ///< Set TOS. @ref Sn_TOS  ( @ref setSn_TOS(), @ref getSn_TOS() )
+   SO_MSS,              ///< Set MSS. @ref Sn_MSSR ( @ref setSn_MSSR(), @ref getSn_MSSR() )
+   SO_DESTIP,           ///< Set the destination IP address. @ref Sn_DIPR ( @ref setSn_DIPR(), @ref getSn_DIPR() )
+   SO_DESTPORT,         ///< Set the destination Port number. @ref Sn_DPORT ( @ref setSn_DPORT(), @ref getSn_DPORT() )
+#if _WIZCHIP_ != 5100   
+   SO_KEEPALIVESEND,    ///< Valid only in setsockopt. Manually send keep-alive packet in TCP mode, Not supported in W5100
+   #if !( (_WIZCHIP_ == 5100) || (_WIZCHIP_ == 5200) )
+      SO_KEEPALIVEAUTO, ///< Set/Get keep-alive auto transmission timer in TCP mode, Not supported in W5100, W5200
+   #endif      
+#endif
+   SO_SENDBUF,          ///< Valid only in getsockopt. Get the free data size of Socekt TX buffer. @ref Sn_TX_FSR, @ref getSn_TX_FSR()
+   SO_RECVBUF,          ///< Valid only in getsockopt. Get the received data size in socket RX buffer. @ref Sn_RX_RSR, @ref getSn_RX_RSR()
+   SO_STATUS,           ///< Valid only in getsockopt. Get the socket status. @ref Sn_SR, @ref getSn_SR()
+   SO_REMAINSIZE,       ///< Valid only in getsockopt. Get the remained packet size in other then TCP mode.
+   SO_PACKINFO          ///< Valid only in getsockopt. Get the packet information as @ref PACK_FIRST, @ref PACK_REMAINED, and @ref PACK_COMPLETED in other then TCP mode.
+}sockopt_type;
+
+/**
+ * @ingroup WIZnet_socket_APIs
+ *  @brief Control socket.
+ *  @details Control IO mode, Interrupt & Mask of socket and get the socket buffer information.
+ *           Refer to @ref ctlsock_type.
+ *  @param sn socket number
+ *  @param cstype type of control socket. refer to @ref ctlsock_type.
+ *  @param arg Data type and value is determined according to @ref ctlsock_type. \n
+ *             <table>
+ *                  <tr> <td> @b cstype </td> <td> @b data type</td><td>@b value</td></tr>
+ *                  <tr> <td> @ref CS_SET_IOMODE \n @ref CS_GET_IOMODE </td> <td> uint8_t </td><td>@ref SOCK_IO_BLOCK @ref SOCK_IO_NONBLOCK</td></tr>
+ *                  <tr> <td> @ref CS_GET_MAXTXBUF \n @ref CS_GET_MAXRXBUF </td> <td> uint16_t </td><td> 0 ~ 16K </td></tr>
+ *                  <tr> <td> @ref CS_CLR_INTERRUPT \n @ref CS_GET_INTERRUPT \n @ref CS_SET_INTMASK \n @ref CS_GET_INTMASK </td> <td> @ref sockint_kind </td><td> @ref SIK_CONNECTED, etc.  </td></tr> 
+ *             </table>
+ *  @return @b Success @ref SOCK_OK \n
+ *          @b fail    @ref SOCKERR_ARG         - Invalid argument\n
+ */
+int8_t  ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg);
+
+/** 
+ * @ingroup WIZnet_socket_APIs
+ *  @brief set socket options
+ *  @details Set socket option like as TTL, MSS, TOS, and so on. Refer to @ref sockopt_type.
+ *               
+ *  @param sn socket number
+ *  @param sotype socket option type. refer to @ref sockopt_type
+ *  @param arg Data type and value is determined according to <I>sotype</I>. \n
+ *             <table>
+ *                  <tr> <td> @b sotype </td> <td> @b data type</td><td>@b value</td></tr> 
+ *                  <tr> <td> @ref SO_TTL </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr>
+ *                  <tr> <td> @ref SO_TOS </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr>
+ *                  <tr> <td> @ref SO_MSS </td> <td> uint16_t </td><td> 0 ~ 65535 </td> </tr>
+ *                  <tr> <td> @ref SO_DESTIP </td> <td> uint8_t[4] </td><td>  </td></tr> 
+ *                  <tr> <td> @ref SO_DESTPORT </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr> 
+ *                  <tr> <td> @ref SO_KEEPALIVESEND </td> <td> null </td><td> null </td></tr> 
+ *                  <tr> <td> @ref SO_KEEPALIVEAUTO </td> <td> uint8_t </td><td> 0 ~ 255 </td></tr> 
+ *             </table>
+ * @return 
+ * - @b Success : @ref SOCK_OK \n
+ * - @b Fail 
+ *  - @ref SOCKERR_SOCKNUM     - Invalid Socket number \n
+ *  - @ref SOCKERR_SOCKMODE    - Invalid socket mode \n
+ *  - @ref SOCKERR_SOCKOPT     - Invalid socket option or its value \n
+ *  - @ref SOCKERR_TIMEOUT     - Timeout occurred when sending keep-alive packet \n
+ */
+int8_t  setsockopt(uint8_t sn, sockopt_type sotype, void* arg);
+
+/** 
+ * @ingroup WIZnet_socket_APIs
+ *  @brief get socket options
+ *  @details Get socket option like as FLAG, TTL, MSS, and so on. Refer to @ref sockopt_type
+ *  @param sn socket number
+ *  @param sotype socket option type. refer to @ref sockopt_type
+ *  @param arg Data type and value is determined according to <I>sotype</I>. \n
+ *             <table>
+ *                  <tr> <td> @b sotype </td> <td>@b data type</td><td>@b value</td></tr>
+ *                  <tr> <td> @ref SO_FLAG </td> <td> uint8_t </td><td> @ref SF_ETHER_OWN, etc... </td> </tr>
+ *                  <tr> <td> @ref SO_TOS </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr>
+ *                  <tr> <td> @ref SO_MSS </td> <td> uint16_t </td><td> 0 ~ 65535 </td> </tr>
+ *                  <tr> <td> @ref SO_DESTIP </td> <td> uint8_t[4] </td><td>  </td></tr> 
+ *                  <tr> <td> @ref SO_DESTPORT </td> <td> uint16_t </td><td>  </td></tr> 
+ *                  <tr> <td> @ref SO_KEEPALIVEAUTO </td> <td> uint8_t </td><td> 0 ~ 255 </td></tr> 
+ *                  <tr> <td> @ref SO_SENDBUF </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr>  
+ *                  <tr> <td> @ref SO_RECVBUF </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr>  
+ *                  <tr> <td> @ref SO_STATUS </td> <td> uint8_t </td><td> @ref SOCK_ESTABLISHED, etc.. </td></tr>  
+ *                  <tr> <td> @ref SO_REMAINSIZE </td> <td> uint16_t </td><td> 0~ 65535 </td></tr>
+ *                  <tr> <td> @ref SO_PACKINFO </td> <td> uint8_t </td><td> @ref PACK_FIRST, etc... </td></tr>
+ *             </table>
+ * @return 
+ * - @b Success : @ref SOCK_OK \n
+ * - @b Fail 
+ *  - @ref SOCKERR_SOCKNUM     - Invalid Socket number \n
+ *  - @ref SOCKERR_SOCKOPT     - Invalid socket option or its value \n
+ *  - @ref SOCKERR_SOCKMODE    - Invalid socket mode \n
+ * @note
+ *   The option as PACK_REMAINED and SO_PACKINFO is valid only in NON-TCP mode and after call @ref recvfrom(). \n
+ *   When SO_PACKINFO value is PACK_FIRST and the return value of recvfrom() is zero, 
+ *   This means the zero byte UDP data(UDP Header only) received.
+  */
+int8_t  getsockopt(uint8_t sn, sockopt_type sotype, void* arg);
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif   // _SOCKET_H_
Index: ctrl/firmware/Main/SES/Wiznet/Ethernet/wizchip_conf.c
===================================================================
--- ctrl/firmware/Main/SES/Wiznet/Ethernet/wizchip_conf.c	(revision 79)
+++ ctrl/firmware/Main/SES/Wiznet/Ethernet/wizchip_conf.c	(revision 79)
@@ -0,0 +1,943 @@
+//****************************************************************************/
+//!
+//! \file wizchip_conf.c
+//! \brief WIZCHIP Config Header File.
+//! \version 1.0.1
+//! \date 2013/10/21
+//! \par  Revision history
+//!       <2015/02/05> Notice
+//!        The version history is not updated after this point.
+//!        Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
+//!        >> https://github.com/Wiznet/ioLibrary_Driver
+//!       <2014/05/01> V1.0.1  Refer to M20140501
+//!        1. Explicit type casting in wizchip_bus_readdata() & wizchip_bus_writedata()
+//            Issued by Mathias ClauBen.
+//!           uint32_t type converts into ptrdiff_t first. And then recoverting it into uint8_t*
+//!           For remove the warning when pointer type size is not 32bit.
+//!           If ptrdiff_t doesn't support in your complier, You should must replace ptrdiff_t into your suitable pointer type.
+//!       <2013/10/21> 1st Release
+//! \author MidnightCow
+//! \copyright
+//!
+//! Copyright (c)  2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//!     * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//!     * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//!     * Neither the name of the <ORGANIZATION> nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************/
+//A20140501 : for use the type - ptrdiff_t
+#include <stddef.h>
+//
+
+#include "spi.h"
+
+#include "wizchip_conf.h"
+
+
+/////////////
+//M20150401 : Remove ; in the default callback function such as wizchip_cris_enter(), wizchip_cs_select() and etc.
+/////////////
+
+/**
+ * @brief Default function to enable interrupt.
+ * @note This function help not to access wrong address. If you do not describe this function or register any functions,
+ * null function is called.
+ */
+//void 	  wizchip_cris_enter(void)           {};
+void 	  wizchip_cris_enter(void)           {}
+
+/**
+ * @brief Default function to disable interrupt.
+ * @note This function help not to access wrong address. If you do not describe this function or register any functions,
+ * null function is called.
+ */
+//void 	  wizchip_cris_exit(void)          {};
+void 	  wizchip_cris_exit(void)          {}
+
+/**
+ * @brief Default function to select chip.
+ * @note This function help not to access wrong address. If you do not describe this function or register any functions,
+ * null function is called.
+ */
+//void 	wizchip_cs_select(void)            {};
+void 	wizchip_cs_select(void)
+{
+	HAL_GPIO_WritePin(ETH_SPI_NSS_GPIO_Port, ETH_SPI_NSS_Pin, GPIO_PIN_RESET);
+}
+
+/**
+ * @brief Default function to deselect chip.
+ * @note This function help not to access wrong address. If you do not describe this function or register any functions,
+ * null function is called.
+ */
+//void 	wizchip_cs_deselect(void)          {};
+void 	wizchip_cs_deselect(void)
+{
+	HAL_GPIO_WritePin(ETH_SPI_NSS_GPIO_Port, ETH_SPI_NSS_Pin, GPIO_PIN_SET);
+}
+
+/**
+ * @brief Default function to read in direct or indirect interface.
+ * @note This function help not to access wrong address. If you do not describe this function or register any functions,
+ * null function is called.
+ */
+ //M20150601 : Rename the function for integrating with W5300
+//uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t *)((ptrdiff_t) AddrSel)); }
+iodata_t wizchip_bus_readdata(uint32_t AddrSel) { return * ((volatile iodata_t *)((ptrdiff_t) AddrSel)); }
+
+/**
+ * @brief Default function to write in direct or indirect interface.
+ * @note This function help not to access wrong address. If you do not describe this function or register any functions,
+ * null function is called.
+ */
+//M20150601 : Rename the function for integrating with W5300
+//void 	wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb)  { *((volatile uint8_t*)((ptrdiff_t)AddrSel)) = wb; }
+void 	wizchip_bus_writedata(uint32_t AddrSel, iodata_t wb)  { *((volatile iodata_t*)((ptrdiff_t)AddrSel)) = wb; }
+
+/**
+ * @brief Default function to read in SPI interface.
+ * @note This function help not to access wrong address. If you do not describe this function or register any functions,
+ * null function is called.
+ */
+//uint8_t wizchip_spi_readbyte(void)        {return 0;};
+uint8_t wizchip_spi_readbyte(void)
+{
+	uint8_t data = 0;
+	while(HAL_SPI_GetState(&hspi2)!=HAL_SPI_STATE_READY);
+	HAL_SPI_Receive(&hspi2, &data, 1, 100);  // Generating Clocking on SCK pin to read exactly one byte
+	return data;
+}
+
+/**
+ * @brief Default function to write in SPI interface.
+ * @note This function help not to access wrong address. If you do not describe this function or register any functions,
+ * null function is called.
+ */
+//void 	wizchip_spi_writebyte(uint8_t wb) {};
+void 	wizchip_spi_writebyte(uint8_t wb)
+{
+	while(HAL_SPI_GetState(&hspi2) != HAL_SPI_STATE_READY);
+	HAL_SPI_Transmit(&hspi2, &wb, 1, 100);  // Generating Clocking on SCK pin to read exactly one byte
+}
+
+/**
+ * @brief Default function to burst read in SPI interface.
+ * @note This function help not to access wrong address. If you do not describe this function or register any functions,
+ * null function is called.
+ */
+//void 	wizchip_spi_readburst(uint8_t* pBuf, uint16_t len) 	{};
+void 	wizchip_spi_readburst(uint8_t* pBuf, uint16_t len)
+{
+	while(HAL_SPI_GetState(&hspi2) != HAL_SPI_STATE_READY);
+	HAL_SPI_Receive(&hspi2, pBuf, len, 100);
+}
+
+/**
+ * @brief Default function to burst write in SPI interface.
+ * @note This function help not to access wrong address. If you do not describe this function or register any functions,
+ * null function is called.
+ */
+//void 	wizchip_spi_writeburst(uint8_t* pBuf, uint16_t len) {};
+void 	wizchip_spi_writeburst(uint8_t* pBuf, uint16_t len)
+{
+	while(HAL_SPI_GetState(&hspi2) != HAL_SPI_STATE_READY);
+	HAL_SPI_Transmit(&hspi2, pBuf, len, 100);
+	/*while(HAL_SPI_GetState(&hspi2) != HAL_SPI_STATE_READY &&
+		  HAL_DMA_GetState(hspi2.hdmarx) != HAL_DMA_STATE_READY && HAL_DMA_GetState(hspi2.hdmatx) != HAL_DMA_STATE_READY);
+
+	HAL_SPI_Transmit_DMA(&hspi2, pBuf, len);
+
+	while (HAL_DMA_GetState(hspi2.hdmarx) == HAL_DMA_STATE_BUSY|| HAL_DMA_GetState(hspi2.hdmarx) == HAL_DMA_STATE_RESET);
+	while (HAL_DMA_GetState(hspi2.hdmatx) == HAL_DMA_STATE_BUSY|| HAL_DMA_GetState(hspi2.hdmatx) == HAL_DMA_STATE_RESET);
+
+	return;*/
+}
+
+/**
+ * @\ref _WIZCHIP instance
+ */
+//
+//M20150401 : For a compiler didnot support a member of structure
+//            Replace the assignment of struct members with the assingment of array
+//
+
+_WIZCHIP  WIZCHIP =
+{
+      .id                  = _WIZCHIP_ID_,
+      .if_mode             = _WIZCHIP_IO_MODE_,
+      .CRIS._enter         = wizchip_cris_enter,
+      .CRIS._exit          = wizchip_cris_exit,
+      .CS._select          = wizchip_cs_select,
+      .CS._deselect        = wizchip_cs_deselect,
+      .IF.SPI._read_byte   = wizchip_spi_readbyte,
+      .IF.SPI._write_byte  = wizchip_spi_writebyte,
+	  .IF.SPI._read_burst   = wizchip_spi_readburst,
+	  .IF.SPI._write_burst  = wizchip_spi_writeburst,
+};
+
+/*_WIZCHIP  WIZCHIP =
+{
+    _WIZCHIP_IO_MODE_,
+    _WIZCHIP_ID_ ,
+    {
+        wizchip_cris_enter,
+        wizchip_cris_exit
+    },
+    {
+        wizchip_cs_select,
+        wizchip_cs_deselect
+    },
+    {
+        {
+            //M20150601 : Rename the function
+            //wizchip_bus_readbyte,
+            //wizchip_bus_writebyte
+            wizchip_bus_readdata,
+            wizchip_bus_writedata
+        },
+
+    }
+};*/
+
+
+static uint8_t    _DNS_[4];      // DNS server ip address
+static dhcp_mode  _DHCP_;        // DHCP mode
+
+void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void))
+{
+   if(!cris_en || !cris_ex)
+   {
+      WIZCHIP.CRIS._enter = wizchip_cris_enter;
+      WIZCHIP.CRIS._exit  = wizchip_cris_exit;
+   }
+   else
+   {
+      WIZCHIP.CRIS._enter = cris_en;
+      WIZCHIP.CRIS._exit  = cris_ex;
+   }
+}
+
+void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void))
+{
+   if(!cs_sel || !cs_desel)
+   {
+      WIZCHIP.CS._select   = wizchip_cs_select;
+      WIZCHIP.CS._deselect = wizchip_cs_deselect;
+   }
+   else
+   {
+      WIZCHIP.CS._select   = cs_sel;
+      WIZCHIP.CS._deselect = cs_desel;
+   }
+}
+
+//M20150515 : For integrating with W5300
+//void reg_wizchip_bus_cbfunc(uint8_t(*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb))
+void reg_wizchip_bus_cbfunc(iodata_t(*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, iodata_t wb))
+{
+   while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_BUS_));
+   //M20150601 : Rename call back function for integrating with W5300
+   /*
+   if(!bus_rb || !bus_wb)
+   {
+      WIZCHIP.IF.BUS._read_byte   = wizchip_bus_readbyte;
+      WIZCHIP.IF.BUS._write_byte  = wizchip_bus_writebyte;
+   }
+   else
+   {
+      WIZCHIP.IF.BUS._read_byte   = bus_rb;
+      WIZCHIP.IF.BUS._write_byte  = bus_wb;
+   }
+   */
+   if(!bus_rb || !bus_wb)
+   {
+      WIZCHIP.IF.BUS._read_data   = wizchip_bus_readdata;
+      WIZCHIP.IF.BUS._write_data  = wizchip_bus_writedata;
+   }
+   else
+   {
+      WIZCHIP.IF.BUS._read_data   = bus_rb;
+      WIZCHIP.IF.BUS._write_data  = bus_wb;
+   }
+}
+
+void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb))
+{
+   while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_));
+
+   if(!spi_rb || !spi_wb)
+   {
+      WIZCHIP.IF.SPI._read_byte   = wizchip_spi_readbyte;
+      WIZCHIP.IF.SPI._write_byte  = wizchip_spi_writebyte;
+   }
+   else
+   {
+      WIZCHIP.IF.SPI._read_byte   = spi_rb;
+      WIZCHIP.IF.SPI._write_byte  = spi_wb;
+   }
+}
+
+// 20140626 Eric Added for SPI burst operations
+void reg_wizchip_spiburst_cbfunc(void (*spi_rb)(uint8_t* pBuf, uint16_t len), void (*spi_wb)(uint8_t* pBuf, uint16_t len))
+{
+   while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_));
+
+   if(!spi_rb || !spi_wb)
+   {
+      WIZCHIP.IF.SPI._read_burst   = wizchip_spi_readburst;
+      WIZCHIP.IF.SPI._write_burst  = wizchip_spi_writeburst;
+   }
+   else
+   {
+      WIZCHIP.IF.SPI._read_burst   = spi_rb;
+      WIZCHIP.IF.SPI._write_burst  = spi_wb;
+   }
+}
+
+int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg)
+{
+#if	_WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500
+   uint8_t tmp = 0;
+#endif
+   uint8_t* ptmp[2] = {0,0};
+   switch(cwtype)
+   {
+      case CW_RESET_WIZCHIP:
+         wizchip_sw_reset();
+         break;
+      case CW_INIT_WIZCHIP:
+         if(arg != 0)
+         {
+            ptmp[0] = (uint8_t*)arg;
+            ptmp[1] = ptmp[0] + _WIZCHIP_SOCK_NUM_;
+         }
+         return wizchip_init(ptmp[0], ptmp[1]);
+      case CW_CLR_INTERRUPT:
+         wizchip_clrinterrupt(*((intr_kind*)arg));
+         break;
+      case CW_GET_INTERRUPT:
+        *((intr_kind*)arg) = wizchip_getinterrupt();
+         break;
+      case CW_SET_INTRMASK:
+         wizchip_setinterruptmask(*((intr_kind*)arg));
+         break;
+      case CW_GET_INTRMASK:
+         *((intr_kind*)arg) = wizchip_getinterruptmask();
+         break;
+   //M20150601 : This can be supported by W5200, W5500
+   //#if _WIZCHIP_ > W5100
+   #if (_WIZCHIP_ == W5200 || _WIZCHIP_ == W5500)
+      case CW_SET_INTRTIME:
+         setINTLEVEL(*(uint16_t*)arg);
+         break;
+      case CW_GET_INTRTIME:
+         *(uint16_t*)arg = getINTLEVEL();
+         break;
+   #endif
+      case CW_GET_ID:
+         ((uint8_t*)arg)[0] = WIZCHIP.id[0];
+         ((uint8_t*)arg)[1] = WIZCHIP.id[1];
+         ((uint8_t*)arg)[2] = WIZCHIP.id[2];
+         ((uint8_t*)arg)[3] = WIZCHIP.id[3];
+         ((uint8_t*)arg)[4] = WIZCHIP.id[4];
+         ((uint8_t*)arg)[5] = WIZCHIP.id[5];
+         ((uint8_t*)arg)[6] = 0;
+         break;
+   #if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500
+      case CW_RESET_PHY:
+         wizphy_reset();
+         break;
+      case CW_SET_PHYCONF:
+         wizphy_setphyconf((wiz_PhyConf*)arg);
+         break;
+      case CW_GET_PHYCONF:
+         wizphy_getphyconf((wiz_PhyConf*)arg);
+         break;
+      case CW_GET_PHYSTATUS:
+         break;
+      case CW_SET_PHYPOWMODE:
+         return wizphy_setphypmode(*(uint8_t*)arg);
+   #endif
+   #if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500
+      case CW_GET_PHYPOWMODE:
+         tmp = wizphy_getphypmode();
+         if((int8_t)tmp == -1) return -1;
+         *(uint8_t*)arg = tmp;
+         break;
+      case CW_GET_PHYLINK:
+         tmp = wizphy_getphylink();
+         if((int8_t)tmp == -1) return -1;
+         *(uint8_t*)arg = tmp;
+         break;
+   #endif
+      default:
+         return -1;
+   }
+   return 0;
+}
+
+
+int8_t ctlnetwork(ctlnetwork_type cntype, void* arg)
+{
+
+   switch(cntype)
+   {
+      case CN_SET_NETINFO:
+         wizchip_setnetinfo((wiz_NetInfo*)arg);
+         break;
+      case CN_GET_NETINFO:
+         wizchip_getnetinfo((wiz_NetInfo*)arg);
+         break;
+      case CN_SET_NETMODE:
+         return wizchip_setnetmode(*(netmode_type*)arg);
+      case CN_GET_NETMODE:
+         *(netmode_type*)arg = wizchip_getnetmode();
+         break;
+      case CN_SET_TIMEOUT:
+         wizchip_settimeout((wiz_NetTimeout*)arg);
+         break;
+      case CN_GET_TIMEOUT:
+         wizchip_gettimeout((wiz_NetTimeout*)arg);
+         break;
+      default:
+         return -1;
+   }
+   return 0;
+}
+
+void wizchip_sw_reset(void)
+{
+   uint8_t gw[4], sn[4], sip[4];
+   uint8_t mac[6];
+//A20150601
+#if _WIZCHIP_IO_MODE_  == _WIZCHIP_IO_MODE_BUS_INDIR_
+   uint16_t mr = (uint16_t)getMR();
+   setMR(mr | MR_IND);
+#endif
+//
+   getSHAR(mac);
+   getGAR(gw);  getSUBR(sn);  getSIPR(sip);
+   setMR(MR_RST);
+   getMR(); // for delay
+//A2015051 : For indirect bus mode
+#if _WIZCHIP_IO_MODE_  == _WIZCHIP_IO_MODE_BUS_INDIR_
+   setMR(mr | MR_IND);
+#endif
+//
+   setSHAR(mac);
+   setGAR(gw);
+   setSUBR(sn);
+   setSIPR(sip);
+}
+
+int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize)
+{
+   int8_t i;
+#if _WIZCHIP_ < W5200
+   int8_t j;
+#endif
+   int8_t tmp = 0;
+   wizchip_sw_reset();
+   if(txsize)
+   {
+      tmp = 0;
+//M20150601 : For integrating with W5300
+#if _WIZCHIP_ == W5300
+		for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
+		{
+			if(txsize[i] > 64) return -1;   //No use 64KB even if W5300 support max 64KB memory allocation
+			tmp += txsize[i];
+			if(tmp > 128) return -1;
+		}
+		if(tmp % 8) return -1;
+#else
+		for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
+		{
+			tmp += txsize[i];
+
+#if _WIZCHIP_ < W5200	//2016.10.28 peter add condition for w5100 and w5100s
+			if(tmp > 8) return -1;
+#else
+			if(tmp > 16) return -1;
+#endif
+		}
+#endif
+		for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
+		{
+#if _WIZCHIP_ < W5200	//2016.10.28 peter add condition for w5100
+			j = 0;
+			while((txsize[i] >> j != 1)&&(txsize[i] !=0)){j++;}
+			setSn_TXBUF_SIZE(i, j);
+#else
+			setSn_TXBUF_SIZE(i, txsize[i]);
+#endif
+		}
+   }
+
+   if(rxsize)
+   {
+      tmp = 0;
+#if _WIZCHIP_ == W5300
+      for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
+		{
+			if(rxsize[i] > 64) return -1;   //No use 64KB even if W5300 support max 64KB memory allocation
+			tmp += rxsize[i];
+			if(tmp > 128) return -1;
+		}
+		if(tmp % 8) return -1;
+#else
+		for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
+		{
+			tmp += rxsize[i];
+#if _WIZCHIP_ < W5200	//2016.10.28 peter add condition for w5100 and w5100s
+			if(tmp > 8) return -1;
+#else
+			if(tmp > 16) return -1;
+#endif
+		}
+#endif
+		for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
+		{
+#if _WIZCHIP_ < W5200	// add condition for w5100
+			j = 0;
+			while((rxsize[i] >> j != 1)&&(txsize[i] !=0)){j++;}
+			setSn_RXBUF_SIZE(i, j);
+#else
+			setSn_RXBUF_SIZE(i, rxsize[i]);
+#endif
+		}
+   }
+   return 0;
+}
+
+void wizchip_clrinterrupt(intr_kind intr)
+{
+   uint8_t ir  = (uint8_t)intr;
+   uint8_t sir = (uint8_t)((uint16_t)intr >> 8);
+#if _WIZCHIP_ < W5500
+   ir |= (1<<4); // IK_WOL
+#endif
+#if _WIZCHIP_ == W5200
+   ir |= (1 << 6);
+#endif
+
+#if _WIZCHIP_ < W5200
+   sir &= 0x0F;
+#endif
+
+#if _WIZCHIP_ <= W5100S
+   ir |= sir;
+   setIR(ir);
+//A20150601 : For integrating with W5300
+#elif _WIZCHIP_ == W5300
+   setIR( ((((uint16_t)ir) << 8) | (((uint16_t)sir) & 0x00FF)) );
+#else
+   setIR(ir);
+//M20200227 : For clear
+   //setSIR(sir);
+   for(ir=0; ir<8; ir++){
+       if(sir & (0x01 <<ir) ) setSn_IR(ir, 0xff);
+   }
+
+#endif
+}
+
+intr_kind wizchip_getinterrupt(void)
+{
+   uint8_t ir  = 0;
+   uint8_t sir = 0;
+   uint16_t ret = 0;
+#if _WIZCHIP_ <= W5100S
+   ir = getIR();
+   sir = ir & 0x0F;
+//A20150601 : For integrating with W5300
+#elif _WIZCHIP_  == W5300
+   ret = getIR();
+   ir = (uint8_t)(ret >> 8);
+   sir = (uint8_t)ret;
+#else
+   ir  = getIR();
+   sir = getSIR();
+#endif
+
+//M20150601 : For Integrating with W5300
+//#if _WIZCHIP_ < W5500
+#if _WIZCHIP_ < W5200
+   ir &= ~(1<<4); // IK_WOL
+#endif
+#if _WIZCHIP_ == W5200
+   ir &= ~(1 << 6);
+#endif
+  ret = sir;
+  ret = (ret << 8) + ir;
+  return (intr_kind)ret;
+}
+
+void wizchip_setinterruptmask(intr_kind intr)
+{
+   uint8_t imr  = (uint8_t)intr;
+   uint8_t simr = (uint8_t)((uint16_t)intr >> 8);
+#if _WIZCHIP_ < W5500
+   imr &= ~(1<<4); // IK_WOL
+#endif
+#if _WIZCHIP_ == W5200
+   imr &= ~(1 << 6);
+#endif
+
+#if _WIZCHIP_ < W5200
+   simr &= 0x0F;
+   imr |= simr;
+   setIMR(imr);
+//A20150601 : For integrating with W5300
+#elif _WIZCHIP_ == W5300
+   setIMR( ((((uint16_t)imr) << 8) | (((uint16_t)simr) & 0x00FF)) );
+#else
+   setIMR(imr);
+   setSIMR(simr);
+#endif
+}
+
+intr_kind wizchip_getinterruptmask(void)
+{
+   uint8_t imr  = 0;
+   uint8_t simr = 0;
+   uint16_t ret = 0;
+#if _WIZCHIP_ < W5200
+   imr  = getIMR();
+   simr = imr & 0x0F;
+//A20150601 : For integrating with W5300
+#elif _WIZCHIP_ == W5300
+   ret = getIMR();
+   imr = (uint8_t)(ret >> 8);
+   simr = (uint8_t)ret;
+#else
+   imr  = getIMR();
+   simr = getSIMR();
+#endif
+
+#if _WIZCHIP_ < W5500
+   imr &= ~(1<<4); // IK_WOL
+#endif
+#if _WIZCHIP_ == W5200
+   imr &= ~(1 << 6);  // IK_DEST_UNREACH
+#endif
+  ret = simr;
+  ret = (ret << 8) + imr;
+  return (intr_kind)ret;
+}
+
+int8_t wizphy_getphylink(void)
+{
+   int8_t tmp = PHY_LINK_OFF;
+#if _WIZCHIP_ == W5100S
+   if(getPHYSR() & PHYSR_LNK)
+	   tmp = PHY_LINK_ON;
+#elif   _WIZCHIP_ == W5200
+   if(getPHYSTATUS() & PHYSTATUS_LINK)
+      tmp = PHY_LINK_ON;
+#elif _WIZCHIP_ == W5500
+   if(getPHYCFGR() & PHYCFGR_LNK_ON)
+      tmp = PHY_LINK_ON;
+
+#else
+   tmp = -1;
+#endif
+   return tmp;
+}
+
+#if _WIZCHIP_ > W5100
+
+int8_t wizphy_getphypmode(void)
+{
+   int8_t tmp = 0;
+   #if   _WIZCHIP_ == W5200
+      if(getPHYSTATUS() & PHYSTATUS_POWERDOWN)
+         tmp = PHY_POWER_DOWN;
+      else
+         tmp = PHY_POWER_NORM;
+   #elif _WIZCHIP_ == 5500
+      if((getPHYCFGR() & PHYCFGR_OPMDC_ALLA) == PHYCFGR_OPMDC_PDOWN)
+         tmp = PHY_POWER_DOWN;
+      else
+         tmp = PHY_POWER_NORM;
+   #else
+      tmp = -1;
+   #endif
+   return tmp;
+}
+#endif
+
+#if _WIZCHIP_ == W5100S
+void wizphy_reset(void)
+{
+	uint16_t tmp = wiz_mdio_read(PHYMDIO_BMCR);
+	tmp |= BMCR_RESET;
+	wiz_mdio_write(PHYMDIO_BMCR, tmp);
+	while(wiz_mdio_read(PHYMDIO_BMCR)&BMCR_RESET){}
+}
+
+void wizphy_setphyconf(wiz_PhyConf* phyconf)
+{
+   uint16_t tmp = wiz_mdio_read(PHYMDIO_BMCR);
+   if(phyconf->mode == PHY_MODE_AUTONEGO)
+      tmp |= BMCR_AUTONEGO;
+   else
+   {
+	  tmp &= ~BMCR_AUTONEGO;
+      if(phyconf->duplex == PHY_DUPLEX_FULL)
+      {
+    	  tmp |= BMCR_DUP;
+      }
+      else
+      {
+    	  tmp &= ~BMCR_DUP;
+      }
+      if(phyconf->speed == PHY_SPEED_100)
+      {
+    	  tmp |= BMCR_SPEED;
+      }
+      else
+      {
+    	  tmp &= ~BMCR_SPEED;
+      }
+   }
+   wiz_mdio_write(PHYMDIO_BMCR, tmp);
+}
+
+void wizphy_getphyconf(wiz_PhyConf* phyconf)
+{
+   uint16_t tmp = 0;
+   tmp = wiz_mdio_read(PHYMDIO_BMCR);
+   phyconf->by   = PHY_CONFBY_SW;
+   if(tmp & BMCR_AUTONEGO)
+   {
+	   phyconf->mode = PHY_MODE_AUTONEGO;
+   }
+   else
+   {
+	   phyconf->mode = PHY_MODE_MANUAL;
+	   if(tmp&BMCR_DUP) phyconf->duplex = PHY_DUPLEX_FULL;
+	   else phyconf->duplex = PHY_DUPLEX_HALF;
+	   if(tmp&BMCR_SPEED) phyconf->speed = PHY_SPEED_100;
+	   else phyconf->speed = PHY_SPEED_10;
+   }
+}
+
+int8_t wizphy_setphypmode(uint8_t pmode)
+{
+   uint16_t tmp = 0;
+   tmp = wiz_mdio_read(PHYMDIO_BMCR);
+   if( pmode == PHY_POWER_DOWN)
+   {
+      tmp |= BMCR_PWDN;
+   }
+   else
+   {
+	   tmp &= ~BMCR_PWDN;
+   }
+   wiz_mdio_write(PHYMDIO_BMCR, tmp);
+   tmp = wiz_mdio_read(PHYMDIO_BMCR);
+   if( pmode == PHY_POWER_DOWN)
+   {
+      if(tmp & BMCR_PWDN) return 0;
+   }
+   else
+   {
+      if((tmp & BMCR_PWDN) != BMCR_PWDN) return 0;
+   }
+   return -1;
+}
+
+#endif
+#if _WIZCHIP_ == W5500
+void wizphy_reset(void)
+{
+   uint8_t tmp = getPHYCFGR();
+   tmp &= PHYCFGR_RST;
+   setPHYCFGR(tmp);
+   tmp = getPHYCFGR();
+   tmp |= ~PHYCFGR_RST;
+   setPHYCFGR(tmp);
+}
+
+void wizphy_setphyconf(wiz_PhyConf* phyconf)
+{
+   uint8_t tmp = 0;
+   if(phyconf->by == PHY_CONFBY_SW)
+      tmp |= PHYCFGR_OPMD;
+   else
+      tmp &= ~PHYCFGR_OPMD;
+   if(phyconf->mode == PHY_MODE_AUTONEGO)
+      tmp |= PHYCFGR_OPMDC_ALLA;
+   else
+   {
+      if(phyconf->duplex == PHY_DUPLEX_FULL)
+      {
+         if(phyconf->speed == PHY_SPEED_100)
+            tmp |= PHYCFGR_OPMDC_100F;
+         else
+            tmp |= PHYCFGR_OPMDC_10F;
+      }
+      else
+      {
+         if(phyconf->speed == PHY_SPEED_100)
+            tmp |= PHYCFGR_OPMDC_100H;
+         else
+            tmp |= PHYCFGR_OPMDC_10H;
+      }
+   }
+   setPHYCFGR(tmp);
+   wizphy_reset();
+}
+
+void wizphy_getphyconf(wiz_PhyConf* phyconf)
+{
+   uint8_t tmp = 0;
+   tmp = getPHYCFGR();
+   phyconf->by   = (tmp & PHYCFGR_OPMD) ? PHY_CONFBY_SW : PHY_CONFBY_HW;
+   switch(tmp & PHYCFGR_OPMDC_ALLA)
+   {
+      case PHYCFGR_OPMDC_ALLA:
+      case PHYCFGR_OPMDC_100FA:
+         phyconf->mode = PHY_MODE_AUTONEGO;
+         break;
+      default:
+         phyconf->mode = PHY_MODE_MANUAL;
+         break;
+   }
+   switch(tmp & PHYCFGR_OPMDC_ALLA)
+   {
+      case PHYCFGR_OPMDC_100FA:
+      case PHYCFGR_OPMDC_100F:
+      case PHYCFGR_OPMDC_100H:
+         phyconf->speed = PHY_SPEED_100;
+         break;
+      default:
+         phyconf->speed = PHY_SPEED_10;
+         break;
+   }
+   switch(tmp & PHYCFGR_OPMDC_ALLA)
+   {
+      case PHYCFGR_OPMDC_100FA:
+      case PHYCFGR_OPMDC_100F:
+      case PHYCFGR_OPMDC_10F:
+         phyconf->duplex = PHY_DUPLEX_FULL;
+         break;
+      default:
+         phyconf->duplex = PHY_DUPLEX_HALF;
+         break;
+   }
+}
+
+void wizphy_getphystat(wiz_PhyConf* phyconf)
+{
+   uint8_t tmp = getPHYCFGR();
+   phyconf->duplex = (tmp & PHYCFGR_DPX_FULL) ? PHY_DUPLEX_FULL : PHY_DUPLEX_HALF;
+   phyconf->speed  = (tmp & PHYCFGR_SPD_100) ? PHY_SPEED_100 : PHY_SPEED_10;
+}
+
+int8_t wizphy_setphypmode(uint8_t pmode)
+{
+   uint8_t tmp = 0;
+   tmp = getPHYCFGR();
+   if((tmp & PHYCFGR_OPMD)== 0) return -1;
+   tmp &= ~PHYCFGR_OPMDC_ALLA;
+   if( pmode == PHY_POWER_DOWN)
+      tmp |= PHYCFGR_OPMDC_PDOWN;
+   else
+      tmp |= PHYCFGR_OPMDC_ALLA;
+   setPHYCFGR(tmp);
+   wizphy_reset();
+   tmp = getPHYCFGR();
+   if( pmode == PHY_POWER_DOWN)
+   {
+      if(tmp & PHYCFGR_OPMDC_PDOWN) return 0;
+   }
+   else
+   {
+      if(tmp & PHYCFGR_OPMDC_ALLA) return 0;
+   }
+   return -1;
+}
+#endif
+
+
+void wizchip_setnetinfo(wiz_NetInfo* pnetinfo)
+{
+   setSHAR(pnetinfo->mac);
+   setGAR(pnetinfo->gw);
+   setSUBR(pnetinfo->sn);
+   setSIPR(pnetinfo->ip);
+   _DNS_[0] = pnetinfo->dns[0];
+   _DNS_[1] = pnetinfo->dns[1];
+   _DNS_[2] = pnetinfo->dns[2];
+   _DNS_[3] = pnetinfo->dns[3];
+   _DHCP_   = pnetinfo->dhcp;
+}
+
+void wizchip_getnetinfo(wiz_NetInfo* pnetinfo)
+{
+   getSHAR(pnetinfo->mac);
+   getGAR(pnetinfo->gw);
+   getSUBR(pnetinfo->sn);
+   getSIPR(pnetinfo->ip);
+   pnetinfo->dns[0]= _DNS_[0];
+   pnetinfo->dns[1]= _DNS_[1];
+   pnetinfo->dns[2]= _DNS_[2];
+   pnetinfo->dns[3]= _DNS_[3];
+   pnetinfo->dhcp  = _DHCP_;
+}
+
+int8_t wizchip_setnetmode(netmode_type netmode)
+{
+   uint8_t tmp = 0;
+#if _WIZCHIP_ != W5500
+   if(netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK)) return -1;
+#else
+   if(netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK | NM_FORCEARP)) return -1;
+#endif
+   tmp = getMR();
+   tmp |= (uint8_t)netmode;
+   setMR(tmp);
+   return 0;
+}
+
+netmode_type wizchip_getnetmode(void)
+{
+   return (netmode_type) getMR();
+}
+
+void wizchip_settimeout(wiz_NetTimeout* nettime)
+{
+   setRCR(nettime->retry_cnt);
+   setRTR(nettime->time_100us);
+}
+
+void wizchip_gettimeout(wiz_NetTimeout* nettime)
+{
+   nettime->retry_cnt = getRCR();
+   nettime->time_100us = getRTR();
+}
Index: ctrl/firmware/Main/SES/Wiznet/Ethernet/wizchip_conf.h
===================================================================
--- ctrl/firmware/Main/SES/Wiznet/Ethernet/wizchip_conf.h	(revision 79)
+++ ctrl/firmware/Main/SES/Wiznet/Ethernet/wizchip_conf.h	(revision 79)
@@ -0,0 +1,661 @@
+//*****************************************************************************
+//
+//! \file wizchip_conf.h
+//! \brief WIZCHIP Config Header File.
+//! \version 1.0.0
+//! \date 2013/10/21
+//! \par  Revision history
+//!       <2015/02/05> Notice
+//!        The version history is not updated after this point.
+//!        Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
+//!        >> https://github.com/Wiznet/ioLibrary_Driver
+//!       <2013/10/21> 1st Release
+//! \author MidnightCow
+//! \copyright
+//!
+//! Copyright (c)  2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//!     * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//!     * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//!     * Neither the name of the <ORGANIZATION> nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+/**
+ * @defgroup extra_functions 2. WIZnet Extra Functions
+ *
+ * @brief These functions is optional function. It could be replaced at WIZCHIP I/O function because they were made by WIZCHIP I/O functions.
+ * @details There are functions of configuring WIZCHIP, network, interrupt, phy, network information and timer. \n
+ *
+ */
+
+#ifndef  _WIZCHIP_CONF_H_
+#define  _WIZCHIP_CONF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+/**
+ * @brief Select WIZCHIP.
+ * @todo You should select one, \b W5100, \b W5100S, \b W5200, \b W5300, \b W5500 or etc. \n\n
+ *       ex> <code> #define \_WIZCHIP_      W5500 </code>
+ */
+
+#define W5100						5100
+#define W5100S						5100+5
+#define W5200						5200
+#define W5300						5300
+#define W5500						5500
+
+#ifndef _WIZCHIP_
+#define _WIZCHIP_                      W5100S   // W5100, W5100S, W5200, W5300, W5500
+#endif
+
+#define _WIZCHIP_IO_MODE_NONE_         0x0000
+#define _WIZCHIP_IO_MODE_BUS_          0x0100 /**< Bus interface mode */
+#define _WIZCHIP_IO_MODE_SPI_          0x0200 /**< SPI interface mode */
+//#define _WIZCHIP_IO_MODE_IIC_          0x0400
+//#define _WIZCHIP_IO_MODE_SDIO_         0x0800
+// Add to
+//
+
+#define _WIZCHIP_IO_MODE_BUS_DIR_      (_WIZCHIP_IO_MODE_BUS_ + 1) /**< BUS interface mode for direct  */
+#define _WIZCHIP_IO_MODE_BUS_INDIR_    (_WIZCHIP_IO_MODE_BUS_ + 2) /**< BUS interface mode for indirect */
+
+#define _WIZCHIP_IO_MODE_SPI_VDM_      (_WIZCHIP_IO_MODE_SPI_ + 1) /**< SPI interface mode for variable length data*/
+#define _WIZCHIP_IO_MODE_SPI_FDM_      (_WIZCHIP_IO_MODE_SPI_ + 2) /**< SPI interface mode for fixed length data mode*/
+#define _WIZCHIP_IO_MODE_SPI_5500_     (_WIZCHIP_IO_MODE_SPI_ + 3) /**< SPI interface mode for fixed length data mode*/
+
+#if   (_WIZCHIP_ == W5100)
+   #define _WIZCHIP_ID_                "W5100\0"
+/**
+ * @brief Define interface mode.
+ * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_
+ */
+// 	#define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_BUS_DIR_
+//	#define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_BUS_INDIR_
+   	   #define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_SPI_
+
+//A20150601 : Define the unit of IO DATA.
+   typedef   uint8_t   iodata_t;
+//A20150401 : Indclude W5100.h file
+   #include "W5100/w5100.h"
+
+#elif (_WIZCHIP_ == W5100S)
+#define _WIZCHIP_ID_                "W5100S\0"
+/**
+* @brief Define interface mode.
+* @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_
+*/
+//	#define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_BUS_INDIR_
+	//#define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_SPI_5500_
+	#define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_SPI_
+
+//A20150601 : Define the unit of IO DATA.
+   typedef   uint8_t   iodata_t;
+//A20150401 : Indclude W5100.h file
+	#include "W5100S/w5100s.h"
+#elif (_WIZCHIP_ == W5200)
+   #define _WIZCHIP_ID_                "W5200\0"
+/**
+ * @brief Define interface mode.
+ * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ or @ref \	_WIZCHIP_IO_MODE_BUS_INDIR_
+ */
+#ifndef _WIZCHIP_IO_MODE_
+// #define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_BUS_INDIR_
+   #define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_SPI_
+#endif
+//A20150601 : Define the unit of IO DATA.
+   typedef   uint8_t   iodata_t;
+   #include "W5200/w5200.h"
+#elif (_WIZCHIP_ == W5500)
+  #define _WIZCHIP_ID_                 "W5500\0"
+
+/**
+ * @brief Define interface mode. \n
+ * @todo Should select interface mode as chip.
+ *        - @ref \_WIZCHIP_IO_MODE_SPI_ \n
+ *          -@ref \_WIZCHIP_IO_MODE_SPI_VDM_ : Valid only in @ref \_WIZCHIP_ == W5500 \n
+ *          -@ref \_WIZCHIP_IO_MODE_SPI_FDM_ : Valid only in @ref \_WIZCHIP_ == W5500 \n
+ *        - @ref \_WIZCHIP_IO_MODE_BUS_ \n
+ *          - @ref \_WIZCHIP_IO_MODE_BUS_DIR_ \n
+ *          - @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ \n
+ *        - Others will be defined in future. \n\n
+ *        ex> <code> #define \_WIZCHIP_IO_MODE_ \_WIZCHIP_IO_MODE_SPI_VDM_ </code>
+ *
+ */
+#ifndef _WIZCHIP_IO_MODE_
+   //#define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_SPI_FDM_
+   #define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_SPI_VDM_
+#endif
+//A20150601 : Define the unit of IO DATA.
+   typedef   uint8_t   iodata_t;
+   #include "W5500/w5500.h"
+#elif ( _WIZCHIP_ == W5300)
+   #define _WIZCHIP_ID_                 "W5300\0"
+/**
+ * @brief Define interface mode.
+ * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_
+ */
+#ifndef _WIZCHIP_IO_MODE_
+   #define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_BUS_DIR_
+// #define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_BUS_INDIR_
+#endif
+
+//A20150601 : Define the unit and bus width of IO DATA.
+   /**
+    * @brief Select the data width 8 or 16 bits.
+    * @todo you should select the bus width. Select one of 8 or 16.
+    */
+   #ifndef _WIZCHIP_IO_BUS_WIDTH_
+   #define _WIZCHIP_IO_BUS_WIDTH_       16  // 8
+   #endif
+   #if _WIZCHIP_IO_BUS_WIDTH_ == 8
+      typedef   uint8_t   iodata_t;
+   #elif _WIZCHIP_IO_BUS_WIDTH_ == 16
+      typedef   uint16_t   iodata_t;
+   #else
+      #error "Unknown _WIZCHIP_IO_BUS_WIDTH_. It should be 8 or 16."
+   #endif
+//
+   #include "W5300/w5300.h"
+#else
+   #error "Unknown defined _WIZCHIP_. You should define one of 5100, 5200, and 5500 !!!"
+#endif
+
+#ifndef _WIZCHIP_IO_MODE_
+   #error "Undefined _WIZCHIP_IO_MODE_. You should define it !!!"
+#endif
+
+/**
+ * @brief Define I/O base address when BUS IF mode.
+ * @todo Should re-define it to fit your system when BUS IF Mode (@ref \_WIZCHIP_IO_MODE_BUS_,
+ *       @ref \_WIZCHIP_IO_MODE_BUS_DIR_, @ref \_WIZCHIP_IO_MODE_BUS_INDIR_). \n\n
+ *       ex> <code> #define \_WIZCHIP_IO_BASE_      0x00008000 </code>
+ */
+#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_
+//	#define _WIZCHIP_IO_BASE_				0x60000000	// for 5100S IND
+	#define _WIZCHIP_IO_BASE_				0x68000000	// for W5300
+#elif _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_
+	#define _WIZCHIP_IO_BASE_				0x00000000	// for 5100S SPI
+#endif
+
+#ifndef _WIZCHIP_IO_BASE_
+#define _WIZCHIP_IO_BASE_              0x00000000  // 0x8000
+#endif
+
+//M20150401 : Typing Error
+//#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS
+#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_
+   #ifndef _WIZCHIP_IO_BASE_
+      #error "You should be define _WIZCHIP_IO_BASE to fit your system memory map."
+   #endif
+#endif
+
+#if _WIZCHIP_ >= W5200
+   #define _WIZCHIP_SOCK_NUM_   8   ///< The count of independant socket of @b WIZCHIP
+#else
+   #define _WIZCHIP_SOCK_NUM_   4   ///< The count of independant socket of @b WIZCHIP
+#endif
+
+
+/********************************************************
+* WIZCHIP BASIC IF functions for SPI, SDIO, I2C , ETC.
+*********************************************************/
+/**
+ * @ingroup DATA_TYPE
+ * @brief The set of callback functions for W5500:@ref WIZCHIP_IO_Functions W5200:@ref WIZCHIP_IO_Functions_W5200
+ */
+typedef struct __WIZCHIP
+{
+   uint16_t  if_mode;               ///< host interface mode
+   uint8_t   id[8];                 ///< @b WIZCHIP ID such as @b 5100, @b 5100S, @b 5200, @b 5500, and so on.
+   /**
+    * The set of critical section callback func.
+    */
+   struct _CRIS
+   {
+      void (*_enter)  (void);       ///< crtical section enter
+      void (*_exit) (void);         ///< critial section exit
+   }CRIS;
+   /**
+    *  The set of @ref \_WIZCHIP_ select control callback func.
+    */
+   struct _CS
+   {
+      void (*_select)  (void);      ///< @ref \_WIZCHIP_ selected
+      void (*_deselect)(void);      ///< @ref \_WIZCHIP_ deselected
+   }CS;
+   /**
+    * The set of interface IO callback func.
+    */
+   union _IF
+   {
+      /**
+       * For BUS interface IO
+       */
+      //M20156501 : Modify the function name for integrating with W5300
+      //struct
+      //{
+      //   uint8_t  (*_read_byte)  (uint32_t AddrSel);
+      //   void     (*_write_byte) (uint32_t AddrSel, uint8_t wb);
+      //}BUS;
+      struct
+      {
+         iodata_t  (*_read_data)   (uint32_t AddrSel);
+         void      (*_write_data)  (uint32_t AddrSel, iodata_t wb);
+      }BUS;
+
+      /**
+       * For SPI interface IO
+       */
+      struct
+      {
+         uint8_t (*_read_byte)   (void);
+         void    (*_write_byte)  (uint8_t wb);
+         void    (*_read_burst)  (uint8_t* pBuf, uint16_t len);
+         void    (*_write_burst) (uint8_t* pBuf, uint16_t len);
+      }SPI;
+      // To be added
+      //
+   }IF;
+}_WIZCHIP;
+
+extern _WIZCHIP  WIZCHIP;
+
+/**
+ * @ingroup DATA_TYPE
+ *  WIZCHIP control type enumration used in @ref ctlwizchip().
+ */
+typedef enum
+{
+   CW_RESET_WIZCHIP,   ///< Resets WIZCHIP by softly
+   CW_INIT_WIZCHIP,    ///< Initializes to WIZCHIP with SOCKET buffer size 2 or 1 dimension array typed uint8_t.
+   CW_GET_INTERRUPT,   ///< Get Interrupt status of WIZCHIP
+   CW_CLR_INTERRUPT,   ///< Clears interrupt
+   CW_SET_INTRMASK,    ///< Masks interrupt
+   CW_GET_INTRMASK,    ///< Get interrupt mask
+   CW_SET_INTRTIME,    ///< Set interval time between the current and next interrupt.
+   CW_GET_INTRTIME,    ///< Set interval time between the current and next interrupt.
+   CW_GET_ID,          ///< Gets WIZCHIP name.
+
+//D20150601 : For no modification your application code
+//#if _WIZCHIP_ ==  W5500
+   CW_RESET_PHY,       ///< Resets internal PHY. Valid Only W5500
+   CW_SET_PHYCONF,     ///< When PHY configured by internal register, PHY operation mode (Manual/Auto, 10/100, Half/Full). Valid Only W5000
+   CW_GET_PHYCONF,     ///< Get PHY operation mode in internal register. Valid Only W5500
+   CW_GET_PHYSTATUS,   ///< Get real PHY status on operating. Valid Only W5500
+   CW_SET_PHYPOWMODE,  ///< Set PHY power mode as normal and down when PHYSTATUS.OPMD == 1. Valid Only W5500
+//#endif
+//D20150601 : For no modification your application code
+//#if _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500
+   CW_GET_PHYPOWMODE,  ///< Get PHY Power mode as down or normal, Valid Only W5100, W5200
+   CW_GET_PHYLINK      ///< Get PHY Link status, Valid Only W5100, W5200
+//#endif
+}ctlwizchip_type;
+
+/**
+ * @ingroup DATA_TYPE
+ *  Network control type enumration used in @ref ctlnetwork().
+ */
+typedef enum
+{
+   CN_SET_NETINFO,  ///< Set Network with @ref wiz_NetInfo
+   CN_GET_NETINFO,  ///< Get Network with @ref wiz_NetInfo
+   CN_SET_NETMODE,  ///< Set network mode as WOL, PPPoE, Ping Block, and Force ARP mode
+   CN_GET_NETMODE,  ///< Get network mode as WOL, PPPoE, Ping Block, and Force ARP mode
+   CN_SET_TIMEOUT,  ///< Set network timeout as retry count and time.
+   CN_GET_TIMEOUT,  ///< Get network timeout as retry count and time.
+}ctlnetwork_type;
+
+/**
+ * @ingroup DATA_TYPE
+ *  Interrupt kind when CW_SET_INTRRUPT, CW_GET_INTERRUPT, CW_SET_INTRMASK
+ *  and CW_GET_INTRMASK is used in @ref ctlnetwork().
+ *  It can be used with OR operation.
+ */
+typedef enum
+{
+#if   _WIZCHIP_ == W5500
+   IK_WOL               = (1 << 4),   ///< Wake On Lan by receiving the magic packet. Valid in W500.
+#elif _WIZCHIP_ == W5300
+   IK_FMTU              = (1 << 4),   ///< Received a ICMP message (Fragment MTU)
+#endif
+
+   IK_PPPOE_TERMINATED  = (1 << 5),   ///< PPPoE Disconnected
+
+#if _WIZCHIP_ != W5200
+   IK_DEST_UNREACH      = (1 << 6),   ///< Destination IP & Port Unreachable, No use in W5200
+#endif
+
+   IK_IP_CONFLICT       = (1 << 7),   ///< IP conflict occurred
+
+   IK_SOCK_0            = (1 << 8),   ///< Socket 0 interrupt
+   IK_SOCK_1            = (1 << 9),   ///< Socket 1 interrupt
+   IK_SOCK_2            = (1 << 10),  ///< Socket 2 interrupt
+   IK_SOCK_3            = (1 << 11),  ///< Socket 3 interrupt
+#if _WIZCHIP_ > W5100S
+   IK_SOCK_4            = (1 << 12),  ///< Socket 4 interrupt, No use in 5100
+   IK_SOCK_5            = (1 << 13),  ///< Socket 5 interrupt, No use in 5100
+   IK_SOCK_6            = (1 << 14),  ///< Socket 6 interrupt, No use in 5100
+   IK_SOCK_7            = (1 << 15),  ///< Socket 7 interrupt, No use in 5100
+#endif
+
+#if _WIZCHIP_ > W5100S
+   IK_SOCK_ALL          = (0xFF << 8) ///< All Socket interrupt
+#else
+   IK_SOCK_ALL          = (0x0F << 8) ///< All Socket interrupt
+#endif
+}intr_kind;
+
+#define PHY_CONFBY_HW            0     ///< Configured PHY operation mode by HW pin
+#define PHY_CONFBY_SW            1     ///< Configured PHY operation mode by SW register
+#define PHY_MODE_MANUAL          0     ///< Configured PHY operation mode with user setting.
+#define PHY_MODE_AUTONEGO        1     ///< Configured PHY operation mode with auto-negotiation
+#define PHY_SPEED_10             0     ///< Link Speed 10
+#define PHY_SPEED_100            1     ///< Link Speed 100
+#define PHY_DUPLEX_HALF          0     ///< Link Half-Duplex
+#define PHY_DUPLEX_FULL          1     ///< Link Full-Duplex
+#define PHY_LINK_OFF             0     ///< Link Off
+#define PHY_LINK_ON              1     ///< Link On
+#define PHY_POWER_NORM           0     ///< PHY power normal mode
+#define PHY_POWER_DOWN           1     ///< PHY power down mode
+
+
+#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500
+/**
+ * @ingroup DATA_TYPE
+ *  It configures PHY configuration when CW_SET PHYCONF or CW_GET_PHYCONF in W5500,
+ *  and it indicates the real PHY status configured by HW or SW in all WIZCHIP. \n
+ *  Valid only in W5500.
+ */
+typedef struct wiz_PhyConf_t
+{
+      uint8_t by;       ///< set by @ref PHY_CONFBY_HW or @ref PHY_CONFBY_SW
+      uint8_t mode;     ///< set by @ref PHY_MODE_MANUAL or @ref PHY_MODE_AUTONEGO
+      uint8_t speed;    ///< set by @ref PHY_SPEED_10 or @ref PHY_SPEED_100
+      uint8_t duplex;   ///< set by @ref PHY_DUPLEX_HALF @ref PHY_DUPLEX_FULL
+      //uint8_t power;  ///< set by @ref PHY_POWER_NORM or @ref PHY_POWER_DOWN
+      //uint8_t link;   ///< Valid only in CW_GET_PHYSTATUS. set by @ref PHY_LINK_ON or PHY_DUPLEX_OFF
+   }wiz_PhyConf;
+#endif
+
+/**
+ * @ingroup DATA_TYPE
+ *  It used in setting dhcp_mode of @ref wiz_NetInfo.
+ */
+typedef enum
+{
+   NETINFO_STATIC = 1,    ///< Static IP configuration by manually.
+   NETINFO_DHCP           ///< Dynamic IP configruation from a DHCP sever
+}dhcp_mode;
+
+/**
+ * @ingroup DATA_TYPE
+ *  Network Information for WIZCHIP
+ */
+typedef struct wiz_NetInfo_t
+{
+   uint8_t mac[6];  ///< Source Mac Address
+   uint8_t ip[4];   ///< Source IP Address
+   uint8_t sn[4];   ///< Subnet Mask
+   uint8_t gw[4];   ///< Gateway IP Address
+   uint8_t dns[4];  ///< DNS server IP Address
+   dhcp_mode dhcp;  ///< 1 - Static, 2 - DHCP
+}wiz_NetInfo;
+
+/**
+ * @ingroup DATA_TYPE
+ *  Network mode
+ */
+typedef enum
+{
+#if _WIZCHIP_ == W5500
+   NM_FORCEARP    = (1<<1),  ///< Force to APP send whenever udp data is sent. Valid only in W5500
+#endif
+   NM_WAKEONLAN   = (1<<5),  ///< Wake On Lan
+   NM_PINGBLOCK   = (1<<4),  ///< Block ping-request
+   NM_PPPOE       = (1<<3),  ///< PPPoE mode
+}netmode_type;
+
+/**
+ * @ingroup DATA_TYPE
+ *  Used in CN_SET_TIMEOUT or CN_GET_TIMEOUT of @ref ctlwizchip() for timeout configruation.
+ */
+typedef struct wiz_NetTimeout_t
+{
+   uint8_t  retry_cnt;     ///< retry count
+   uint16_t time_100us;    ///< time unit 100us
+}wiz_NetTimeout;
+
+/**
+ *@brief Registers call back function for critical section of I/O functions such as
+ *\ref WIZCHIP_READ, @ref WIZCHIP_WRITE, @ref WIZCHIP_READ_BUF and @ref WIZCHIP_WRITE_BUF.
+ *@param cris_en : callback function for critical section enter.
+ *@param cris_ex : callback function for critical section exit.
+ *@todo Describe @ref WIZCHIP_CRITICAL_ENTER and @ref WIZCHIP_CRITICAL_EXIT marco or register your functions.
+ *@note If you do not describe or register, default functions(@ref wizchip_cris_enter & @ref wizchip_cris_exit) is called.
+ */
+void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void));
+
+
+/**
+ *@brief Registers call back function for WIZCHIP select & deselect.
+ *@param cs_sel : callback function for WIZCHIP select
+ *@param cs_desel : callback fucntion for WIZCHIP deselect
+ *@todo Describe @ref wizchip_cs_select and @ref wizchip_cs_deselect function or register your functions.
+ *@note If you do not describe or register, null function is called.
+ */
+void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void));
+
+/**
+ *@brief Registers call back function for bus interface.
+ *@param bus_rb   : callback function to read byte data using system bus
+ *@param bus_wb   : callback function to write byte data using system bus
+ *@todo Describe @ref wizchip_bus_readbyte and @ref wizchip_bus_writebyte function
+ *or register your functions.
+ *@note If you do not describe or register, null function is called.
+ */
+//M20150601 : For integrating with W5300
+//void reg_wizchip_bus_cbfunc(uint8_t (*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb));
+void reg_wizchip_bus_cbfunc(iodata_t (*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, iodata_t wb));
+
+/**
+ *@brief Registers call back function for SPI interface.
+ *@param spi_rb : callback function to read byte using SPI
+ *@param spi_wb : callback function to write byte using SPI
+ *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte function
+ *or register your functions.
+ *@note If you do not describe or register, null function is called.
+ */
+void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb));
+
+/**
+ *@brief Registers call back function for SPI interface.
+ *@param spi_rb : callback function to burst read using SPI
+ *@param spi_wb : callback function to burst write using SPI
+ *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte function
+ *or register your functions.
+ *@note If you do not describe or register, null function is called.
+ */
+void reg_wizchip_spiburst_cbfunc(void (*spi_rb)(uint8_t* pBuf, uint16_t len), void (*spi_wb)(uint8_t* pBuf, uint16_t len));
+
+/**
+ * @ingroup extra_functions
+ * @brief Controls to the WIZCHIP.
+ * @details Resets WIZCHIP & internal PHY, Configures PHY mode, Monitor PHY(Link,Speed,Half/Full/Auto),
+ * controls interrupt & mask and so on.
+ * @param cwtype : Decides to the control type
+ * @param arg : arg type is dependent on cwtype.
+ * @return  0 : Success \n
+ *         -1 : Fail because of invalid \ref ctlwizchip_type or unsupported \ref ctlwizchip_type in WIZCHIP
+ */
+int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg);
+
+/**
+ * @ingroup extra_functions
+ * @brief Controls to network.
+ * @details Controls to network environment, mode, timeout and so on.
+ * @param cntype : Input. Decides to the control type
+ * @param arg : Inout. arg type is dependent on cntype.
+ * @return -1 : Fail because of invalid \ref ctlnetwork_type or unsupported \ref ctlnetwork_type in WIZCHIP \n
+ *          0 : Success
+ */
+int8_t ctlnetwork(ctlnetwork_type cntype, void* arg);
+
+
+/*
+ * The following functions are implemented for internal use.
+ * but You can call these functions for code size reduction instead of ctlwizchip() and ctlnetwork().
+ */
+
+/**
+ * @ingroup extra_functions
+ * @brief Reset WIZCHIP by softly.
+ */
+void   wizchip_sw_reset(void);
+
+/**
+ * @ingroup extra_functions
+ * @brief Initializes WIZCHIP with socket buffer size
+ * @param txsize Socket tx buffer sizes. If null, initialized the default size 2KB.
+ * @param rxsize Socket rx buffer sizes. If null, initialized the default size 2KB.
+ * @return 0 : succcess \n
+ *        -1 : fail. Invalid buffer size
+ */
+int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize);
+
+/**
+ * @ingroup extra_functions
+ * @brief Clear Interrupt of WIZCHIP.
+ * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t.
+ */
+void wizchip_clrinterrupt(intr_kind intr);
+
+/**
+ * @ingroup extra_functions
+ * @brief Get Interrupt of WIZCHIP.
+ * @return @ref intr_kind value operated OR. It can type-cast to uint16_t.
+ */
+intr_kind wizchip_getinterrupt(void);
+
+/**
+ * @ingroup extra_functions
+ * @brief Mask or Unmask Interrupt of WIZCHIP.
+ * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t.
+ */
+void wizchip_setinterruptmask(intr_kind intr);
+
+/**
+ * @ingroup extra_functions
+ * @brief Get Interrupt mask of WIZCHIP.
+ * @return : The operated OR vaule of @ref intr_kind. It can type-cast to uint16_t.
+ */
+intr_kind wizchip_getinterruptmask(void);
+
+//todo
+#if _WIZCHIP_ > W5100
+   int8_t wizphy_getphylink(void);              ///< get the link status of phy in WIZCHIP. No use in W5100
+   int8_t wizphy_getphypmode(void);             ///< get the power mode of PHY in WIZCHIP. No use in W5100
+#endif
+
+#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500
+   void   wizphy_reset(void);                   ///< Reset phy. Vailid only in W5500
+/**
+ * @ingroup extra_functions
+ * @brief Set the phy information for WIZCHIP without power mode
+ * @param phyconf : @ref wiz_PhyConf
+ */
+   void   wizphy_setphyconf(wiz_PhyConf* phyconf);
+ /**
+ * @ingroup extra_functions
+ * @brief Get phy configuration information.
+ * @param phyconf : @ref wiz_PhyConf
+ */
+   void   wizphy_getphyconf(wiz_PhyConf* phyconf);
+ /**
+ * @ingroup extra_functions
+ * @brief Get phy status.
+ * @param phyconf : @ref wiz_PhyConf
+ */
+   void   wizphy_getphystat(wiz_PhyConf* phyconf);
+ /**
+ * @ingroup extra_functions
+ * @brief set the power mode of phy inside WIZCHIP. Refer to @ref PHYCFGR in W5500, @ref PHYSTATUS in W5200
+ * @param pmode Settig value of power down mode.
+ */
+   int8_t wizphy_setphypmode(uint8_t pmode);
+#endif
+
+/**
+* @ingroup extra_functions
+ * @brief Set the network information for WIZCHIP
+ * @param pnetinfo : @ref wizNetInfo
+ */
+void wizchip_setnetinfo(wiz_NetInfo* pnetinfo);
+
+/**
+ * @ingroup extra_functions
+ * @brief Get the network information for WIZCHIP
+ * @param pnetinfo : @ref wizNetInfo
+ */
+void wizchip_getnetinfo(wiz_NetInfo* pnetinfo);
+
+/**
+ * @ingroup extra_functions
+ * @brief Set the network mode such WOL, PPPoE, Ping Block, and etc.
+ * @param pnetinfo Value of network mode. Refer to @ref netmode_type.
+ */
+int8_t wizchip_setnetmode(netmode_type netmode);
+
+/**
+ * @ingroup extra_functions
+ * @brief Get the network mode such WOL, PPPoE, Ping Block, and etc.
+ * @return Value of network mode. Refer to @ref netmode_type.
+ */
+netmode_type wizchip_getnetmode(void);
+
+/**
+ * @ingroup extra_functions
+ * @brief Set retry time value(@ref _RTR_) and retry count(@ref _RCR_).
+ * @details @ref _RTR_ configures the retransmission timeout period and @ref _RCR_ configures the number of time of retransmission.
+ * @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref wiz_NetTimeout.
+ */
+void wizchip_settimeout(wiz_NetTimeout* nettime);
+
+/**
+ * @ingroup extra_functions
+ * @brief Get retry time value(@ref _RTR_) and retry count(@ref _RCR_).
+ * @details @ref _RTR_ configures the retransmission timeout period and @ref _RCR_ configures the number of time of retransmission.
+ * @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref wiz_NetTimeout.
+ */
+void wizchip_gettimeout(wiz_NetTimeout* nettime);
+#ifdef __cplusplus
+ }
+#endif
+
+#endif   // _WIZCHIP_CONF_H_
Index: ctrl/firmware/Main/SES/Wiznet/Internet/DHCP/dhcp.c
===================================================================
--- ctrl/firmware/Main/SES/Wiznet/Internet/DHCP/dhcp.c	(revision 79)
+++ ctrl/firmware/Main/SES/Wiznet/Internet/DHCP/dhcp.c	(revision 79)
@@ -0,0 +1,1036 @@
+//*****************************************************************************
+//
+//! \file dhcp.c
+//! \brief DHCP APIs implement file.
+//! \details Processing DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE.
+//! \version 1.1.1
+//! \date 2019/10/08
+//! \par  Revision history
+//!       <2019/10/08> compare DHCP server ip address
+//!       <2013/11/18> 1st Release
+//!       <2012/12/20> V1.1.0
+//!         1. Optimize code
+//!         2. Add reg_dhcp_cbfunc()
+//!         3. Add DHCP_stop()
+//!         4. Integrate check_DHCP_state() & DHCP_run() to DHCP_run()
+//!         5. Don't care system endian
+//!         6. Add comments
+//!       <2012/12/26> V1.1.1
+//!         1. Modify variable declaration: dhcp_tick_1s is declared volatile for code optimization
+//! \author Eric Jung & MidnightCow
+//! \copyright
+//!
+//! Copyright (c)  2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//!     * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//!     * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//!     * Neither the name of the <ORGANIZATION> nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+#include "socket.h"
+#include "dhcp.h"
+
+/* If you want to display debug & processing message, Define _DHCP_DEBUG_ in dhcp.h */
+
+#ifdef _DHCP_DEBUG_
+   #include <stdio.h>
+#endif
+
+/* DHCP state machine. */
+#define STATE_DHCP_INIT          0        ///< Initialize
+#define STATE_DHCP_DISCOVER      1        ///< send DISCOVER and wait OFFER
+#define STATE_DHCP_REQUEST       2        ///< send REQEUST and wait ACK or NACK
+#define STATE_DHCP_LEASED        3        ///< ReceiveD ACK and IP leased
+#define STATE_DHCP_REREQUEST     4        ///< send REQUEST for maintaining leased IP
+#define STATE_DHCP_RELEASE       5        ///< No use
+#define STATE_DHCP_STOP          6        ///< Stop processing DHCP
+
+#define DHCP_FLAGSBROADCAST      0x8000   ///< The broadcast value of flags in @ref RIP_MSG
+#define DHCP_FLAGSUNICAST        0x0000   ///< The unicast   value of flags in @ref RIP_MSG
+
+/* DHCP message OP code */
+#define DHCP_BOOTREQUEST         1        ///< Request Message used in op of @ref RIP_MSG
+#define DHCP_BOOTREPLY           2        ///< Reply Message used i op of @ref RIP_MSG
+
+/* DHCP message type */
+#define DHCP_DISCOVER            1        ///< DISCOVER message in OPT of @ref RIP_MSG
+#define DHCP_OFFER               2        ///< OFFER message in OPT of @ref RIP_MSG
+#define DHCP_REQUEST             3        ///< REQUEST message in OPT of @ref RIP_MSG
+#define DHCP_DECLINE             4        ///< DECLINE message in OPT of @ref RIP_MSG
+#define DHCP_ACK                 5        ///< ACK message in OPT of @ref RIP_MSG
+#define DHCP_NAK                 6        ///< NACK message in OPT of @ref RIP_MSG
+#define DHCP_RELEASE             7        ///< RELEASE message in OPT of @ref RIP_MSG. No use
+#define DHCP_INFORM              8        ///< INFORM message in OPT of @ref RIP_MSG. No use
+
+#define DHCP_HTYPE10MB           1        ///< Used in type of @ref RIP_MSG
+#define DHCP_HTYPE100MB          2        ///< Used in type of @ref RIP_MSG
+
+#define DHCP_HLENETHERNET        6        ///< Used in hlen of @ref RIP_MSG
+#define DHCP_HOPS                0        ///< Used in hops of @ref RIP_MSG
+#define DHCP_SECS                0        ///< Used in secs of @ref RIP_MSG
+
+#define INFINITE_LEASETIME       0xffffffff	///< Infinite lease time
+
+#define OPT_SIZE                 312               /// Max OPT size of @ref RIP_MSG
+#define RIP_MSG_SIZE             (236+OPT_SIZE)    /// Max size of @ref RIP_MSG
+
+/*
+ * @brief DHCP option and value (cf. RFC1533)
+ */
+enum
+{
+   padOption               = 0,
+   subnetMask              = 1,
+   timerOffset             = 2,
+   routersOnSubnet         = 3,
+   timeServer              = 4,
+   nameServer              = 5,
+   dns                     = 6,
+   logServer               = 7,
+   cookieServer            = 8,
+   lprServer               = 9,
+   impressServer           = 10,
+   resourceLocationServer	= 11,
+   hostName                = 12,
+   bootFileSize            = 13,
+   meritDumpFile           = 14,
+   domainName              = 15,
+   swapServer              = 16,
+   rootPath                = 17,
+   extentionsPath          = 18,
+   IPforwarding            = 19,
+   nonLocalSourceRouting   = 20,
+   policyFilter            = 21,
+   maxDgramReasmSize       = 22,
+   defaultIPTTL            = 23,
+   pathMTUagingTimeout     = 24,
+   pathMTUplateauTable     = 25,
+   ifMTU                   = 26,
+   allSubnetsLocal         = 27,
+   broadcastAddr           = 28,
+   performMaskDiscovery    = 29,
+   maskSupplier            = 30,
+   performRouterDiscovery  = 31,
+   routerSolicitationAddr  = 32,
+   staticRoute             = 33,
+   trailerEncapsulation    = 34,
+   arpCacheTimeout         = 35,
+   ethernetEncapsulation   = 36,
+   tcpDefaultTTL           = 37,
+   tcpKeepaliveInterval    = 38,
+   tcpKeepaliveGarbage     = 39,
+   nisDomainName           = 40,
+   nisServers              = 41,
+   ntpServers              = 42,
+   vendorSpecificInfo      = 43,
+   netBIOSnameServer       = 44,
+   netBIOSdgramDistServer	= 45,
+   netBIOSnodeType         = 46,
+   netBIOSscope            = 47,
+   xFontServer             = 48,
+   xDisplayManager         = 49,
+   dhcpRequestedIPaddr     = 50,
+   dhcpIPaddrLeaseTime     = 51,
+   dhcpOptionOverload      = 52,
+   dhcpMessageType         = 53,
+   dhcpServerIdentifier    = 54,
+   dhcpParamRequest        = 55,
+   dhcpMsg                 = 56,
+   dhcpMaxMsgSize          = 57,
+   dhcpT1value             = 58,
+   dhcpT2value             = 59,
+   dhcpClassIdentifier     = 60,
+   dhcpClientIdentifier    = 61,
+   endOption               = 255
+};
+
+/*
+ * @brief DHCP message format
+ */
+typedef struct {
+	uint8_t  op;            ///< @ref DHCP_BOOTREQUEST or @ref DHCP_BOOTREPLY
+	uint8_t  htype;         ///< @ref DHCP_HTYPE10MB or @ref DHCP_HTYPE100MB
+	uint8_t  hlen;          ///< @ref DHCP_HLENETHERNET
+	uint8_t  hops;          ///< @ref DHCP_HOPS
+	uint32_t xid;           ///< @ref DHCP_XID  This increase one every DHCP transaction.
+	uint16_t secs;          ///< @ref DHCP_SECS
+	uint16_t flags;         ///< @ref DHCP_FLAGSBROADCAST or @ref DHCP_FLAGSUNICAST
+	uint8_t  ciaddr[4];     ///< @ref Request IP to DHCP sever
+	uint8_t  yiaddr[4];     ///< @ref Offered IP from DHCP server
+	uint8_t  siaddr[4];     ///< No use
+	uint8_t  giaddr[4];     ///< No use
+	uint8_t  chaddr[16];    ///< DHCP client 6bytes MAC address. Others is filled to zero
+	uint8_t  sname[64];     ///< No use
+	uint8_t  file[128];     ///< No use
+	uint8_t  OPT[OPT_SIZE]; ///< Option
+} RIP_MSG;
+
+
+
+uint8_t DHCP_SOCKET;                      // Socket number for DHCP
+
+uint8_t DHCP_SIP[4];                      // DHCP Server IP address
+uint8_t DHCP_REAL_SIP[4];                 // For extract my DHCP server in a few DHCP server
+
+// Network information from DHCP Server
+uint8_t OLD_allocated_ip[4]   = {0, };    // Previous IP address
+uint8_t DHCP_allocated_ip[4]  = {0, };    // IP address from DHCP
+uint8_t DHCP_allocated_gw[4]  = {0, };    // Gateway address from DHCP
+uint8_t DHCP_allocated_sn[4]  = {0, };    // Subnet mask from DHCP
+uint8_t DHCP_allocated_dns[4] = {0, };    // DNS address from DHCP
+
+
+int8_t   dhcp_state        = STATE_DHCP_INIT;   // DHCP state
+int8_t   dhcp_retry_count  = 0;
+
+uint32_t dhcp_lease_time   			= INFINITE_LEASETIME;
+volatile uint32_t dhcp_tick_1s      = 0;                 // unit 1 second
+uint32_t dhcp_tick_next    			= DHCP_WAIT_TIME ;
+
+uint32_t DHCP_XID;      // Any number
+
+RIP_MSG* pDHCPMSG;      // Buffer pointer for DHCP processing
+
+uint8_t HOST_NAME[] = DCHP_HOST_NAME;
+
+uint8_t DHCP_CHADDR[6]; // DHCP Client MAC address.
+
+/* The default callback function */
+void default_ip_assign(void);
+void default_ip_update(void);
+void default_ip_conflict(void);
+
+/* Callback handler */
+void (*dhcp_ip_assign)(void)   = default_ip_assign;     /* handler to be called when the IP address from DHCP server is first assigned */
+void (*dhcp_ip_update)(void)   = default_ip_update;     /* handler to be called when the IP address from DHCP server is updated */
+void (*dhcp_ip_conflict)(void) = default_ip_conflict;   /* handler to be called when the IP address from DHCP server is conflict */
+
+void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void));
+
+char NibbleToHex(uint8_t nibble);
+
+/* send DISCOVER message to DHCP server */
+void     send_DHCP_DISCOVER(void);
+
+/* send REQEUST message to DHCP server */
+void     send_DHCP_REQUEST(void);
+
+/* send DECLINE message to DHCP server */
+void     send_DHCP_DECLINE(void);
+
+/* IP conflict check by sending ARP-request to leased IP and wait ARP-response. */
+int8_t   check_DHCP_leasedIP(void);
+
+/* check the timeout in DHCP process */
+uint8_t  check_DHCP_timeout(void);
+
+/* Initialize to timeout process.  */
+void     reset_DHCP_timeout(void);
+
+/* Parse message as OFFER and ACK and NACK from DHCP server.*/
+int8_t   parseDHCPCMSG(void);
+
+/* The default handler of ip assign first */
+void default_ip_assign(void)
+{
+   setSIPR(DHCP_allocated_ip);
+   setSUBR(DHCP_allocated_sn);
+   setGAR (DHCP_allocated_gw);
+}
+
+/* The default handler of ip changed */
+void default_ip_update(void)
+{
+	/* WIZchip Software Reset */
+   setMR(MR_RST);
+   getMR(); // for delay
+   default_ip_assign();
+   setSHAR(DHCP_CHADDR);
+}
+
+/* The default handler of ip changed */
+void default_ip_conflict(void)
+{
+	// WIZchip Software Reset
+	setMR(MR_RST);
+	getMR(); // for delay
+	setSHAR(DHCP_CHADDR);
+}
+
+/* register the call back func. */
+void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void))
+{
+   dhcp_ip_assign   = default_ip_assign;
+   dhcp_ip_update   = default_ip_update;
+   dhcp_ip_conflict = default_ip_conflict;
+   if(ip_assign)   dhcp_ip_assign = ip_assign;
+   if(ip_update)   dhcp_ip_update = ip_update;
+   if(ip_conflict) dhcp_ip_conflict = ip_conflict;
+}
+
+/* make the common DHCP message */
+void makeDHCPMSG(void)
+{
+   uint8_t  bk_mac[6];
+   uint8_t* ptmp;
+   uint8_t  i;
+   getSHAR(bk_mac);
+	pDHCPMSG->op      = DHCP_BOOTREQUEST;
+	pDHCPMSG->htype   = DHCP_HTYPE10MB;
+	pDHCPMSG->hlen    = DHCP_HLENETHERNET;
+	pDHCPMSG->hops    = DHCP_HOPS;
+	ptmp              = (uint8_t*)(&pDHCPMSG->xid);
+	*(ptmp+0)         = (uint8_t)((DHCP_XID & 0xFF000000) >> 24);
+	*(ptmp+1)         = (uint8_t)((DHCP_XID & 0x00FF0000) >> 16);
+   *(ptmp+2)         = (uint8_t)((DHCP_XID & 0x0000FF00) >>  8);
+	*(ptmp+3)         = (uint8_t)((DHCP_XID & 0x000000FF) >>  0);
+	pDHCPMSG->secs    = DHCP_SECS;
+	ptmp              = (uint8_t*)(&pDHCPMSG->flags);
+	*(ptmp+0)         = (uint8_t)((DHCP_FLAGSBROADCAST & 0xFF00) >> 8);
+	*(ptmp+1)         = (uint8_t)((DHCP_FLAGSBROADCAST & 0x00FF) >> 0);
+
+	pDHCPMSG->ciaddr[0] = 0;
+	pDHCPMSG->ciaddr[1] = 0;
+	pDHCPMSG->ciaddr[2] = 0;
+	pDHCPMSG->ciaddr[3] = 0;
+
+	pDHCPMSG->yiaddr[0] = 0;
+	pDHCPMSG->yiaddr[1] = 0;
+	pDHCPMSG->yiaddr[2] = 0;
+	pDHCPMSG->yiaddr[3] = 0;
+
+	pDHCPMSG->siaddr[0] = 0;
+	pDHCPMSG->siaddr[1] = 0;
+	pDHCPMSG->siaddr[2] = 0;
+	pDHCPMSG->siaddr[3] = 0;
+
+	pDHCPMSG->giaddr[0] = 0;
+	pDHCPMSG->giaddr[1] = 0;
+	pDHCPMSG->giaddr[2] = 0;
+	pDHCPMSG->giaddr[3] = 0;
+
+	pDHCPMSG->chaddr[0] = DHCP_CHADDR[0];
+	pDHCPMSG->chaddr[1] = DHCP_CHADDR[1];
+	pDHCPMSG->chaddr[2] = DHCP_CHADDR[2];
+	pDHCPMSG->chaddr[3] = DHCP_CHADDR[3];
+	pDHCPMSG->chaddr[4] = DHCP_CHADDR[4];
+	pDHCPMSG->chaddr[5] = DHCP_CHADDR[5];
+
+	for (i = 6; i < 16; i++)  pDHCPMSG->chaddr[i] = 0;
+	for (i = 0; i < 64; i++)  pDHCPMSG->sname[i]  = 0;
+	for (i = 0; i < 128; i++) pDHCPMSG->file[i]   = 0;
+
+	// MAGIC_COOKIE
+	pDHCPMSG->OPT[0] = (uint8_t)((MAGIC_COOKIE & 0xFF000000) >> 24);
+	pDHCPMSG->OPT[1] = (uint8_t)((MAGIC_COOKIE & 0x00FF0000) >> 16);
+	pDHCPMSG->OPT[2] = (uint8_t)((MAGIC_COOKIE & 0x0000FF00) >>  8);
+	pDHCPMSG->OPT[3] = (uint8_t) (MAGIC_COOKIE & 0x000000FF) >>  0;
+}
+
+/* SEND DHCP DISCOVER */
+void send_DHCP_DISCOVER(void)
+{
+	uint16_t i;
+	uint8_t ip[4];
+	uint16_t k = 0;
+
+   makeDHCPMSG();
+   DHCP_SIP[0]=0;
+   DHCP_SIP[1]=0;
+   DHCP_SIP[2]=0;
+   DHCP_SIP[3]=0;
+   DHCP_REAL_SIP[0]=0;
+   DHCP_REAL_SIP[1]=0;
+   DHCP_REAL_SIP[2]=0;
+   DHCP_REAL_SIP[3]=0;
+
+   k = 4;     // because MAGIC_COOKIE already made by makeDHCPMSG()
+
+	// Option Request Param
+	pDHCPMSG->OPT[k++] = dhcpMessageType;
+	pDHCPMSG->OPT[k++] = 0x01;
+	pDHCPMSG->OPT[k++] = DHCP_DISCOVER;
+
+	// Client identifier
+	pDHCPMSG->OPT[k++] = dhcpClientIdentifier;
+	pDHCPMSG->OPT[k++] = 0x07;
+	pDHCPMSG->OPT[k++] = 0x01;
+	pDHCPMSG->OPT[k++] = DHCP_CHADDR[0];
+	pDHCPMSG->OPT[k++] = DHCP_CHADDR[1];
+	pDHCPMSG->OPT[k++] = DHCP_CHADDR[2];
+	pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
+	pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
+	pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
+
+	// host name
+	pDHCPMSG->OPT[k++] = hostName;
+	pDHCPMSG->OPT[k++] = 0;          // fill zero length of hostname
+	for(i = 0 ; HOST_NAME[i] != 0; i++)
+   	pDHCPMSG->OPT[k++] = HOST_NAME[i];
+	pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3] >> 4);
+	pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3]);
+	pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4] >> 4);
+	pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4]);
+	pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5] >> 4);
+	pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5]);
+	pDHCPMSG->OPT[k - (i+6+1)] = i+6; // length of hostname
+
+	pDHCPMSG->OPT[k++] = dhcpParamRequest;
+	pDHCPMSG->OPT[k++] = 0x06;	// length of request
+	pDHCPMSG->OPT[k++] = subnetMask;
+	pDHCPMSG->OPT[k++] = routersOnSubnet;
+	pDHCPMSG->OPT[k++] = dns;
+	pDHCPMSG->OPT[k++] = domainName;
+	pDHCPMSG->OPT[k++] = dhcpT1value;
+	pDHCPMSG->OPT[k++] = dhcpT2value;
+	pDHCPMSG->OPT[k++] = endOption;
+
+	for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0;
+
+	// send broadcasting packet
+	ip[0] = 255;
+	ip[1] = 255;
+	ip[2] = 255;
+	ip[3] = 255;
+
+#ifdef _DHCP_DEBUG_
+	printf("> Send DHCP_DISCOVER\r\n");
+#endif
+
+	sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT);
+}
+
+/* SEND DHCP REQUEST */
+void send_DHCP_REQUEST(void)
+{
+	int i;
+	uint8_t ip[4];
+	uint16_t k = 0;
+
+   makeDHCPMSG();
+
+   if(dhcp_state == STATE_DHCP_LEASED || dhcp_state == STATE_DHCP_REREQUEST)
+   {
+   	*((uint8_t*)(&pDHCPMSG->flags))   = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8);
+   	*((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF);
+   	pDHCPMSG->ciaddr[0] = DHCP_allocated_ip[0];
+   	pDHCPMSG->ciaddr[1] = DHCP_allocated_ip[1];
+   	pDHCPMSG->ciaddr[2] = DHCP_allocated_ip[2];
+   	pDHCPMSG->ciaddr[3] = DHCP_allocated_ip[3];
+   	ip[0] = DHCP_SIP[0];
+   	ip[1] = DHCP_SIP[1];
+   	ip[2] = DHCP_SIP[2];
+   	ip[3] = DHCP_SIP[3];
+   }
+   else
+   {
+   	ip[0] = 255;
+   	ip[1] = 255;
+   	ip[2] = 255;
+   	ip[3] = 255;
+   }
+
+   k = 4;      // because MAGIC_COOKIE already made by makeDHCPMSG()
+
+	// Option Request Param.
+	pDHCPMSG->OPT[k++] = dhcpMessageType;
+	pDHCPMSG->OPT[k++] = 0x01;
+	pDHCPMSG->OPT[k++] = DHCP_REQUEST;
+
+	pDHCPMSG->OPT[k++] = dhcpClientIdentifier;
+	pDHCPMSG->OPT[k++] = 0x07;
+	pDHCPMSG->OPT[k++] = 0x01;
+	pDHCPMSG->OPT[k++] = DHCP_CHADDR[0];
+	pDHCPMSG->OPT[k++] = DHCP_CHADDR[1];
+	pDHCPMSG->OPT[k++] = DHCP_CHADDR[2];
+	pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
+	pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
+	pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
+
+   if(ip[3] == 255)  // if(dchp_state == STATE_DHCP_LEASED || dchp_state == DHCP_REREQUEST_STATE)
+   {
+		pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr;
+		pDHCPMSG->OPT[k++] = 0x04;
+		pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0];
+		pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1];
+		pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2];
+		pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3];
+
+		pDHCPMSG->OPT[k++] = dhcpServerIdentifier;
+		pDHCPMSG->OPT[k++] = 0x04;
+		pDHCPMSG->OPT[k++] = DHCP_SIP[0];
+		pDHCPMSG->OPT[k++] = DHCP_SIP[1];
+		pDHCPMSG->OPT[k++] = DHCP_SIP[2];
+		pDHCPMSG->OPT[k++] = DHCP_SIP[3];
+	}
+
+	// host name
+	pDHCPMSG->OPT[k++] = hostName;
+	pDHCPMSG->OPT[k++] = 0; // length of hostname
+	for(i = 0 ; HOST_NAME[i] != 0; i++)
+   	pDHCPMSG->OPT[k++] = HOST_NAME[i];
+	pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3] >> 4);
+	pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3]);
+	pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4] >> 4);
+	pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4]);
+	pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5] >> 4);
+	pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5]);
+	pDHCPMSG->OPT[k - (i+6+1)] = i+6; // length of hostname
+
+	pDHCPMSG->OPT[k++] = dhcpParamRequest;
+	pDHCPMSG->OPT[k++] = 0x08;
+	pDHCPMSG->OPT[k++] = subnetMask;
+	pDHCPMSG->OPT[k++] = routersOnSubnet;
+	pDHCPMSG->OPT[k++] = dns;
+	pDHCPMSG->OPT[k++] = domainName;
+	pDHCPMSG->OPT[k++] = dhcpT1value;
+	pDHCPMSG->OPT[k++] = dhcpT2value;
+	pDHCPMSG->OPT[k++] = performRouterDiscovery;
+	pDHCPMSG->OPT[k++] = staticRoute;
+	pDHCPMSG->OPT[k++] = endOption;
+
+	for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0;
+
+#ifdef _DHCP_DEBUG_
+	printf("> Send DHCP_REQUEST\r\n");
+#endif
+
+	sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT);
+
+}
+
+/* SEND DHCP DHCPDECLINE */
+void send_DHCP_DECLINE(void)
+{
+	int i;
+	uint8_t ip[4];
+	uint16_t k = 0;
+
+	makeDHCPMSG();
+
+   k = 4;      // because MAGIC_COOKIE already made by makeDHCPMSG()
+
+	*((uint8_t*)(&pDHCPMSG->flags))   = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8);
+	*((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF);
+
+	// Option Request Param.
+	pDHCPMSG->OPT[k++] = dhcpMessageType;
+	pDHCPMSG->OPT[k++] = 0x01;
+	pDHCPMSG->OPT[k++] = DHCP_DECLINE;
+
+	pDHCPMSG->OPT[k++] = dhcpClientIdentifier;
+	pDHCPMSG->OPT[k++] = 0x07;
+	pDHCPMSG->OPT[k++] = 0x01;
+	pDHCPMSG->OPT[k++] = DHCP_CHADDR[0];
+	pDHCPMSG->OPT[k++] = DHCP_CHADDR[1];
+	pDHCPMSG->OPT[k++] = DHCP_CHADDR[2];
+	pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
+	pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
+	pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
+
+	pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr;
+	pDHCPMSG->OPT[k++] = 0x04;
+	pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0];
+	pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1];
+	pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2];
+	pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3];
+
+	pDHCPMSG->OPT[k++] = dhcpServerIdentifier;
+	pDHCPMSG->OPT[k++] = 0x04;
+	pDHCPMSG->OPT[k++] = DHCP_SIP[0];
+	pDHCPMSG->OPT[k++] = DHCP_SIP[1];
+	pDHCPMSG->OPT[k++] = DHCP_SIP[2];
+	pDHCPMSG->OPT[k++] = DHCP_SIP[3];
+
+	pDHCPMSG->OPT[k++] = endOption;
+
+	for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0;
+
+	//send broadcasting packet
+	ip[0] = 0xFF;
+	ip[1] = 0xFF;
+	ip[2] = 0xFF;
+	ip[3] = 0xFF;
+
+#ifdef _DHCP_DEBUG_
+	printf("\r\n> Send DHCP_DECLINE\r\n");
+#endif
+
+	sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT);
+}
+
+/* PARSE REPLY pDHCPMSG */
+int8_t parseDHCPMSG(void)
+{
+	uint8_t svr_addr[6];
+	uint16_t  svr_port;
+	uint16_t len;
+
+	uint8_t* p;
+	uint8_t* e;
+	uint8_t type = 0;
+	uint8_t opt_len;
+
+	if ((len = getSn_RX_RSR(DHCP_SOCKET)) > 0)
+	{
+		len = recvfrom(DHCP_SOCKET, (uint8_t *)pDHCPMSG, len, svr_addr, &svr_port);
+#ifdef _DHCP_DEBUG_
+		printf("DHCP message : %d.%d.%d.%d(%d) %d received. \r\n",svr_addr[0],svr_addr[1],svr_addr[2], svr_addr[3],svr_port, len);
+#endif
+	}
+	else return 0;
+
+	if (svr_port == DHCP_SERVER_PORT)
+	{	// compare mac address
+		if ( (pDHCPMSG->chaddr[0] != DHCP_CHADDR[0]) || (pDHCPMSG->chaddr[1] != DHCP_CHADDR[1]) ||
+		     (pDHCPMSG->chaddr[2] != DHCP_CHADDR[2]) || (pDHCPMSG->chaddr[3] != DHCP_CHADDR[3]) ||
+		     (pDHCPMSG->chaddr[4] != DHCP_CHADDR[4]) || (pDHCPMSG->chaddr[5] != DHCP_CHADDR[5])   )
+		{
+#ifdef _DHCP_DEBUG_
+            printf("No My DHCP Message. This message is ignored.\r\n");
+#endif
+			return 0;
+		}
+
+        //compare DHCP server ip address
+        if ((DHCP_SIP[0]!=0) || (DHCP_SIP[1]!=0) || (DHCP_SIP[2]!=0) || (DHCP_SIP[3]!=0))
+		{
+            if( ((svr_addr[0]!=DHCP_SIP[0])|| (svr_addr[1]!=DHCP_SIP[1])|| (svr_addr[2]!=DHCP_SIP[2])|| (svr_addr[3]!=DHCP_SIP[3])) &&
+                ((svr_addr[0]!=DHCP_REAL_SIP[0])|| (svr_addr[1]!=DHCP_REAL_SIP[1])|| (svr_addr[2]!=DHCP_REAL_SIP[2])|| (svr_addr[3]!=DHCP_REAL_SIP[3]))  )
+            {
+#ifdef _DHCP_DEBUG_
+                printf("Another DHCP sever send a response message. This is ignored.\r\n");
+#endif
+                return 0;
+            }
+        }
+
+		p = (uint8_t *)(&pDHCPMSG->op);
+		p = p + 240;      // 240 = sizeof(RIP_MSG) + MAGIC_COOKIE size in RIP_MSG.opt - sizeof(RIP_MSG.opt)
+		e = p + (len - 240);
+
+		while ( p < e )
+		{
+			switch ( *p )
+			{
+				case endOption :
+					p = e;   // for break while(p < e)
+					break;
+				case padOption :
+					p++;
+					break;
+				case dhcpMessageType :
+					p++;
+					p++;
+					type = *p++;
+					break;
+				case subnetMask :
+					p++;
+					p++;
+					DHCP_allocated_sn[0] = *p++;
+					DHCP_allocated_sn[1] = *p++;
+					DHCP_allocated_sn[2] = *p++;
+					DHCP_allocated_sn[3] = *p++;
+					break;
+				case routersOnSubnet :
+					p++;
+					opt_len = *p++;
+					DHCP_allocated_gw[0] = *p++;
+					DHCP_allocated_gw[1] = *p++;
+					DHCP_allocated_gw[2] = *p++;
+					DHCP_allocated_gw[3] = *p++;
+					p = p + (opt_len - 4);
+					break;
+				case dns :
+					p++;
+					opt_len = *p++;
+					DHCP_allocated_dns[0] = *p++;
+					DHCP_allocated_dns[1] = *p++;
+					DHCP_allocated_dns[2] = *p++;
+					DHCP_allocated_dns[3] = *p++;
+					p = p + (opt_len - 4);
+					break;
+				case dhcpIPaddrLeaseTime :
+					p++;
+					opt_len = *p++;
+					dhcp_lease_time  = *p++;
+					dhcp_lease_time  = (dhcp_lease_time << 8) + *p++;
+					dhcp_lease_time  = (dhcp_lease_time << 8) + *p++;
+					dhcp_lease_time  = (dhcp_lease_time << 8) + *p++;
+#ifdef _DHCP_DEBUG_
+					dhcp_lease_time = 10;
+#endif
+					break;
+				case dhcpServerIdentifier :
+       				p++;
+       				opt_len = *p++;
+       				DHCP_SIP[0] = *p++;
+       				DHCP_SIP[1] = *p++;
+       				DHCP_SIP[2] = *p++;
+       				DHCP_SIP[3] = *p++;
+                    DHCP_REAL_SIP[0]=svr_addr[0];
+                    DHCP_REAL_SIP[1]=svr_addr[1];
+                    DHCP_REAL_SIP[2]=svr_addr[2];
+                    DHCP_REAL_SIP[3]=svr_addr[3];
+       				break;
+				default :
+					p++;
+					opt_len = *p++;
+					p += opt_len;
+					break;
+			} // switch
+		} // while
+	} // if
+	return	type;
+}
+
+uint8_t DHCP_run(void)
+{
+	uint8_t  type;
+	uint8_t  ret;
+
+	if (dhcp_state == STATE_DHCP_STOP) return DHCP_STOPPED;
+
+	if (getSn_SR(DHCP_SOCKET) != SOCK_UDP)
+	   socket(DHCP_SOCKET, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00);
+
+	ret = DHCP_RUNNING;
+	type = parseDHCPMSG();
+
+	switch ( dhcp_state )
+	{
+		case STATE_DHCP_INIT     :
+			DHCP_allocated_ip[0] = 0;
+			DHCP_allocated_ip[1] = 0;
+			DHCP_allocated_ip[2] = 0;
+			DHCP_allocated_ip[3] = 0;
+			send_DHCP_DISCOVER();
+			dhcp_state = STATE_DHCP_DISCOVER;
+			break;
+		case STATE_DHCP_DISCOVER :
+			if (type == DHCP_OFFER)
+			{
+#ifdef _DHCP_DEBUG_
+				printf("> Receive DHCP_OFFER\r\n");
+#endif
+                DHCP_allocated_ip[0] = pDHCPMSG->yiaddr[0];
+                DHCP_allocated_ip[1] = pDHCPMSG->yiaddr[1];
+                DHCP_allocated_ip[2] = pDHCPMSG->yiaddr[2];
+                DHCP_allocated_ip[3] = pDHCPMSG->yiaddr[3];
+
+				send_DHCP_REQUEST();
+				dhcp_state = STATE_DHCP_REQUEST;
+			}
+			else
+				ret = check_DHCP_timeout();
+			break;
+
+		case STATE_DHCP_REQUEST :
+			if (type == DHCP_ACK)
+			{
+#ifdef _DHCP_DEBUG_
+				printf("> Receive DHCP_ACK\r\n");
+#endif
+				if (check_DHCP_leasedIP())
+				{	// Network info assignment from DHCP
+					dhcp_ip_assign();
+					reset_DHCP_timeout();
+
+					dhcp_state = STATE_DHCP_LEASED;
+				}
+				else
+				{	// IP address conflict occurred
+					reset_DHCP_timeout();
+					dhcp_ip_conflict();
+				    dhcp_state = STATE_DHCP_INIT;
+				}
+			}
+			else if (type == DHCP_NAK)
+			{
+#ifdef _DHCP_DEBUG_
+				printf("> Receive DHCP_NACK\r\n");
+#endif
+				reset_DHCP_timeout();
+
+				dhcp_state = STATE_DHCP_DISCOVER;
+			}
+			else
+				ret = check_DHCP_timeout();
+			break;
+
+		case STATE_DHCP_LEASED :
+			ret = DHCP_IP_LEASED;
+			if ((dhcp_lease_time != INFINITE_LEASETIME) && ((dhcp_lease_time/2) < dhcp_tick_1s))
+			{
+#ifdef _DHCP_DEBUG_
+ 				printf("> Maintains the IP address \r\n");
+#endif
+				type = 0;
+				OLD_allocated_ip[0] = DHCP_allocated_ip[0];
+				OLD_allocated_ip[1] = DHCP_allocated_ip[1];
+				OLD_allocated_ip[2] = DHCP_allocated_ip[2];
+				OLD_allocated_ip[3] = DHCP_allocated_ip[3];
+
+				DHCP_XID++;
+
+				send_DHCP_REQUEST();
+
+				reset_DHCP_timeout();
+
+				dhcp_state = STATE_DHCP_REREQUEST;
+			}
+			break;
+
+		case STATE_DHCP_REREQUEST :
+			ret = DHCP_IP_LEASED;
+			if (type == DHCP_ACK)
+			{
+				dhcp_retry_count = 0;
+				if (OLD_allocated_ip[0] != DHCP_allocated_ip[0] ||
+				    OLD_allocated_ip[1] != DHCP_allocated_ip[1] ||
+				    OLD_allocated_ip[2] != DHCP_allocated_ip[2] ||
+				    OLD_allocated_ip[3] != DHCP_allocated_ip[3])
+				{
+					ret = DHCP_IP_CHANGED;
+					dhcp_ip_update();
+#ifdef _DHCP_DEBUG_
+					printf(">IP changed.\r\n");
+#endif
+
+				}
+#ifdef _DHCP_DEBUG_
+				else printf(">IP is continued.\r\n");
+#endif
+				reset_DHCP_timeout();
+				dhcp_state = STATE_DHCP_LEASED;
+			}
+			else if (type == DHCP_NAK)
+			{
+#ifdef _DHCP_DEBUG_
+				printf("> Receive DHCP_NACK, Failed to maintain ip\r\n");
+#endif
+				reset_DHCP_timeout();
+
+				dhcp_state = STATE_DHCP_DISCOVER;
+			}
+			else
+				ret = check_DHCP_timeout();
+			break;
+		default :
+			break;
+	}
+
+	return ret;
+}
+
+void    DHCP_stop(void)
+{
+   close(DHCP_SOCKET);
+   dhcp_state = STATE_DHCP_STOP;
+}
+
+uint8_t check_DHCP_timeout(void)
+{
+	uint8_t ret = DHCP_RUNNING;
+
+	if (dhcp_retry_count < MAX_DHCP_RETRY) {
+		if (dhcp_tick_next < dhcp_tick_1s) {
+
+			switch ( dhcp_state ) {
+				case STATE_DHCP_DISCOVER :
+//					printf("<<timeout>> state : STATE_DHCP_DISCOVER\r\n");
+					send_DHCP_DISCOVER();
+				break;
+
+				case STATE_DHCP_REQUEST :
+//					printf("<<timeout>> state : STATE_DHCP_REQUEST\r\n");
+
+					send_DHCP_REQUEST();
+				break;
+
+				case STATE_DHCP_REREQUEST :
+//					printf("<<timeout>> state : STATE_DHCP_REREQUEST\r\n");
+
+					send_DHCP_REQUEST();
+				break;
+
+				default :
+				break;
+			}
+
+			dhcp_tick_1s = 0;
+			dhcp_tick_next = dhcp_tick_1s + DHCP_WAIT_TIME;
+			dhcp_retry_count++;
+		}
+	} else { // timeout occurred
+
+		switch(dhcp_state) {
+			case STATE_DHCP_DISCOVER:
+				dhcp_state = STATE_DHCP_INIT;
+				ret = DHCP_FAILED;
+				break;
+			case STATE_DHCP_REQUEST:
+			case STATE_DHCP_REREQUEST:
+				send_DHCP_DISCOVER();
+				dhcp_state = STATE_DHCP_DISCOVER;
+				break;
+			default :
+				break;
+		}
+		reset_DHCP_timeout();
+	}
+	return ret;
+}
+
+int8_t check_DHCP_leasedIP(void)
+{
+	uint8_t tmp;
+	int32_t ret;
+
+	//WIZchip RCR value changed for ARP Timeout count control
+	tmp = getRCR();
+	setRCR(0x03);
+
+	// IP conflict detection : ARP request - ARP reply
+	// Broadcasting ARP Request for check the IP conflict using UDP sendto() function
+	ret = sendto(DHCP_SOCKET, (uint8_t *)"CHECK_IP_CONFLICT", 17, DHCP_allocated_ip, 5000);
+
+	// RCR value restore
+	setRCR(tmp);
+
+	if(ret == SOCKERR_TIMEOUT) {
+		// UDP send Timeout occurred : allocated IP address is unique, DHCP Success
+
+#ifdef _DHCP_DEBUG_
+		printf("\r\n> Check leased IP - OK\r\n");
+#endif
+
+		return 1;
+	} else {
+		// Received ARP reply or etc : IP address conflict occur, DHCP Failed
+		send_DHCP_DECLINE();
+
+		ret = dhcp_tick_1s;
+		while((dhcp_tick_1s - ret) < 2) ;   // wait for 1s over; wait to complete to send DECLINE message;
+
+		return 0;
+	}
+}
+
+void DHCP_init(uint8_t s, uint8_t * buf)
+{
+   uint8_t zeroip[4] = {0,0,0,0};
+   getSHAR(DHCP_CHADDR);
+   if((DHCP_CHADDR[0] | DHCP_CHADDR[1]  | DHCP_CHADDR[2] | DHCP_CHADDR[3] | DHCP_CHADDR[4] | DHCP_CHADDR[5]) == 0x00)
+   {
+      // assigning temporary mac address, you should be set SHAR before call this function.
+      DHCP_CHADDR[0] = 0x00;
+      DHCP_CHADDR[1] = 0x08;
+      DHCP_CHADDR[2] = 0xdc;
+      DHCP_CHADDR[3] = 0x00;
+      DHCP_CHADDR[4] = 0x00;
+      DHCP_CHADDR[5] = 0x00;
+      setSHAR(DHCP_CHADDR);
+   }
+
+	DHCP_SOCKET = s; // SOCK_DHCP
+	pDHCPMSG = (RIP_MSG*)buf;
+	DHCP_XID = 0x12345678;
+	{
+		DHCP_XID += DHCP_CHADDR[3];
+		DHCP_XID += DHCP_CHADDR[4];
+		DHCP_XID += DHCP_CHADDR[5];
+		DHCP_XID += (DHCP_CHADDR[3] ^ DHCP_CHADDR[4] ^ DHCP_CHADDR[5]);
+	}
+	// WIZchip Netinfo Clear
+	setSIPR(zeroip);
+	setGAR(zeroip);
+
+	reset_DHCP_timeout();
+	dhcp_state = STATE_DHCP_INIT;
+}
+
+
+/* Reset the DHCP timeout count and retry count. */
+void reset_DHCP_timeout(void)
+{
+	dhcp_tick_1s = 0;
+	dhcp_tick_next = DHCP_WAIT_TIME;
+	dhcp_retry_count = 0;
+}
+
+void DHCP_time_handler(void)
+{
+	dhcp_tick_1s++;
+}
+
+void getIPfromDHCP(uint8_t* ip)
+{
+	ip[0] = DHCP_allocated_ip[0];
+	ip[1] = DHCP_allocated_ip[1];
+	ip[2] = DHCP_allocated_ip[2];
+	ip[3] = DHCP_allocated_ip[3];
+}
+
+void getGWfromDHCP(uint8_t* ip)
+{
+	ip[0] =DHCP_allocated_gw[0];
+	ip[1] =DHCP_allocated_gw[1];
+	ip[2] =DHCP_allocated_gw[2];
+	ip[3] =DHCP_allocated_gw[3];
+}
+
+void getSNfromDHCP(uint8_t* ip)
+{
+   ip[0] = DHCP_allocated_sn[0];
+   ip[1] = DHCP_allocated_sn[1];
+   ip[2] = DHCP_allocated_sn[2];
+   ip[3] = DHCP_allocated_sn[3];
+}
+
+void getDNSfromDHCP(uint8_t* ip)
+{
+   ip[0] = DHCP_allocated_dns[0];
+   ip[1] = DHCP_allocated_dns[1];
+   ip[2] = DHCP_allocated_dns[2];
+   ip[3] = DHCP_allocated_dns[3];
+}
+
+uint32_t getDHCPLeasetime(void)
+{
+	return dhcp_lease_time;
+}
+
+char NibbleToHex(uint8_t nibble)
+{
+  nibble &= 0x0F;
+  if (nibble <= 9)
+    return nibble + '0';
+  else
+    return nibble + ('A'-0x0A);
+}
+
+
Index: ctrl/firmware/Main/SES/Wiznet/Internet/DHCP/dhcp.h
===================================================================
--- ctrl/firmware/Main/SES/Wiznet/Internet/DHCP/dhcp.h	(revision 79)
+++ ctrl/firmware/Main/SES/Wiznet/Internet/DHCP/dhcp.h	(revision 79)
@@ -0,0 +1,161 @@
+//*****************************************************************************
+//
+//! \file dhcp.h
+//! \brief DHCP APIs Header file.
+//! \details Processig DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE.
+//! \version 1.1.1
+//! \date 2019/10/08
+//! \par  Revision history
+//!       <2019/10/08> compare DHCP server ip address
+//!       <2013/11/18> 1st Release
+//!       <2012/12/20> V1.1.0
+//!         1. Move unreferenced DEFINE to dhcp.c
+//!       <2012/12/26> V1.1.1
+//! \author Eric Jung & MidnightCow
+//! \copyright
+//!
+//! Copyright (c)  2013, WIZnet Co., LTD.
+//! All rights reserved.
+//! 
+//! Redistribution and use in source and binary forms, with or without 
+//! modification, are permitted provided that the following conditions 
+//! are met: 
+//! 
+//!     * Redistributions of source code must retain the above copyright 
+//! notice, this list of conditions and the following disclaimer. 
+//!     * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution. 
+//!     * Neither the name of the <ORGANIZATION> nor the names of its 
+//! contributors may be used to endorse or promote products derived 
+//! from this software without specific prior written permission. 
+//! 
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+#ifndef _DHCP_H_
+#define _DHCP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * @brief 
+ * @details If you want to display debug & processing message, Define _DHCP_DEBUG_ 
+ * @note    If defined, it depends on <stdio.h>
+ */
+//#define _DHCP_DEBUG_
+
+
+/* Retry to processing DHCP */
+#define	MAX_DHCP_RETRY          2        ///< Maximum retry count
+#define	DHCP_WAIT_TIME          10       ///< Wait Time 10s
+
+
+/* UDP port numbers for DHCP */
+#define DHCP_SERVER_PORT      	67	      ///< DHCP server port number
+#define DHCP_CLIENT_PORT         68	      ///< DHCP client port number
+
+
+#define MAGIC_COOKIE             0x63825363  ///< You should not modify it number.
+
+#define DCHP_HOST_NAME           "WIZnet\0"
+
+/* 
+ * @brief return value of @ref DHCP_run()
+ */
+enum
+{
+   DHCP_FAILED = 0,  ///< Processing Fail
+   DHCP_RUNNING,     ///< Processing DHCP protocol
+   DHCP_IP_ASSIGN,   ///< First Occupy IP from DHPC server      (if cbfunc == null, act as default default_ip_assign)
+   DHCP_IP_CHANGED,  ///< Change IP address by new ip from DHCP (if cbfunc == null, act as default default_ip_update)
+   DHCP_IP_LEASED,   ///< Stand by 
+   DHCP_STOPPED      ///< Stop processing DHCP protocol
+};
+
+/*
+ * @brief DHCP client initialization (outside of the main loop)
+ * @param s   - socket number
+ * @param buf - buffer for processing DHCP message
+ */
+void DHCP_init(uint8_t s, uint8_t * buf);
+
+/*
+ * @brief DHCP 1s Tick Timer handler
+ * @note SHOULD BE register to your system 1s Tick timer handler 
+ */
+void DHCP_time_handler(void);
+
+/* 
+ * @brief Register call back function 
+ * @param ip_assign   - callback func when IP is assigned from DHCP server first
+ * @param ip_update   - callback func when IP is changed
+ * @param ip_conflict - callback func when the assigned IP is conflict with others.
+ */
+void reg_dhcp_cbfunc(void(*ip_assign)(void), void(*ip_update)(void), void(*ip_conflict)(void));
+
+/*
+ * @brief DHCP client in the main loop
+ * @return    The value is as the follow \n
+ *            @ref DHCP_FAILED     \n
+ *            @ref DHCP_RUNNING    \n
+ *            @ref DHCP_IP_ASSIGN  \n
+ *            @ref DHCP_IP_CHANGED \n
+ * 			  @ref DHCP_IP_LEASED  \n
+ *            @ref DHCP_STOPPED    \n
+ *
+ * @note This function is always called by you main task.
+ */ 
+uint8_t DHCP_run(void);
+
+/*
+ * @brief Stop DHCP processing
+ * @note If you want to restart. call DHCP_init() and DHCP_run()
+ */ 
+void    DHCP_stop(void);
+
+/* Get Network information assigned from DHCP server */
+/*
+ * @brief Get IP address
+ * @param ip  - IP address to be returned
+ */
+void getIPfromDHCP(uint8_t* ip);
+/*
+ * @brief Get Gateway address
+ * @param ip  - Gateway address to be returned
+ */
+void getGWfromDHCP(uint8_t* ip);
+/*
+ * @brief Get Subnet mask value
+ * @param ip  - Subnet mask to be returned
+ */
+void getSNfromDHCP(uint8_t* ip);
+/*
+ * @brief Get DNS address
+ * @param ip  - DNS address to be returned
+ */
+void getDNSfromDHCP(uint8_t* ip);
+
+/*
+ * @brief Get the leased time by DHCP sever
+ * @return unit 1s
+ */
+uint32_t getDHCPLeasetime(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _DHCP_H_ */
Index: ctrl/firmware/Main/SES/charger.emProject
===================================================================
--- ctrl/firmware/Main/SES/charger.emProject	(revision 78)
+++ ctrl/firmware/Main/SES/charger.emProject	(revision 79)
@@ -35,5 +35,5 @@
       c_enforce_ansi_checking="Yes"
       c_preprocessor_definitions="STM32H723xx;_DHCP_DEBUG_"
-      c_user_include_directories="./../CubeMX/Core/Inc;./../CubeMX/Drivers/STM32H7xx_HAL_Driver/Inc;./../CubeMX/Drivers/CMSIS/Device/ST/STM32H7xx/Include;./../CubeMX/Drivers/CMSIS/Core/Include;./../CubeMX/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2;./../CubeMX/Middlewares/Third_Party/FreeRTOS/Source/include;./../CubeMX/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F;./../CubeMX/FATFS/App;./../CubeMX/Middlewares/Third_Party/FatFs/src;./../CubeMX/FATFS/Target;$(ProjectDir)/Core/Inc;$(ProjectDir)/Wiznet/Ethernet/W5100S;$(ProjectDir)/Wiznet/Ethernet;$(ProjectDir)/Wiznet/Internet/DHCP"
+      c_user_include_directories="./../CubeMX/Core/Inc;./../CubeMX/Drivers/STM32H7xx_HAL_Driver/Inc;./../CubeMX/Drivers/CMSIS/Device/ST/STM32H7xx/Include;./../CubeMX/Drivers/CMSIS/Core/Include;./../CubeMX/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2;./../CubeMX/Middlewares/Third_Party/FreeRTOS/Source/include;./../CubeMX/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F;./../CubeMX/FATFS/App;./../CubeMX/Middlewares/Third_Party/FatFs/src;./../CubeMX/FATFS/Target;$(ProjectDir)/Core/Inc;$(ProjectDir)/Wiznet/Ethernet/W5100S;$(ProjectDir)/Wiznet/Ethernet;$(ProjectDir)/Wiznet/Internet/DHCP;$(ProjectDir)/Wiznet/Application/loopback"
       compiler_color_diagnostics="Yes"
       debug_initial_breakpoint_set_option="Never"
@@ -69,8 +69,4 @@
       <folder Name="Inc">
         <file file_name="../CubeMX/Core/Inc/dma.h" />
-        <file file_name="Core/Inc/eth_thread.h">
-          <configuration Name="Debug" build_exclude_from_build="Yes" />
-          <configuration Name="Release" build_exclude_from_build="Yes" />
-        </file>
         <file file_name="Core/Inc/fan_thread.h">
           <configuration Name="Release" build_exclude_from_build="No" />
@@ -79,7 +75,5 @@
         <file file_name="Core/Inc/gsm_rx_thread.h" />
         <file file_name="Core/Inc/gsm_thread.h" />
-        <file file_name="Core/Inc/keys_task.h" />
         <file file_name="../CubeMX/Core/Inc/main.h" />
-        <file file_name="Core/Inc/main_task.h" />
         <file file_name="../CubeMX/Core/Inc/memorymap.h" />
         <file file_name="../CubeMX/Core/Inc/rtc.h" />
@@ -94,8 +88,4 @@
       <folder Name="Src">
         <file file_name="../CubeMX/Core/Src/dma.c" />
-        <file file_name="Core/Src/eth_thread.cpp">
-          <configuration Name="Debug" build_exclude_from_build="Yes" />
-          <configuration Name="Release" build_exclude_from_build="Yes" />
-        </file>
         <file file_name="Core/Src/fan_thread.cpp">
           <configuration Name="Debug" build_exclude_from_build="Yes" />
@@ -112,7 +102,5 @@
           <configuration Name="Release" build_exclude_from_build="Yes" />
         </file>
-        <file file_name="Core/Src/keys_task.cpp" />
         <file file_name="../CubeMX/Core/Src/main.c" />
-        <file file_name="Core/Src/main_task.cpp" />
         <file file_name="../CubeMX/Core/Src/memorymap.c" />
         <file file_name="../CubeMX/Core/Src/rtc.c" />
@@ -208,4 +196,12 @@
           </folder>
         </folder>
+        <folder Name="Loopback">
+          <folder Name="Inc">
+            <file file_name="Wiznet/Application/loopback/loopback.h" />
+          </folder>
+          <folder Name="Src">
+            <file file_name="Wiznet/Application/loopback/loopback.c" />
+          </folder>
+        </folder>
       </folder>
     </folder>
@@ -294,4 +290,16 @@
       <file file_name="STM32H7xx/Source/stm32h723xx_Vectors.s" />
     </folder>
+    <folder Name="Tasks">
+      <folder Name="Inc">
+        <file file_name="Core/Inc/eth_task.h" />
+        <file file_name="Core/Inc/keys_task.h" />
+        <file file_name="Core/Inc/main_task.h" />
+      </folder>
+      <folder Name="Src">
+        <file file_name="Core/Src/eth_task.cpp" />
+        <file file_name="Core/Src/keys_task.cpp" />
+        <file file_name="Core/Src/main_task.cpp" />
+      </folder>
+    </folder>
   </project>
 </solution>
