]> git.sur5r.net Git - freertos/commitdiff
New Demo files for Tern E-Engine controller port.
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sat, 27 May 2006 13:55:53 +0000 (13:55 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sat, 27 May 2006 13:55:53 +0000 (13:55 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@7 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

19 files changed:
Demo/WizNET_DEMO_TERN_186/186.cfg [new file with mode: 0644]
Demo/WizNET_DEMO_TERN_186/AE.LIB [new file with mode: 0644]
Demo/WizNET_DEMO_TERN_186/FreeRTOSConfig.h [new file with mode: 0644]
Demo/WizNET_DEMO_TERN_186/HTTPTask.c [new file with mode: 0644]
Demo/WizNET_DEMO_TERN_186/HTTPTask.h [new file with mode: 0644]
Demo/WizNET_DEMO_TERN_186/RTOSDemo.DSW [new file with mode: 0644]
Demo/WizNET_DEMO_TERN_186/RTOSDemo.ide [new file with mode: 0644]
Demo/WizNET_DEMO_TERN_186/RTOSDemo.mbt [new file with mode: 0644]
Demo/WizNET_DEMO_TERN_186/RTOSDemo.mrt [new file with mode: 0644]
Demo/WizNET_DEMO_TERN_186/RTOSDemo.rom [new file with mode: 0644]
Demo/WizNET_DEMO_TERN_186/i2chip_hw.c [new file with mode: 0644]
Demo/WizNET_DEMO_TERN_186/include/SOCKET.H [new file with mode: 0644]
Demo/WizNET_DEMO_TERN_186/include/TYPES.H [new file with mode: 0644]
Demo/WizNET_DEMO_TERN_186/include/ae.H [new file with mode: 0644]
Demo/WizNET_DEMO_TERN_186/include/i2chip_hw.h [new file with mode: 0644]
Demo/WizNET_DEMO_TERN_186/include/utils/system_common.h [new file with mode: 0644]
Demo/WizNET_DEMO_TERN_186/main.c [new file with mode: 0644]
Demo/WizNET_DEMO_TERN_186/serial/serial.c [new file with mode: 0644]
Demo/WizNET_DEMO_TERN_186/socket.c [new file with mode: 0644]

diff --git a/Demo/WizNET_DEMO_TERN_186/186.cfg b/Demo/WizNET_DEMO_TERN_186/186.cfg
new file mode 100644 (file)
index 0000000..f7e6170
--- /dev/null
@@ -0,0 +1,145 @@
+// 186.cfg\r
+//     You must select RAM, ROM for your controller   04-26-2000\r
+//     Your TERN controller is installed with SRAM and ROM with different sizes.\r
+//     For debug, 128K or 512K SRAM can be selected\r
+//     For build a ROM, you need to select the ROM size.\r
+// How to select ?\r
+//     1) commend out the unwanted #define RAM size line with "//"\r
+//     2) delete the "//" preceding the wanted #define RAM size line\r
+//\r
+\r
+// #define RAM 32 // 32KB SRAM installed\r
+#define RAM 128 // 128KB SRAM installed\r
+// #define RAM 512 // 512KB SRAM installed\r
+\r
+// #define ROM 32 // Use 32KB ROM chip 27C256-70\r
+#define ROM 64 // Use 64KB ROM chip 27C512-70\r
+// #define ROM 128 // Use 128KB ROM chip 27C010-70 \r
+// #define ROM 256 // Use 256KB ROM chip 27C020-70\r
+// #define ROM 512 // Use 512KB ROM chip 27C040-70, Change Jumper on board\r
+\r
+\r
+cputype Am186ES // AMD188/6 based controllers\r
+\r
+#if defined(__PDREMOTE__)\r
+\r
+#if RAM == 32\r
+map    0x00000 to 0x00fff as reserved // interrupt vector table\r
+map    0x01000 to 0x03fff as rdwr      // System RAM area (60KB RAM)\r
+map    0x04000 to 0x07fff as rdonly    // Simulated EPROM area (64KB RAM)\r
+map    0x08000 to 0xfffff as reserved  // No access allowed\r
+#define CODE_START 0x0400      // Start of application code, STEP2 !\r
+\r
+#elif RAM == 128\r
+map    0x00000 to 0x00fff as reserved // interrupt vector table\r
+map    0x01000 to 0x07fff as rdwr      // System RAM area (60KB RAM)\r
+map    0x08000 to 0x1ffff as rdonly    // Simulated EPROM area (64KB RAM)\r
+map    0x20000 to 0xfffff as reserved  // No access allowed\r
+#define CODE_START 0x0800              // Start of application code\r
+\r
+#elif RAM == 512\r
+map    0x00000 to 0x00fff as reserved // interrupt vector table\r
+map    0x01000 to 0x07fff as rdwr      // System RAM area (60KB RAM)\r
+map    0x08000 to 0x7ffff as rdonly    // Simulated EPROM area(480KB RAM)\r
+map    0x80000 to 0xfffff as reserved // No access allowed\r
+#define CODE_START 0x0800              // Start of application code\r
+#endif\r
+\r
+#define DATA_START 0x0100      // Start of application data\r
+#define BOOT_START 0x1fc0      // Start of initialization code\r
+\r
+#else\r
+#if ROM == 32                      \r
+map    0x00000 to 0x1ffff as rdwr      // 128KB RAM address space\r
+map    0x20000 to 0xf7fff as reserved  // No access\r
+map    0xF8000 to 0xfffff as rdonly    // 32KB EPROM address space\r
+#define CODE_START 0xF800              // Start of application code\r
+#elif ROM == 64\r
+map    0x00000 to 0x1ffff as rdwr      // 128KB RAM address space\r
+map    0x20000 to 0xEffff as reserved  // No access\r
+map    0xF0000 to 0xfffff as rdonly    // 64KB EPROM address space\r
+#define CODE_START 0xF000              // Start of application code\r
+#elif ROM == 128\r
+map    0x00000 to 0x1ffff as rdwr      // 128KB RAM address space\r
+map    0x20000 to 0xDffff as reserved  // No access\r
+map    0xE0000 to 0xfffff as rdonly    // 128KB EPROM address space\r
+#define CODE_START 0xE000              // Start of application code\r
+#elif ROM == 256\r
+map    0x00000 to 0x1ffff as rdwr      // 128KB RAM address space\r
+map    0x20000 to 0xBffff as reserved  // No access\r
+map    0xC0000 to 0xfffff as rdonly    // 256KB EPROM address space\r
+#define CODE_START 0xC000                      // Start of application code\r
+#elif ROM == 512\r
+map    0x00000 to 0x1ffff as rdwr                      // 128KB RAM address space\r
+map    0x20000 to 0x7ffff as reserved  // No access\r
+map    0x80000 to 0xfffff as rdonly            // 512KB EPROM address space\r
+#define CODE_START 0x8000                      // Start of application code\r
+#endif\r
+\r
+#define DATA_START             0x0040                  // Start of application data\r
+#define BOOT_START             0xffc0                  // Start of initialization code\r
+\r
+initcode       reset           \ // Reset vector to program entry point\r
+               umcs = 0x80bf   \ // 512K ROM, 3 wait states\r
+               lmcs = 0x7fbf   \ // 512K RAM, 3 wait states\r
+               mpcs = 0xa0bf   \\r
+               mmcs = 0x81ff   \\r
+               pacs = 0x007f\r
+\r
+class  ??LOCATE = BOOT_START           // Chip select initialization\r
+output ??LOCATE\r
+\r
+#if ROM == 32                  // 27C256-90 EPROM or FLASH\r
+hexfile binary offset=0xf8000 size=32  // for 27C256, bin file\r
+#elif ROM == 64                                // 27C512-90 EPROM or FLASH\r
+hexfile binary offset=0xF0000 size=64  // for 27C512\r
+#elif ROM == 128                       // 27C010-90 EPROM or FLASH\r
+hexfile binary offset=0xE0000 size=128 // for 27C010\r
+#elif ROM == 256                       // 27C020-90 EPROM or FLASH\r
+hexfile binary offset=0xC0000 size=256 // for 27C020\r
+#elif ROM == 512                       // 27C040-90 EPROM or FLASH\r
+hexfile Intel86 offset=0x80000 size=512        // for 27C040, output .HEX file\r
+#endif\r
+\r
+#endif\r
+\r
+\r
+//\r
+// Start of common configuration file settings.\r
+//\r
+\r
+absfile        axe86                                                                   // Paradigm C++ debugging output\r
+listfile       segments                                                                // Absolute segment map\r
+\r
+dup            DATA ROMDATA            // Make a copy of initialized data\r
+dup            FAR_DATA ROMFARDATA     // Make a copy of far initialized data\r
+\r
+#if defined(__COMPFARDATA__)           // Compress and display results\r
+compress       ROMFARDATA\r
+display        compression\r
+#endif\r
+\r
+class          CODE = CODE_START       // Application code\r
+class          DATA = DATA_START       // Application data\r
+\r
+order          DATA                                                            \       // RAM class organization\r
+                       BSS                     \\r
+                       NVRAM                   \\r
+                       EDATA                   \\r
+                       STACK                   \\r
+                       FAR_DATA ENDFAR_DATA    \\r
+                       FAR_BSS ENDFAR_BSS      \\r
+                       FAR_HEAP ENDFAR_HEAP\r
+\r
+order          CODE                            \       // EPROM class organization\r
+                       INITDATA EXITDATA       \\r
+                       FAR_CONST ENDFAR_CONST  \\r
+                       ROMDATA ENDROMDATA      \\r
+                       ROMFARDATA ENDROMFARDATA\r
+\r
+output CODE                                    \       // Classes in the output file(s)\r
+                       INITDATA EXITDATA       \\r
+                       FAR_CONST ENDFAR_CONST  \\r
+                       ROMDATA ENDROMDATA      \\r
+                       ROMFARDATA ENDROMFARDATA\r
+\1a
\ No newline at end of file
diff --git a/Demo/WizNET_DEMO_TERN_186/AE.LIB b/Demo/WizNET_DEMO_TERN_186/AE.LIB
new file mode 100644 (file)
index 0000000..dcfffa1
Binary files /dev/null and b/Demo/WizNET_DEMO_TERN_186/AE.LIB differ
diff --git a/Demo/WizNET_DEMO_TERN_186/FreeRTOSConfig.h b/Demo/WizNET_DEMO_TERN_186/FreeRTOSConfig.h
new file mode 100644 (file)
index 0000000..2a1e99c
--- /dev/null
@@ -0,0 +1,77 @@
+/*\r
+       FreeRTOS V4.0.1 - Copyright (C) 2003-2006 Richard Barry.\r
+\r
+       This file is part of the FreeRTOS distribution.\r
+\r
+       FreeRTOS is free software; you can redistribute it and/or modify\r
+       it under the terms of the GNU General Public License as published by\r
+       the Free Software Foundation; either version 2 of the License, or\r
+       (at your option) any later version.\r
+\r
+       FreeRTOS is distributed in the hope that it will be useful,\r
+       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+       GNU General Public License for more details.\r
+\r
+       You should have received a copy of the GNU General Public License\r
+       along with FreeRTOS; if not, write to the Free Software\r
+       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+       A special exception to the GPL can be applied should you wish to distribute\r
+       a combined work that includes FreeRTOS, without being obliged to provide\r
+       the source code for any proprietary components.  See the licensing section \r
+       of http://www.FreeRTOS.org for full details of how and when the exception\r
+       can be applied.\r
+\r
+       ***************************************************************************\r
+       See http://www.FreeRTOS.org for documentation, latest information, license \r
+       and contact details.  Please ensure to read the configuration and relevant \r
+       port sections of the online documentation.\r
+       ***************************************************************************\r
+*/\r
+\r
+#ifndef FREERTOS_CONFIG_H\r
+#define FREERTOS_CONFIG_H\r
+\r
+/*-----------------------------------------------------------\r
+ * Application specific definitions.\r
+ *\r
+ * These definitions should be adjusted for your particular hardware and\r
+ * application requirements.\r
+ *\r
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE\r
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. \r
+ *----------------------------------------------------------*/\r
+\r
+#define configUSE_PREEMPTION           1\r
+#define configUSE_IDLE_HOOK                    1\r
+#define configUSE_TICK_HOOK                    0\r
+#define configCPU_CLOCK_HZ                     ( ( unsigned portLONG ) 80000000 )\r
+#define configTICK_RATE_HZ                     ( ( portTickType ) 1000 )\r
+#define configMAX_PRIORITIES           ( ( unsigned portBASE_TYPE ) 5 )\r
+#define configMINIMAL_STACK_SIZE       ( ( unsigned portSHORT ) 256 ) /* This can be made smaller if required. */\r
+#define configTOTAL_HEAP_SIZE          ( ( size_t ) ( 20 * 1024 ) ) \r
+#define configMAX_TASK_NAME_LEN                ( 16 )\r
+#define configUSE_TRACE_FACILITY       1\r
+#define configUSE_16_BIT_TICKS         0\r
+#define configIDLE_SHOULD_YIELD                1\r
+\r
+/* Co-routine definitions. */\r
+#define configUSE_CO_ROUTINES          0\r
+#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )\r
+\r
+/* Set the following definitions to 1 to include the API function, or zero\r
+to exclude the API function. */\r
+\r
+#define INCLUDE_vTaskPrioritySet        1\r
+#define INCLUDE_uxTaskPriorityGet       1\r
+#define INCLUDE_vTaskDelete             1\r
+#define INCLUDE_vTaskCleanUpResources   1\r
+#define INCLUDE_vTaskSuspend            1\r
+#define INCLUDE_vTaskDelayUntil                        1\r
+#define INCLUDE_vTaskDelay                             1\r
+\r
+\r
+\r
+\r
+#endif /* FREERTOS_CONFIG_H */\r
diff --git a/Demo/WizNET_DEMO_TERN_186/HTTPTask.c b/Demo/WizNET_DEMO_TERN_186/HTTPTask.c
new file mode 100644 (file)
index 0000000..c3384d4
--- /dev/null
@@ -0,0 +1,289 @@
+/*\r
+       FreeRTOS V4.0.1 - Copyright (C) 2003-2006 Richard Barry.\r
+\r
+       This file is part of the FreeRTOS distribution.\r
+\r
+       FreeRTOS is free software; you can redistribute it and/or modify\r
+       it under the terms of the GNU General Public License as published by\r
+       the Free Software Foundation; either version 2 of the License, or\r
+       (at your option) any later version.\r
+\r
+       FreeRTOS is distributed in the hope that it will be useful,\r
+       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+       GNU General Public License for more details.\r
+\r
+       You should have received a copy of the GNU General Public License\r
+       along with FreeRTOS; if not, write to the Free Software\r
+       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+       A special exception to the GPL can be applied should you wish to distribute\r
+       a combined work that includes FreeRTOS, without being obliged to provide\r
+       the source code for any proprietary components.  See the licensing section \r
+       of http://www.FreeRTOS.org for full details of how and when the exception\r
+       can be applied.\r
+\r
+       ***************************************************************************\r
+       See http://www.FreeRTOS.org for documentation, latest information, license \r
+       and contact details.  Please ensure to read the configuration and relevant \r
+       port sections of the online documentation.\r
+       ***************************************************************************\r
+*/\r
+\r
+/* \r
+ * Very simple task that responds with a single WEB page to http requests.\r
+ *\r
+ * The WEB page displays task and system status.  A semaphore is used to \r
+ * wake the task when there is processing to perform as determined by the \r
+ * interrupts generated by the Ethernet interface.\r
+ */\r
+\r
+/* Standard includes. */\r
+#include <string.h>\r
+#include <stdio.h>\r
+\r
+/* Tern includes. */\r
+#include "utils\system_common.h"\r
+#include "i2chip_hw.h"\r
+#include "socket.h"\r
+\r
+/* FreeRTOS.org includes. */\r
+#include <FreeRTOS.h>\r
+#include <task.h>\r
+#include <semphr.h>\r
+\r
+/* The standard http port on which we are going to listen. */\r
+#define httpPORT 80\r
+\r
+#define httpTX_WAIT 2\r
+\r
+/* Network address configuration. */\r
+const unsigned portCHAR ucMacAddress[] =                       { 12, 128, 12, 34, 56, 78 };\r
+const unsigned portCHAR ucGatewayAddress[] =           { 192, 168, 2, 1 };\r
+const unsigned portCHAR ucIPAddress[] =                                { 172, 25, 218, 210 };\r
+const unsigned portCHAR ucSubnetMask[] =                       { 255, 255, 255, 0 };\r
+\r
+/* The number of sockets this task is going to handle. */\r
+#define httpSOCKET_NUM                       3\r
+unsigned portCHAR ucConnection[ httpSOCKET_NUM ];\r
+\r
+/* The maximum data buffer size we can handle. */\r
+#define httpSOCKET_BUFFER_SIZE 2048\r
+\r
+/* Standard HTTP response. */\r
+#define httpOUTPUT_OK  "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n"\r
+\r
+/* Hard coded HTML components.  Other data is generated dynamically. */\r
+#define HTML_OUTPUT_BEGIN "\\r
+<HTML><head><meta http-equiv=\"Refresh\" content=\"1\;url=index.htm\"></head>\\r
+<BODY bgcolor=\"#CCCCFF\"><font face=\"arial\"><H2>FreeRTOS.org<sup>tm</sup> + Tern E-Engine<sup>tm</sup></H2>\\r
+<a href=\"http:\/\/www.FreeRTOS.org\">FreeRTOS.org Homepage</a><P>\\r
+<HR>Task status table:\r\n\\r
+<p><font face=\"courier\"><pre>Task          State  Priority  Stack    #<br>\\r
+************************************************<br>"\r
+\r
+#define HTML_OUTPUT_END   "\\r
+</font></BODY></HTML>"\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Initialise the data structures used to hold the socket status.\r
+ */\r
+static void prvHTTPInit( void );\r
+\r
+/*\r
+ * Setup the Ethernet interface with the network addressing information.\r
+ */\r
+static void prvNetifInit( void );\r
+\r
+/*\r
+ * Generate the dynamic components of the served WEB page and transmit the \r
+ * entire page through the socket.\r
+ */\r
+static void prvTransmitHTTP( unsigned portCHAR socket );\r
+/*-----------------------------------------------------------*/\r
+\r
+/* This variable is simply incremented by the idle task hook so the number of\r
+iterations the idle task has performed can be displayed as part of the served\r
+page. */\r
+unsigned portLONG ulIdleLoops = 0UL;\r
+\r
+/* Data buffer shared by sockets. */\r
+unsigned portCHAR ucSocketBuffer[ httpSOCKET_BUFFER_SIZE ];\r
+\r
+/* The semaphore used by the Ethernet ISR to signal that the task should wake\r
+and process whatever caused the interrupt. */\r
+xSemaphoreHandle xTCPSemaphore = NULL;\r
+\r
+/*-----------------------------------------------------------*/\r
+void vHTTPTask( void * pvParameters )\r
+{\r
+portSHORT i, sLen;\r
+unsigned portCHAR ucState;\r
+\r
+       ( void ) pvParameters;\r
+\r
+    /* Create the semaphore used to communicate between this task and the\r
+    WIZnet ISR. */\r
+    vSemaphoreCreateBinary( xTCPSemaphore );\r
+\r
+       /* Make sure everything is setup before we start. */\r
+       prvNetifInit();\r
+       prvHTTPInit();\r
+\r
+       for( ;; )\r
+       {\r
+               /* Wait until the ISR tells us there is something to do. */\r
+       xSemaphoreTake( xTCPSemaphore, portMAX_DELAY );\r
+\r
+               /* Check each socket. */\r
+               for( i = 0; i < httpSOCKET_NUM; i++ )\r
+               {\r
+                       ucState = select( i, SEL_CONTROL );\r
+\r
+                       switch (ucState)\r
+                       {\r
+                               case SOCK_ESTABLISHED :  /* new connection established. */\r
+\r
+                                       if( ( sLen = select( i, SEL_RECV ) ) > 0 )\r
+                                       {\r
+                                               if( sLen > httpSOCKET_BUFFER_SIZE ) \r
+                                               {\r
+                                                       sLen = httpSOCKET_BUFFER_SIZE;\r
+                                               }\r
+\r
+                                               disable();\r
+                                               \r
+                                               sLen = recv( i, ucSocketBuffer, sLen );    \r
+\r
+                                               if( ucConnection[ i ] == 1 )\r
+                                               {       \r
+                                                       /* This is our first time processing a HTTP\r
+                                                        request on this connection. */\r
+                                                       prvTransmitHTTP( i );\r
+                                                       ucConnection[i] = 0;\r
+                                               }\r
+                                               enable();\r
+                                       }\r
+                                       break;\r
+\r
+                               case SOCK_CLOSE_WAIT :\r
+\r
+                                       close(i);\r
+                                       break;\r
+\r
+                               case SOCK_CLOSED :\r
+\r
+                                       ucConnection[i] = 1;\r
+                                       socket( i, SOCK_STREAM, 80, 0x00 );\r
+                                       NBlisten( i ); /* reinitialize socket. */\r
+                                       break;\r
+                       }\r
+               }\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvHTTPInit( void )\r
+{\r
+unsigned portCHAR ucIndex;\r
+\r
+       /* There are 4 total sockets available; we will claim 3 for HTTP. */\r
+       for(ucIndex = 0; ucIndex < httpSOCKET_NUM; ucIndex++)\r
+       {\r
+               socket( ucIndex, SOCK_STREAM, httpPORT, 0x00 );\r
+               NBlisten( ucIndex );\r
+               ucConnection[ ucIndex ] = 1;\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvNetifInit( void )\r
+{\r
+       i2chip_init();\r
+       initW3100A();\r
+\r
+       setMACAddr( ( unsigned portCHAR * ) ucMacAddress );\r
+       setgateway( ( unsigned portCHAR * ) ucGatewayAddress );\r
+       setsubmask( ( unsigned portCHAR * ) ucSubnetMask );\r
+       setIP( ( unsigned portCHAR * ) ucIPAddress );\r
+\r
+       /* See definition of 'sysinit' in socket.c\r
+        - 8 KB transmit buffer, and 8 KB receive buffer available.  These buffers\r
+          are shared by all 4 channels.\r
+        - (0x55, 0x55) configures the send and receive buffers at \r
+               httpSOCKET_BUFFER_SIZE bytes for each of the 4 channels. */\r
+       sysinit( 0x55, 0x55 );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvTransmitHTTP(unsigned portCHAR socket)\r
+{\r
+extern portSHORT usCheckStatus;\r
+\r
+       /* Send the http and html headers. */\r
+       send( socket, ( unsigned portCHAR * ) httpOUTPUT_OK, strlen( httpOUTPUT_OK ) );\r
+       send( socket, ( unsigned portCHAR * ) HTML_OUTPUT_BEGIN, strlen( HTML_OUTPUT_BEGIN ) );\r
+\r
+       /* Generate then send the table showing the status of each task. */\r
+       vTaskList( ucSocketBuffer );\r
+       send( socket, ( unsigned portCHAR * ) ucSocketBuffer, strlen( ucSocketBuffer ) );\r
+\r
+       /* Send the number of times the idle task has looped. */\r
+    sprintf( ucSocketBuffer, "</pre></font><p><br>The idle task has looped 0x%08lx times<br>", ulIdleLoops );\r
+       send( socket, ( unsigned portCHAR * ) ucSocketBuffer, strlen( ucSocketBuffer ) );\r
+\r
+       /* Send the tick count. */\r
+    sprintf( ucSocketBuffer, "The tick count is 0x%08lx<br>", xTaskGetTickCount() );\r
+       send( socket, ( unsigned portCHAR * ) ucSocketBuffer, strlen( ucSocketBuffer ) );\r
+\r
+       /* Show a message indicating whether or not the check task has discovered \r
+       an error in any of the standard demo tasks. */\r
+    if( usCheckStatus == 0 )\r
+    {\r
+           sprintf( ucSocketBuffer, "No errors detected." );\r
+               send( socket, ( unsigned portCHAR * ) ucSocketBuffer, strlen( ucSocketBuffer ) );\r
+    }\r
+    else\r
+    {\r
+           sprintf( ucSocketBuffer, "<font color=\"red\">An error has been detected in at least one task %x.</font><p>", usCheckStatus );\r
+               send( socket, ( unsigned portCHAR * ) ucSocketBuffer, strlen( ucSocketBuffer ) );\r
+    }\r
+\r
+       /* Finish the page off. */\r
+       send( socket, (unsigned portCHAR*)HTML_OUTPUT_END, strlen(HTML_OUTPUT_END));\r
+\r
+       /* Must make sure the data is gone before closing the socket. */\r
+       while( !tx_empty( socket ) )\r
+    {\r
+       vTaskDelay( httpTX_WAIT );\r
+    }\r
+       close(socket);\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationIdleHook( void )\r
+{\r
+       ulIdleLoops++;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
diff --git a/Demo/WizNET_DEMO_TERN_186/HTTPTask.h b/Demo/WizNET_DEMO_TERN_186/HTTPTask.h
new file mode 100644 (file)
index 0000000..3961fb1
--- /dev/null
@@ -0,0 +1,39 @@
+/*\r
+       FreeRTOS V4.0.1 - Copyright (C) 2003-2006 Richard Barry.\r
+\r
+       This file is part of the FreeRTOS distribution.\r
+\r
+       FreeRTOS is free software; you can redistribute it and/or modify\r
+       it under the terms of the GNU General Public License as published by\r
+       the Free Software Foundation; either version 2 of the License, or\r
+       (at your option) any later version.\r
+\r
+       FreeRTOS is distributed in the hope that it will be useful,\r
+       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+       GNU General Public License for more details.\r
+\r
+       You should have received a copy of the GNU General Public License\r
+       along with FreeRTOS; if not, write to the Free Software\r
+       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+       A special exception to the GPL can be applied should you wish to distribute\r
+       a combined work that includes FreeRTOS, without being obliged to provide\r
+       the source code for any proprietary components.  See the licensing section \r
+       of http://www.FreeRTOS.org for full details of how and when the exception\r
+       can be applied.\r
+\r
+       ***************************************************************************\r
+       See http://www.FreeRTOS.org for documentation, latest information, license \r
+       and contact details.  Please ensure to read the configuration and relevant \r
+       port sections of the online documentation.\r
+       ***************************************************************************\r
+*/\r
+\r
+#ifndef HTTP_TASK_H\r
+#define HTTP_TASK_H\r
+\r
+void vHTTPTask( void *pvParameters );\r
+\r
+#endif\r
+\r
diff --git a/Demo/WizNET_DEMO_TERN_186/RTOSDemo.DSW b/Demo/WizNET_DEMO_TERN_186/RTOSDemo.DSW
new file mode 100644 (file)
index 0000000..789ec35
Binary files /dev/null and b/Demo/WizNET_DEMO_TERN_186/RTOSDemo.DSW differ
diff --git a/Demo/WizNET_DEMO_TERN_186/RTOSDemo.ide b/Demo/WizNET_DEMO_TERN_186/RTOSDemo.ide
new file mode 100644 (file)
index 0000000..e231813
Binary files /dev/null and b/Demo/WizNET_DEMO_TERN_186/RTOSDemo.ide differ
diff --git a/Demo/WizNET_DEMO_TERN_186/RTOSDemo.mbt b/Demo/WizNET_DEMO_TERN_186/RTOSDemo.mbt
new file mode 100644 (file)
index 0000000..9af2d52
Binary files /dev/null and b/Demo/WizNET_DEMO_TERN_186/RTOSDemo.mbt differ
diff --git a/Demo/WizNET_DEMO_TERN_186/RTOSDemo.mrt b/Demo/WizNET_DEMO_TERN_186/RTOSDemo.mrt
new file mode 100644 (file)
index 0000000..6fe70dd
Binary files /dev/null and b/Demo/WizNET_DEMO_TERN_186/RTOSDemo.mrt differ
diff --git a/Demo/WizNET_DEMO_TERN_186/RTOSDemo.rom b/Demo/WizNET_DEMO_TERN_186/RTOSDemo.rom
new file mode 100644 (file)
index 0000000..74ecd1f
Binary files /dev/null and b/Demo/WizNET_DEMO_TERN_186/RTOSDemo.rom differ
diff --git a/Demo/WizNET_DEMO_TERN_186/i2chip_hw.c b/Demo/WizNET_DEMO_TERN_186/i2chip_hw.c
new file mode 100644 (file)
index 0000000..eb513ef
--- /dev/null
@@ -0,0 +1,239 @@
+/*\r
+********************************************************************************\r
+* TERN, Inc.\r
+* (c) Copyright 2005, http://www.tern.com\r
+*\r
+* - Created to support i2chip module on a variety of TERN hardware platforms.\r
+********************************************************************************\r
+*/\r
+\r
+#include <embedded.h>\r
+#include "i2chip_hw.h"\r
+\r
+#ifdef I2CHIP_MMC\r
+#include "mmc.h"\r
+#endif\r
+\r
+void i2chip_init(void)\r
+{\r
+\r
+#ifdef TERN_586\r
+/*\r
+       poke(MMCR,_BOOTCSCTL_,peek(MMCR,_BOOTCSCTL_)&0xffc9);   // ROM 1 wait\r
+       poke(MMCR,_ROMCS2CTL_,peek(MMCR,_ROMCS2CTL_)&0xffc8);   // SRAM 0 wait\r
+\r
+       pokeb(MMCR,     _GPCSRT_, 24); // set the GP CS recovery time, 12 works\r
+       pokeb(MMCR,     _GPCSPW_, 128); // set the GP CS width, 64 works\r
+       pokeb(MMCR,     _GPCSOFF_, 16); // set the GP CS offset, 8 works\r
+       pokeb(MMCR,     _GPRDW_, 80); // set the GP RD pulse width, 50 works\r
+       pokeb(MMCR,     _GPRDOFF_, 30); // set the GP RD offset, 15 works\r
+       pokeb(MMCR,     _GPWRW_, 80); // set the GP WR pulse width, 50\r
+       pokeb(MMCR,     _GPWROFF_, 30); // set the GP WR offset, 15\r
+*/\r
+\r
+#ifdef TERN_5E\r
+       pokeb(MMCR,     _GPCSDW_, peekb(MMCR, _GPCSDW_)&0xf7); // set /CS3-/CSM Data Width=8\r
+       pokeb(MMCR,     _CSPFS_, peekb(MMCR, _CSPFS_)|0x08); // set the GP CS3 PIN Function\r
+       poke(MMCR,      _PAR15_, 0x2000); // set CS3 I/O region\r
+       poke(MMCR,      _PAR15_+2, 0x2dff); // set CS3 I/O region, 512 bytes\r
+\r
+       pokeb(MMCR,     _GPCSDW_, peekb(MMCR, _GPCSDW_)&0x7f); // CS7=J4.3 Data Width=8, /CSI\r
+//     pokeb(MMCR,     _GPCSDW_, peekb(MMCR, _GPCSDW_)|0x80); // CS7=J4.3 Data Width=16\r
+       pokeb(MMCR,     _CSPFS_, peekb(MMCR, _CSPFS_)|0x80); // set the GP CS7 PIN Function\r
+       poke(MMCR,      _PAR7_, 0x4000); // set CS7 I/O region\r
+       poke(MMCR,      _PAR7_+2, 0x3dff); // set CS7 I/O region, 512 bytes\r
+#else\r
+   // If it's not 5E, then it must be 5P... in which case, we use PCS0 and\r
+   // PCS1 as the chip-selects.\r
+       pokeb(MMCR,     _GPCSDW_, peekb(MMCR, _GPCSDW_)&0xfe); // CS0 Data Width=8\r
+       poke(MMCR, _PIOPFS31_16_, peek(MMCR,_PIOPFS31_16_)|0x0800); // P27=/CS0\r
+       poke(MMCR,      _PAR13_, 0x1800); // CS0 I/O region\r
+       poke(MMCR,      _PAR13_+2, 0x21ff); // CS0 I/O RW, 512 bytes, start 0x1800\r
+#endif\r
+\r
+a      HLPRsetvect(0x47, (void far *) spu_m_isr);\r
+       HLPRsetvect(0x4f, (void far *) spu_1_isr);\r
+       HLPRsetvect(0x57, (void far *) spu_2_isr);\r
+#endif  // 186, or RE\r
+\r
+#ifdef TERN_186\r
+   pio_init(18, 0);    //      P18=CTS1 for /PCS2\r
+\r
+#ifdef TERN_16_BIT\r
+       outport(0xfff2, 2);     // AUXCON, MCS, Bus 16-bit\r
+#endif\r
+\r
+#ifdef I2CHIP_MCS_DIRECT\r
+       outport(0xffa0,0xc0bf);                                                      // UMCS, 256K ROM, disable AD15-0\r
+       outport(0xfff0,inport(0xfff0)|0x4000 );        // SYSCON, MCS0 0x80000-0xbffff\r
+       outport(0xffa8,0xa0bf );                                                // MPCS, MCS0=P14, 64KB, PCS I/O,\r
+       outport(0xffa6,0x81ff);                                                      // MMCS, base 0x80000,\r
+       outport(0xffa2,0x7fbf);                                                 // 512K RAM,\r
+       outport(0xffa4,0x007d);                                                      // PACS, base 0,\r
+       \r
+#else\r
+\r
+       outport( 0xffa0,0xc0bf); // UMCS, 256K ROM, 3 wait, disable AD15-0\r
+       outport( 0xfff0,inport(0xfff0)|0x4000 ); // SYSCON, MCS0 0x80000-0xbffff\r
+//   outport( 0xffa8,0xa0bc ); // MPCS, MCS0=P14, 64KB, PCS I/O 0 wait\r
+//     outport( 0xffa8,0xa0bd ); // MPCS, MCS0=P14, 64KB, PCS I/O 1 wait\r
+       outport( 0xffa8,0xa0bf ); // MPCS, MCS0=P14, 64KB, PCS I/O 1 wait\r
+#endif // I2CHIP_MCS_DIRECT\r
+\r
+#ifndef TERN_RE   // 80 MHz R- boards can't tolerate zero wait state.\r
+       outport( 0xffa6,0x81ff ); // MMCS, base 0x80000\r
+       outport(0xffa2,0x7fbe); // 512K RAM, 0 wait states\r
+       outport(0xffa4,0x007d); // PACS, base 0, 0 wait\r
+#endif\r
+       pio_init(14,0);                                                                              //  Enable /MCS0\r
+\r
+#endif // TERN_186\r
+\r
+\r
+#ifdef I2CHIP_WINDOW\r
+#ifdef I2CHIP_SHIFTED_ADDRESS\r
+       pio_init(12, 2); // Configure P12 as A7, an output we'll be using.\r
+   pio_wr(12, 0);   // Set A7 low, initially.\r
+#endif\r
+       WINDOW_RESTORE_BASE;    // Equivalent to calling mmc_window(7, 0);\r
+#endif\r
+}\r
+\r
+#ifdef I2CHIP_WINDOW\r
+\r
+void i2chip_set_page(u_int page)\r
+{\r
+       u_int new_page = page;\r
+\r
+#ifdef   I2CHIP_SHIFTED_ADDRESS\r
+       if (page & 0x01)   // ... we're checking the right-most bit in the page.\r
+       outport(0xff74, inport(0xff74) | 0x1000 ); // Using P12 as A7...\r
+   else\r
+       outport(0xff74, inport(0xff74) & 0xefff );\r
+\r
+   new_page = page >> 1;\r
+#endif\r
+\r
+#ifdef   I2CHIP_MMC\r
+       mmc_window(7, new_page);   // See mmc.c\r
+#endif\r
+#ifdef   I2CHIP_P51\r
+       p51_window(new_page);\r
+#endif\r
+}\r
+\r
+static u_int s_addr = 0xffff;\r
+u_char far* i2chip_mkptr(u_int addr)\r
+{\r
+       if ((s_addr & 0xff00) == (addr & 0xff00)) // No point... no point...\r
+               return MK_FP(WINDOW_BASE_SEGM, addr & 0xff);\r
+\r
+       s_addr = addr ;\r
+\r
+       // So the argument to this function is... what again?\r
+   // I think it should be the highest 16-bits... or, in other words,\r
+   // FP_SEG of a huge ptr.\r
+   // Ok, and the *return* value should be a UINT value for the new\r
+   // segment address to be used, if it's at all needed.  TODO\r
+   I2CHIP_SET_PAGE(s_addr >> 8);  // Portable version\r
+//     outportb(0x00, addr>>8); // quicker version\r
+\r
+       return MK_FP(WINDOW_BASE_SEGM, addr & 0xff);\r
+}\r
+\r
+void i2chip_set_window(u_int window_addr)\r
+{\r
+       s_addr = window_addr;\r
+   I2CHIP_SET_PAGE(s_addr >> 8);\r
+}\r
+\r
+// Still inside #define I2CHIP_WINDOW ...\r
+\r
+u_int i2chip_get_window(void)\r
+{\r
+   return s_addr & 0xff00;\r
+}\r
+\r
+void i2chip_push_window(u_int addr)\r
+{\r
+       I2CHIP_SET_PAGE(addr>>8);\r
+}\r
+\r
+void i2chip_pop_window(void)\r
+{\r
+       I2CHIP_SET_PAGE(s_addr >> 8);\r
+}\r
+\r
+#ifdef I2CHIP_WINDOW_IO\r
+u_char   io_read_value(u_char far* addr)\r
+{\r
+       // return value ... we assume the page is already set.  So, instead,\r
+   // we just go ahead and output valeu.\r
+   return inportb(I2CHIP_BASE_SEG + (FP_OFF(addr) & 0xff));\r
+}\r
+\r
+void     io_write_value(u_char far* addr, u_char value)\r
+{\r
+       // Get the last whatever bytes... and write value.\r
+       outportb(I2CHIP_BASE_SEG + (FP_OFF(addr) & 0xff), value);\r
+}\r
+\r
+#endif // I2CHIP_WINDOW_IO\r
+\r
+\r
+#ifdef   I2CHIP_P51\r
+void p51_window(unsigned int page)\r
+{\r
+asm xor ax, ax\r
+asm mov ax, page\r
+#ifdef   I2CHIP_WINDOW_IO\r
+asm mov dx, 1040h\r
+asm out dx, al\r
+#else\r
+asm out 040h, al\r
+#endif\r
+// use J1.19=/CS6\r
+}\r
+#endif  // I2CHIP_P51\r
+\r
+#endif // I2CHIP_WINDOW\r
+\r
+#ifdef TERN_586\r
+/*\r
+//     Function: spu_m_isr\r
+//     P22=Master PIC IR7, interrupt vector=0x47, /INTA\r
+*/\r
+void interrupt far spu_m_isr(void)\r
+{\r
+disable();\r
+// Issue the EOI to interrupt controller\r
+outportb(_MPICOCW2_IO,0x67); // Specific EQI for master IR7\r
+enable();\r
+}\r
+\r
+/*\r
+//     Function: spu_1_isr\r
+//     P10=slave1 PIC IR7, Master IR2, interrupt vector=0x4f, /INTC\r
+*/\r
+void interrupt far spu_1_isr(void)\r
+{\r
+disable();\r
+// Issue the EOI to interrupt controller\r
+       outportb(_S1PICOCW2_IO,0x67);   // Specific EOI for slave 1 IR7\r
+       outportb(_MPICOCW2_IO,0x62); // Specific EQI for master IR2\r
+enable();\r
+}\r
+\r
+/*\r
+//     Function: spu_2_isr\r
+//     P20=Slave2 PIC IR7, Master IR5, interrupt vector=0x57, GPIRQ7=PIO16 GP timer1\r
+*/\r
+void interrupt far spu_2_isr(void)\r
+{\r
+disable();\r
+// Issue the EOI to interrupt controller\r
+       outportb(_S2PICOCW2_IO,0x67);   // Specific EOI for slave 1 IR7\r
+       outportb(_MPICOCW2_IO,0x65); // Specific EQI for master IR5\r
+enable();\r
+}\r
+#endif\r
diff --git a/Demo/WizNET_DEMO_TERN_186/include/SOCKET.H b/Demo/WizNET_DEMO_TERN_186/include/SOCKET.H
new file mode 100644 (file)
index 0000000..b3f7b6c
--- /dev/null
@@ -0,0 +1,247 @@
+/*\r
+********************************************************************************\r
+* TERN, Inc.\r
+* (c) Copyright 2005, http://www.tern.com\r
+*\r
+* - Derived based on development version provided by Wiznet.\r
+*\r
+* Filename : socket.h\r
+* Programmer(s):\r
+* Created : 2002/06/20\r
+* Modified :\r
+*  2002/09/27 : - Renaming\r
+*                             INT_STATUS --> INT_REG\r
+*                             STATUS(i) --> INT_STATUS(i)\r
+*                             C_STATUS(i) --> SOCK_STATUS(i)\r
+*  2003/11/06 : Ported for use with TERN controller.  Note all byte access is at even addresses\r
+*  2005/10/8  : Modified constants for easier initialization.\r
+*\r
+* Description : Header file of W3100A for TERN embedded controller\r
+********************************************************************************\r
+*/\r
+#ifndef        __SOCKET_H__\r
+#define        __SOCKET_H__\r
+\r
+#include "types.h"\r
+#include "i2chip_hw.h"\r
+#include <dos.h>\r
+\r
+/*******************************************************************/\r
+#define        MAX_SOCK_NUM    4                                       // Concurrent maxmium number of socket\r
+\r
+#define I2CHIP_C0_CR       0x00\r
+#define I2CHIP_C1_CR       0x01\r
+#define I2CHIP_C2_CR       0x02\r
+#define I2CHIP_C3_CR       0x03\r
+#define I2CHIP_C0_ISR      0x04\r
+#define I2CHIP_C1_ISR      0x05\r
+#define I2CHIP_C2_ISR      0x06\r
+#define I2CHIP_C3_ISR      0x07\r
+#define I2CHIP_IR          0x08\r
+#define I2CHIP_IMR         0x09\r
+\r
+#define I2CHIP_IDM_OR          0x0C\r
+#define I2CHIP_IDM_AR0     0x0D\r
+#define I2CHIP_IDM_AR1     0x0E\r
+#define I2CHIP_IDM_DR      0x0F\r
+#define I2CHIP_C0_RW_PR    0x10\r
+#define I2CHIP_C0_RR_PR    0x14\r
+#define I2CHIP_C0_TA_PR    0x18\r
+#define I2CHIP_C1_RW_PR    0x1C\r
+#define I2CHIP_C1_RR_PR    0x20\r
+#define I2CHIP_C1_TA_PR    0x24\r
+#define I2CHIP_C2_RW_PR    0x28\r
+#define I2CHIP_C2_RR_PR    0x2C\r
+#define I2CHIP_C2_TA_PR    0x30\r
+#define I2CHIP_C3_RW_PR    0x34\r
+#define I2CHIP_C3_RR_PR    0x38\r
+#define I2CHIP_C3_TA_PR    0x3C\r
+#define I2CHIP_C0_TW_PR    0x40\r
+#define I2CHIP_C0_TR_PR    0x44\r
+#define I2CHIP_C1_TW_PR    0x4C\r
+#define I2CHIP_C1_TR_PR    0x50\r
+#define I2CHIP_C2_TW_PR    0x58\r
+#define I2CHIP_C2_TR_PR    0x5C\r
+#define I2CHIP_C3_TW_PR    0x64\r
+#define I2CHIP_C3_TR_PR    0x68\r
+#define I2CHIP_GAR         0x80\r
+#define I2CHIP_SMR         0x84\r
+#define I2CHIP_SHAR            0x88\r
+#define I2CHIP_SIPR        0x8E\r
+#define I2CHIP_IRTR        0x92\r
+#define I2CHIP_RCR         0x94\r
+#define I2CHIP_RMSR        0x95\r
+#define I2CHIP_TMSR        0x96\r
+#define I2CHIP_C0_SSR      0xA0\r
+#define I2CHIP_C0_SOPR     0xA1\r
+#define I2CHIP_C0_DIR      0xA8\r
+#define I2CHIP_CO_DPR      0xAC\r
+#define I2CHIP_C0_SPR      0xAE\r
+#define I2CHIP_C0_IPR      0xB0\r
+#define I2CHIP_C0_TOSR     0xB1\r
+#define I2CHIP_C0_MSSR     0xB2\r
+\r
+#define I2CHIP_C1_SSR      0xB8\r
+#define I2CHIP_C1_SOPR     0xB9\r
+#define I2CHIP_C1_DIR      0xC0\r
+#define I2CHIP_C1_DPR      0xC4\r
+#define I2CHIP_C1_SPR      0xC6\r
+#define I2CHIP_C1_IPR      0xC8\r
+#define I2CHIP_C1_TOSR     0xC9\r
+#define I2CHIP_C1_MSSR     0xCA\r
+\r
+#define I2CHIP_C2_SSR      0xD0\r
+#define I2CHIP_C2_SOPR     0xD1\r
+#define I2CHIP_C2_DIR      0xD8\r
+#define I2CHIP_C2_DPR      0xDC\r
+#define I2CHIP_C2_SPR      0xDE\r
+#define I2CHIP_C2_IPR      0xE0\r
+#define I2CHIP_C2_TOSR     0xE1\r
+#define I2CHIP_C2_MSSR     0xE2\r
+\r
+#define I2CHIP_C3_SSR      0xE8\r
+#define I2CHIP_C3_SOPR     0xE9\r
+#define I2CHIP_C3_DIR      0xF0\r
+#define I2CHIP_C3_DPR      0xF4\r
+#define I2CHIP_C3_SPR      0xF6\r
+#define I2CHIP_C3_IPR      0xF8\r
+#define I2CHIP_C3_TOSR     0xF9\r
+#define I2CHIP_C3_MSSR     0xFA\r
+\r
+#define MAX_SEGMENT_SIZE       1460                    // Maximum TCP transmission packet size\r
+#define MAX_BUF_SIZE1          0\r
+\r
+\r
+/* SOCKET OPTION(Settting OPT_PROTOCOL REG.) */\r
+#define SOCKOPT_BROADCAST      0x80            // Transmission, Reception of broadcasting data\r
+#define SOCKOPT_NDTIMEOUT      0x40            // Setting timeout\r
+#define SOCKOPT_NDACK          0x20            // Setting No Delayed Ack(TCP)\r
+#define SOCKOPT_SWS                    0x10            // Setting Silly Window Syndrome(TCP)\r
+\r
+/* OPTION(Setting OPT_PROTOCOL REG.) for MAC LAYER RAW MODE */\r
+#define MACLOPT_RXERR          0x80            // Setting reception of error packet\r
+#define MACLOPT_BROADCAST      0x40            // Setting reception of broadcast packet\r
+#define MACLOPT_PROMISC                0x20            // Setting reception of promiscuous packet\r
+\r
+/* Distinguish TCP / UDP / IP RAW / MAC RAW (Setting OPT_PROTOCOL REG.) */\r
+#define        SOCK_CLOSEDM    0x00                    // unused socket\r
+#define        SOCK_STREAM             0x01                    // TCP\r
+#define        SOCK_DGRAM              0x02                    // UDP\r
+#define        SOCK_IPL_RAW    0x03                    // IP LAYER RAW SOCK\r
+#define        SOCK_MACL_RAW   0x04                    // MAC LAYER RAW SOCK\r
+\r
+/* Setting IP PROTOCOL */\r
+#define IPPROTO_IP              0               // dummy for IP\r
+#define IPPROTO_ICMP            1               // control message protocol\r
+#define IPPROTO_IGMP            2               // internet group management protocol\r
+#define IPPROTO_GGP             3               // gateway^2 (deprecated)\r
+#define IPPROTO_TCP             6               // tcp\r
+#define IPPROTO_PUP             12              // pup\r
+#define IPPROTO_UDP             17              // user datagram protocol\r
+#define IPPROTO_IDP             22              // xns idp\r
+#define IPPROTO_ND              77              // UNOFFICIAL net disk proto\r
+#define IPPROTO_RAW             255             // raw IP packet\r
+\r
+/* Select parameter to use */\r
+#define SEL_CONTROL    0                       //Confirm socket status\r
+#define SEL_SEND               1                       // Confirm Tx free buffer size\r
+#define SEL_RECV               2                       // Confirm Rx data size\r
+\r
+/* Command variables */\r
+#define CSYS_INIT              0x01       // To set up network information(mac address, gateway address,\r
+                              // subnet mask, source ip)\r
+#define CSOCK_INIT     0x02            // To initialize socket\r
+#define CCONNECT               0x04            // To establish connection as tcp client mode\r
+#define CLISTEN                0x08            // To wait for connection request as tcp server mode\r
+#define CCLOSE                 0x10            // To terminate connection\r
+#define CSEND                  0x20            // To send data\r
+#define CRECV                  0x40            // To receive data\r
+#define CSW_RESET              0x80            // To do software reset\r
+\r
+#define CSET_MEMORY_TEST   0x80     // To set the memory test bit\r
+#define CRESET_MEMORY_TEST 0x00     // To clear the memory test bit\r
+\r
+/* Status Variables */\r
+#define SSYS_INIT_OK           0x01    // Completion of CSYS_INIT command\r
+#define SSOCK_INIT_OK  0x02    // Completion of CSOCK_INIT command\r
+#define SESTABLISHED           0x04    // Completion of connection setup\r
+#define SCLOSED                        0x08    // Completion of CCLOSED command\r
+#define SSEND_OK                  0x20 // Completion of sending data\r
+#define SRECV_OK                  0x40 // Completion of receiving data\r
+\r
+/* Socket Status Vabiables */\r
+#define SOCK_CLOSED               0x00    // Status of connection closed\r
+#define SOCK_ARP                     0x01              // Status of ARP\r
+#define SOCK_LISTEN               0x02         // Status of waiting for TCP connection setup\r
+#define SOCK_SYNSENT              0x03         // Status of setting up TCP connection\r
+#define SOCK_SYNSENT_ACK       0x04            // Status of setting up TCP connection\r
+#define SOCK_SYNRECV              0x05         // Status of setting up TCP connection\r
+#define SOCK_ESTABLISHED       0x06            // Status of TCP connection established\r
+#define SOCK_CLOSE_WAIT                0x07            // Status of closing TCP connection\r
+#define SOCK_LAST_ACK          0x08            // Status of closing TCP connection\r
+#define SOCK_FIN_WAIT1         0x09            // Status of closing TCP connection\r
+#define SOCK_FIN_WAIT2         0x0A            // Status of closing TCP connection\r
+#define SOCK_CLOSING              0x0B         // Status of closing TCP connection\r
+#define SOCK_TIME_WAIT         0x0C            // Status of closing TCP connection\r
+#define SOCK_RESET                0x0D         // Status of closing TCP connection\r
+#define SOCK_INIT                    0x0E              // Status of socket initialization\r
+#define SOCK_UDP                     0x0F              // Status of UDP\r
+#define SOCK_RAW                     0x10              // Status of IP RAW\r
+\r
+/* TERN Behavior Parameters */\r
+#define TERN_TDMA_THRES    10000      // Use DMA for transmits if data > thres bytes.\r
+#define TERN_RDMA_THRES    10000      // Use DMA for receives if data > thres bytes.\r
+                                      // High thres value effectively disables DMA\r
+                                      \r
+void far interrupt in4_isr_i2chip(void);\r
+\r
+//void ISR_ESTABLISHED(SOCKET s);\r
+//void ISR_CLOSED(SOCKET s);\r
+//void ISR_RX(SOCKET s);\r
+\r
+void initW3100A(void);\r
+void sysinit(u_char sbufsize, u_char rbufsize);\r
+void setsubmask(u_char * addr);\r
+void setgateway(u_char * addr);\r
+void setMACAddr(u_char * addr);\r
+void setIP(u_char * addr);\r
+\r
+char socket(SOCKET s, u_char protocol, u_int port, u_char flag);\r
+\r
+void setIPprotocol(SOCKET s, u_char ipprotocol);\r
+\r
+void setINTMask(u_char mask);\r
+void settimeout(u_char * val);\r
+void setTOS(SOCKET s, u_char tos);\r
+\r
+void GetDestAddr(SOCKET s, u_char* addr);\r
+\r
+//void setbroadcast(SOCKET s);\r
+\r
+char connect(SOCKET s, u_char far * addr, u_int port);\r
+char NBconnect(SOCKET s, u_char far * addr, u_int port);\r
+\r
+//char listen(SOCKET s, u_char far * addr, u_int far * port);\r
+char NBlisten(SOCKET s);\r
+\r
+void initseqnum(SOCKET s);\r
+\r
+int send(SOCKET s, u_char far * buf, u_int len);\r
+int send_in(SOCKET s, u_char far * buf, u_int len);\r
+int recv(SOCKET s, u_char far * buf, u_int len);\r
+\r
+u_int sendto(SOCKET , u_char far * buf, u_int, u_char * addr, u_int);\r
+u_int sendto_in(SOCKET , u_char far *, u_int);\r
+u_int recvfrom(SOCKET , u_char far * buf, u_int, u_char * addr, u_int *);\r
+\r
+u_int read_data(SOCKET s, u_int src_offset, u_char far * dst, u_int len);\r
+u_int write_data(SOCKET s, u_char far * src, u_int dst_offset, u_int len);\r
+\r
+void close(SOCKET s);\r
+char reset_sock(SOCKET s);\r
+\r
+u_int select(SOCKET s, u_char func);\r
+void recv_clear(SOCKET s);\r
+u_char tx_empty(SOCKET s);\r
+\r
+#endif // __SOCKET_H__\r
diff --git a/Demo/WizNET_DEMO_TERN_186/include/TYPES.H b/Demo/WizNET_DEMO_TERN_186/include/TYPES.H
new file mode 100644 (file)
index 0000000..eb4551e
--- /dev/null
@@ -0,0 +1,64 @@
+/*\r
+********************************************************************************\r
+* Wiznet.\r
+* 5F Simmtech Bldg., 228-3, Nonhyun-dong, Kangnam-gu,\r
+* Seoul, Korea\r
+*\r
+* (c) Copyright 2002, Wiznet, Seoul, Korea\r
+*\r
+* Filename : types.h\r
+* Programmer(s): \r
+* Created : 2002/01/\r
+* Modified :\r
+* Description : Define of data type.\r
+********************************************************************************\r
+*/\r
+\r
+#ifndef _TYPES_H_\r
+#define _TYPES_H_\r
+\r
+#ifndef NULL\r
+# define NULL          ((void *) 0)\r
+#endif\r
+\r
+typedef enum { false, true } bool;\r
+\r
+#ifndef _SIZE_T\r
+#define _SIZE_T\r
+typedef unsigned int size_t;\r
+#endif\r
+\r
+typedef        unsigned char   BYTE;           // 8-bit value\r
+typedef        unsigned char   UCHAR;          // 8-bit value\r
+typedef                 int    INT;            // 16-bit value\r
+typedef        unsigned int    UINT;           // 16-bit value\r
+typedef        unsigned short  USHORT;         // 16-bit value\r
+typedef        unsigned short  WORD;           // 16-bit value\r
+typedef        unsigned long   ULONG;          // 32-bit value\r
+typedef        unsigned long   DWORD;          // 32-bit value\r
+\r
+// bsd\r
+typedef unsigned char  u_char;         // 8-bit value\r
+typedef unsigned short u_short;        // 16-bit value\r
+typedef unsigned int           u_int;          // 16-bit value\r
+typedef unsigned long  u_long;         // 32-bit value\r
+\r
+typedef UCHAR  SOCKET;\r
+\r
+\r
+/* Type for treating 4 byte variables with byte by byte */\r
+typedef union un_l2cval\r
+  {\r
+  u_long       lVal;\r
+  u_char       cVal[4];\r
+  };\r
+\r
+/* Type for treating 2 byte variables with byte by byte */\r
+typedef union un_i2cval\r
+  {\r
+  u_int        iVal;\r
+  u_char       cVal[2];\r
+  };\r
+\r
+#endif         // _TYPES_H_\r
+\r
diff --git a/Demo/WizNET_DEMO_TERN_186/include/ae.H b/Demo/WizNET_DEMO_TERN_186/include/ae.H
new file mode 100644 (file)
index 0000000..060c7ef
--- /dev/null
@@ -0,0 +1,264 @@
+#ifndef _AE_H_\r
+#define _AE_H_\r
+\r
+/*********************************************************************\r
+       ae.h            headers for AM188ES   6-20-99   7-16-98             \r
+*********************************************************************/\r
+/*  Data structure for Serial operation */\r
+\r
+typedef struct  {\r
+       unsigned char ready;          /* TRUE when ready */\r
+       unsigned char baud;\r
+       unsigned int mode;              \r
+       unsigned char iflag;     /* interrupt status     */\r
+       unsigned char* in_buf;        /* Input buffer */\r
+       unsigned int in_tail;        /* Input buffer TAIL ptr */\r
+       unsigned int in_head;        /* Input buffer HEAD ptr */\r
+       unsigned int in_size;        /* Input buffer size */\r
+       unsigned int in_crcnt;       /* Input <CR> count */\r
+       unsigned char in_mt;          /* Input buffer FLAG */\r
+       unsigned char in_full;        /* input buffer full */\r
+       unsigned char* out_buf;       /* Output buffer */\r
+       unsigned int out_tail;       /* Output buffer TAIL ptr */\r
+       unsigned int out_head;       /* Output buffer HEAD ptr */\r
+       unsigned int out_size;       /* Output buffer size */\r
+       unsigned char out_full;       /* Output buffer FLAG */\r
+       unsigned char out_mt;         /* Output buffer MT */\r
+       unsigned char tmso;     // transmit macro service operation\r
+       unsigned char rts;\r
+       unsigned char dtr;\r
+       unsigned char en485;\r
+       unsigned char err;\r
+       unsigned char node;\r
+       unsigned char cr; /* scc CR register    */\r
+       unsigned char slave;\r
+       unsigned int in_segm;       /* input buffer segment */\r
+       unsigned int in_offs;       /* input buffer offset */\r
+       unsigned int out_segm;       /* output buffer segment */\r
+       unsigned int out_offs;       /* output buffer offset */\r
+       unsigned char byte_delay;       /* V25 macro service byte delay */\r
+} COM;\r
+\r
+\r
+typedef struct{\r
+       unsigned char sec1;\r
+       unsigned char sec10;\r
+       unsigned char min1;\r
+       unsigned char min10;\r
+       unsigned char hour1;\r
+       unsigned char hour10;\r
+       unsigned char day1;\r
+       unsigned char day10;\r
+       unsigned char mon1;\r
+       unsigned char mon10;\r
+       unsigned char year1;\r
+       unsigned char year10; \r
+       unsigned char wk;\r
+} TIM;\r
+\r
+void ae_init(void);\r
+void ae_reset(void);\r
+void led(int i);      //P12 used for led\r
+void delay_ms(int m);\r
+void delay0(unsigned int t);\r
+void   HLPRsetvect(\r
+                               unsigned int    wVec,           /* Interrupt vector number */\r
+                               void    far             *ih             /* Interrupt handler to install */\r
+                       );\r
+\r
+void clka_en(int i);\r
+void clkb_en(int i);\r
+void pwr_save_en(int i);\r
+void hitwd(void);\r
+\r
+//\r
+//     reset ee to remain enabled for reads\r
+//     where s = segment register value pointing to ee starting addr.\r
+//             for example = 0x8000\r
+//\r
+void amd_ee_read_reset(unsigned int s);\r
+\r
+//\r
+//     sec=0x00-0x07 for AM29F010, 16K/sector\r
+//             sec=0   0x00000-0x03fff\r
+//             sec=1   0x04000-0x07fff\r
+//             sec=2   0x08000-0x0bfff\r
+//             sec=3   0x0c000-0x0ffff\r
+//             sec=4   0x10000-0x13fff\r
+//             sec=5   0x14000-0x17fff\r
+//             sec=6   0x18000-0x1bfff\r
+//             sec=7   0x1c000-0x1ffff\r
+//\r
+//     sec=0x10-0x17 for AM29F040\r
+//             sec=10  0x00000-0x0ffff\r
+//             sec=11  0x10000-0x1ffff\r
+//             sec=12  0x20000-0x2ffff\r
+//             sec=13  0x30000-0x3ffff\r
+//             sec=14  0x40000-0x4ffff\r
+//             sec=15  0x50000-0x5ffff\r
+//             sec=16  0x60000-0x6ffff\r
+//             sec=17  0x70000-0x7ffff\r
+//     segm=segment register value pointing to ee address 0\r
+// returns:            if pass, return(0);\r
+//                             if fail, return(1);\r
+//\r
+int amd_ee_sec_erase(unsigned int segm, unsigned char sec );\r
+\r
+//\r
+//     write one byte dat to AM29F040, at address of s:o\r
+//     Approximately 70 us for 0 wait, 80us for 1 wait.\r
+//             where s=segment register, it is fixed to 0x8000\r
+//                             o=offset register\r
+// returns:            if pass, return(0);\r
+//                             if fail, return(1);\r
+//\r
+// Be aware of that a data bit "0" can not be programmed back to a "1" !!!\r
+// Attempting to do so will hang up the system !!!\r
+// you can program the "1"s to "0"s.\r
+// Only erase operation can convert "0"s to "1"s\r
+//\r
+//\r
+\r
+int amd_ee_byte_pro_512(unsigned int s, unsigned int o, unsigned char dat);\r
+\r
+//\r
+//     write one byte dat to AM29F010, at address of s:o, 80us per byte approx.\r
+//             where s=segment register, you may use s=0x8000-0xe000\r
+//                             o=offset register\r
+// returns:            if pass, return(0);\r
+//                             if fail, return(1);\r
+//\r
+// Be aware of that a data bit "0" can not be programmed back to a "1" !!!\r
+// Attempting to do so will hang up the system !!!\r
+// you can program the "1"s to "0"s.\r
+// Only erase operation can convert "0"s to "1"s\r
+//\r
+\r
+int amd_ee_byte_pro_128(unsigned int s, unsigned int o, unsigned char dat);\r
+\r
+//\r
+// unsigned char rtc_rds(char* time_string); \r
+// put a time string into time_string, based on the reading of RTC.\r
+//     At least 15 bytes of buffer must be available for the time_string\r
+//     returns 0, if RTC OK, or returns 1, if problem\r
+//\r
+unsigned char rtc_rds(char* time_string); \r
+int rtc_rd(TIM *r);\r
+void rtc_init(unsigned char*);    \r
+unsigned char r_rd(void);\r
+int r_out(unsigned char v);\r
+\r
+\r
+void t2_init(unsigned int tm,unsigned int ta,void interrupt far(*t2_isr)());\r
+void t1_init(unsigned int tm,unsigned int ta,unsigned int tb,void interrupt far(*t1_isr)());\r
+void t0_init(unsigned int tm,unsigned int ta,unsigned int tb,void interrupt far(*t0_isr)());\r
+unsigned int t2_rd(void);\r
+unsigned int t1_rd(void);\r
+unsigned int t0_rd(void);\r
+\r
+//     Analog to Digital conversion using TLC2543 on the A-Engine-88/86\r
+//     Input:\r
+//             unsigned char c = input channel \r
+//             c = 0,  input ch = AD0\r
+//             c = 1,  input ch = AD1\r
+//             c = 2,  input ch = AD2\r
+//             c = 3,  input ch = AD3\r
+//             c = 4,  input ch = AD4\r
+//             c = 5,  input ch = AD5\r
+//             c = 6,  input ch = AD6\r
+//             c = 7,  input ch = AD7\r
+//             c = 8,  input ch = AD8\r
+//             c = 9,  input ch = AD9\r
+//             c = a,  input ch = AD10\r
+//     In order to operate ADC, P11 must be input.\r
+//     P11 is shared by RTC, EE. It must be high while power on/reset\r
+//     For AE88, using PPI for ADC, I20,I21,I22 must be output\r
+//     For AE86, using PAL for ADC, T0=CLK, T1=DIN, T2=ADCS\r
+//             Enter the ae_ad12(unsigned char c);  EE is stopped first.\r
+//             Enter the ae86_ad12(unsigned char c);  EE is stopped first.\r
+//\r
+//     Output: 12 bit AD data of the previous channel !\r
+//             Unipolar:\r
+//             (Vref+ - Vref-)=0x7ff\r
+//             Vref- = 0x000\r
+//             Vref+ = 0xfff\r
+//\r
+//\r
+int ae_ad12(unsigned char c);\r
+\r
+//     outportb(0x120,1);  // T0=0, CLK\r
+//     outportb(0x128,1);  // T1=0, DIN\r
+//     outportb(0x130,1);  // T2=0, ADCS\r
+int ae86_ad12(unsigned char c);\r
+\r
+void nmi_init(void interrupt far (* nmi_isr)());\r
+void int0_init(unsigned char i, void interrupt far (*int0_isr)());\r
+void int1_init(unsigned char i, void interrupt far (*int1_isr)());\r
+void int2_init(unsigned char i, void interrupt far (*int2_isr)());\r
+void int3_init(unsigned char i, void interrupt far (*int3_isr)());\r
+void int4_init(unsigned char i, void interrupt far (*int4_isr)());\r
+void int5_init(unsigned char i, void interrupt far (*int5_isr)());\r
+void int6_init(unsigned char i, void interrupt far (*int6_isr)());\r
+\r
+\r
+//\r
+// void pio_init(char bit, char mode)\r
+//     where bit=0-31\r
+//                     mode=0, Normal operation\r
+//                     mode=1, Input with pullup/down\r
+//                     mode=2, Output\r
+//                     mode=3, input without pull\r
+//\r
+void pio_init(char bit, char mode);\r
+\r
+\r
+//\r
+//     void pio_wr(char bit, char dat)\r
+//     where bit=0-31\r
+//             dat=0/1\r
+//\r
+void pio_wr(char bit, char dat);\r
+\r
+//\r
+// unsigned int pio_rd(char port)\r
+//     return P15-P0, if port=0\r
+//     return P31-P16, if port=1\r
+//\r
+unsigned int pio_rd(char port);\r
+\r
+// setup I/O wait states for I/O instructions\r
+//     where wait = 0-7\r
+//     wait=0,                 wait states = 0, I/O enable for 100 ns\r
+//     wait=1,                 wait states = 1, I/O enable for 100+25 ns\r
+//     wait=2,                 wait states = 2, I/O enable for 100+50 ns\r
+//     wait=3,                 wait states = 3, I/O enable for 100+75 ns\r
+//     wait=4,                 wait states = 5, I/O enable for 100+125 ns\r
+//     wait=5,                 wait states = 7, I/O enable for 100+175 ns\r
+//     wait=6,                 wait states = 9, I/O enable for 100+225 ns\r
+//     wait=7,                 wait states = 15, I/O enable for 100+375 ns\r
+void io_wait(char wait);\r
+\r
+unsigned int crc16(unsigned char *wptr, unsigned int count);\r
+\r
+/******************************************************\r
+       void ae_da(int dat1, int dat2)\r
+       output dat to U11 DAC of AE88\r
+       Requires P12=CLK, P26=DI, P29=LD/CS as output pins !\r
+       where dat1 for channel A, dat2 for channel B;   dat1/2 = 0-4095\r
+*******************************************************/\r
+void ae_da(int dat1, int dat2);\r
+\r
+/******************************************************\r
+       void ae86_da(int dat1, int dat2)\r
+       output dat to U15 DAC of AE86\r
+       Requires T0=CLK=0x120, T1=DI=0x128, T3=LD/CS=0x138\r
+       where dat1 for channel A, dat2 for channel B;   dat1/2 = 0-4095\r
+       Output 0-2.5V at VA=J4.16, VB=J4.18\r
+*******************************************************/\r
+void ae86_da(int dat1, int dat2);\r
+void interrupt reset_io_trap();\r
+\r
+#endif\r
+\r
+\r
+\1a
\ No newline at end of file
diff --git a/Demo/WizNET_DEMO_TERN_186/include/i2chip_hw.h b/Demo/WizNET_DEMO_TERN_186/include/i2chip_hw.h
new file mode 100644 (file)
index 0000000..2ea32c1
--- /dev/null
@@ -0,0 +1,309 @@
+/*\r
+********************************************************************************\r
+* TERN, Inc.\r
+* (c) Copyright 2005, http://www.tern.com\r
+*\r
+* - Created to support i2chip module on a variety of TERN hardware platforms.\r
+********************************************************************************\r
+*/\r
+\r
+#ifndef _I2CHIP_HW_H_\r
+#define _I2CHIP_HW_H_\r
+\r
+#include "types.h"\r
+\r
+#ifdef TERN_SC    // SensorCore controller, has mapping identical to the RL\r
+#define TERN_RL\r
+#endif\r
+\r
+#ifdef TERN_RL    // R-Engine-L controller, with mapping at MCS0.\r
+#define I2CHIP_MCS_DIRECT\r
+#define I2CHIP_INT4\r
+#define TERN_RE\r
+#endif                // TERN_RL\r
+\r
+#ifdef TERN_5E\r
+#define TERN_586\r
+#endif\r
+\r
+#ifdef TERN_RD\r
+#define TERN_RE\r
+#endif                // TERN_RD\r
+\r
+#ifdef TERN_RE\r
+#define TERN_186\r
+#endif\r
+\r
+#ifdef TERN_P51\r
+void p51_window(unsigned int page);\r
+#define I2CHIP_WINDOW\r
+#define I2CHIP_P51\r
+#ifdef  TERN_186\r
+#define I2CHIP_INT4\r
+#define TERN_16_BIT\r
+#endif                // TERN_186\r
+#ifdef  TERN_586\r
+#define I2CHIP_INT0\r
+#define I2CHIP_WINDOW_IO\r
+#endif                // TERN_586\r
+#endif                // TERN_P51\r
+\r
+#ifdef TERN_CEYE\r
+#define TERN_EE       // C-Eye configured with onboard i2chip, same as EE\r
+#endif\r
+\r
+#ifdef TERN_EE\r
+#define TERN_186\r
+#define I2CHIP_MCS_DIRECT\r
+#define I2CHIP_INT4\r
+#define TERN_16_BIT\r
+#endif                    // TERN_EE\r
+\r
+#ifdef TERN_MMC\r
+#define I2CHIP_WINDOW\r
+#define I2CHIP_MMC\r
+#ifdef TERN_RD\r
+#define I2CHIP_INT3\r
+#else\r
+#ifdef TERN_186\r
+#define I2CHIP_INT4\r
+#endif                   // TERN_186\r
+#endif                   // TERN_RD\r
+#ifdef TERN_586\r
+#define I2CHIP_INT0\r
+#define I2CHIP_WINDOW_IO\r
+#endif                   // TERN_586\r
+#endif                   // TERN_MMC\r
+\r
+#ifdef TERN_586\r
+#include "586.h"\r
+void interrupt far int0_isr(void);\r
+void interrupt far spu_m_isr(void);\r
+void interrupt far spu_1_isr(void);\r
+void interrupt far spu_2_isr(void);\r
+#define MMCR 0xdf00\r
+#endif                   // TERN_586\r
+\r
+#ifdef TERN_186\r
+#ifndef TERN_RE\r
+#include "ae.h"\r
+#else\r
+#include "re.h"\r
+#define I2CHIP_SHIFTED_ADDRESS\r
+#endif\r
+#endif\r
+\r
+\r
+#ifndef I2CHIP_MCS_DIRECT\r
+#ifndef I2CHIP_WINDOW\r
+#ifndef I2CHIP_WINDOW_IO\r
+#error You must define the TERN address mapping used to drive the I2CHIP module!\r
+#endif  // I2CHIP_WINDOW_IO\r
+#endif  // I2CHIP_MMC_WINDOW\r
+#endif  // I2CHIP_MCS_DIRECT\r
+\r
+#ifndef I2CHIP_INT0\r
+#ifndef I2CHIP_INT3\r
+#ifndef I2CHIP_INT4\r
+#ifndef I2CHIP_POLL\r
+#error You must specify an interrupt/polling mechanism for the I2CHIP module!\r
+#endif  // I2CHIP_POLL\r
+#endif  // I2CHIP_INT3\r
+#endif  // I2CHIP_INT4\r
+#endif  // I2CHIP_INT0\r
+\r
+#ifdef   I2CHIP_POLL\r
+#define  I2CHIP_POLL_ISR(a)   { delay_ms(20); disable(); a(); enable(); }\r
+#define  INT_INIT(isr)\r
+#define  INT_EOI\r
+#endif   // I2CHIP_POLL\r
+\r
+#ifdef   I2CHIP_INT4\r
+#define  INT_INIT(isr) int4_init(1, isr)\r
+#define  INT_EOI       outport(0xff22,0x0010)\r
+#define  I2CHIP_POLL_ISR(a)\r
+#endif\r
+\r
+#ifdef   I2CHIP_INT3\r
+#define  INT_INIT(isr) int3_init(1, isr)\r
+#define  INT_EOI       outport(0xff22,0x000f)\r
+#define  I2CHIP_POLL_ISR(a)\r
+#endif\r
+\r
+#ifdef   I2CHIP_INT0\r
+#define  INT_INIT(isr) int0_init(1, isr)\r
+#define  INT_EOI        outportb(_MPICOCW2_IO,0x61); // 586 only EOI\r
+#define  I2CHIP_POLL_ISR(a)\r
+#endif\r
+\r
+\r
+#ifdef   I2CHIP_SHIFTED_ADDRESS\r
+#define  SA_OFFSET(a)   ((a) << 1)\r
+#else\r
+#define  SA_OFFSET(a)   a\r
+#endif   // I2CHIP_SHIFTED_ADDRESS ... *if*\r
+\r
+\r
+// -------------------- WINDOW-RELATED DEFINES ----------------------\r
+#ifdef   I2CHIP_WINDOW\r
+void        i2chip_set_page(u_int addr);\r
+#define  I2CHIP_SET_PAGE(p) i2chip_set_page(p)\r
+\r
+u_char far* i2chip_mkptr(u_int addr);\r
+void                   i2chip_push_window(u_int addr);\r
+void                   i2chip_pop_window(void);\r
+u_int       i2chip_get_window(void);\r
+void i2chip_set_window(u_int window_addr);\r
+\r
+// Set to command window.\r
+// Note that if you're using other MMC chips within your application, you will\r
+// need to call this function regularly, if you've changed the MMC chip/page\r
+// selection via mmc_window().  The driver code otherwise assume that you never\r
+// change away from chip 7, page 0.\r
+#define  WINDOW_RESTORE_BASE    i2chip_mkptr(0)\r
+\r
+//  ----------------------- I2CHIP_WINDOW_IO ----------------------------\r
+#ifdef   I2CHIP_WINDOW_IO\r
+\r
+#ifdef   TERN_5E\r
+#define        I2CHIP_BASE_SEG    0x2000                       // Address offset for W3100A\r
+#else\r
+#define        I2CHIP_BASE_SEG    0x1800                       // Address offset for W3100A\r
+#endif\r
+\r
+#define  COMMAND_BASE_SEG     0x0000\r
+#define        SEND_DATA_BUF              0x4000                       // Internal Tx buffer address of W3100A\r
+#define        RECV_DATA_BUF              0x6000                       // Internal Rx buffer address of W3100A\r
+#define  WINDOW_BASE_SEGM     COMMAND_BASE_SEG\r
+\r
+#define  MK_FP_WINDOW(a, b)   i2chip_mkptr(a+SA_OFFSET(b))\r
+#define  MK_FP_SA             MK_FP_WINDOW\r
+\r
+u_char   io_read_value(u_char far* addr);\r
+void     io_write_value(u_char far* addr, u_char value);\r
+#define  READ_VALUE(a)        io_read_value(a)\r
+#define  WRITE_VALUE(a, v)    io_write_value(a, v)\r
+\r
+#define  WINDOW_PTR_INC(a)    \\r
+         if ((FP_OFF(a) & 0xff) == 0xff) \\r
+            a = MK_FP_WINDOW(i2chip_get_window() + 0x100, 0); \\r
+         else \\r
+               a++;\r
+\r
+#endif  // I2CHIP_WINDOW_IO\r
+\r
+//  -------------------- !NOT! I2CHIP_WINDOW_IO ----------------------------\r
+#ifndef  I2CHIP_WINDOW_IO\r
+\r
+#define  READ_VALUE(a)        *(a)\r
+#define  WRITE_VALUE(a, v)    *(a) = v\r
+\r
+#define  WINDOW_BASE_SEGM  0x8000\r
+#define  MK_FP_WINDOW(a, b)   i2chip_mkptr(a+SA_OFFSET(b))\r
+#define  MK_FP_SA  MK_FP_WINDOW\r
+\r
+#ifdef   I2CHIP_SHIFTED_ADDRESS\r
+#define  COMMAND_BASE_SEG  0x0000\r
+#define  SEND_DATA_BUF     0x8000\r
+#define  RECV_DATA_BUF     0xC000\r
+#define  WINDOW_PTR_INC(a)    \\r
+         if ((FP_OFF(a) & 0xff) == 0xfe) \\r
+            a = MK_FP_WINDOW(i2chip_get_window() + 0x100, 0); \\r
+         else \\r
+               a+=2;\r
+#else\r
+#define  COMMAND_BASE_SEG  0x0000\r
+#define  SEND_DATA_BUF     0x4000\r
+#define  RECV_DATA_BUF     0x6000\r
+#define  WINDOW_PTR_INC(a)    \\r
+         if ((FP_OFF(a) & 0xff) == 0xff) \\r
+            a = MK_FP_WINDOW(i2chip_get_window() + 0x100, 0); \\r
+         else \\r
+               a++;\r
+#endif   // I2CHIP_SHIFTED_ADDRESS\r
+#endif   // NOT I2CHIP_WINDOW_IO\r
+\r
+#endif   // I2CHIP_WINDOW\r
+\r
+//  --------------------  I2CHIP_DIRECT ----------------------------\r
+#ifdef   I2CHIP_MCS_DIRECT\r
+\r
+#define  READ_VALUE(a)        *(a)\r
+#define  WRITE_VALUE(a, v)    *(a) = v\r
+\r
+#define  I2CHIP_BASE_SEG  0x8000\r
+#define  MK_FP_SA(a, b)   MK_FP(a, SA_OFFSET(b))\r
+#define  WINDOW_PTR_INC(a)   a+=SA_OFFSET(1);\r
+#define  WINDOW_RESTORE_BASE\r
+#define  MK_FP_WINDOW           MK_FP_SA\r
+#define  WINDOW_BASE_SEG        I2CHIP_BASE_SEG\r
+#define  COMMAND_BASE_SEG       I2CHIP_BASE_SEG\r
+\r
+#ifdef   I2CHIP_SHIFTED_ADDRESS\r
+#define        SEND_DATA_BUF           0x8800                  // Internal Tx buffer address of W3100A\r
+#define        RECV_DATA_BUF           0x8C00                  // Internal Rx buffer address of W3100A\r
+#else\r
+#define        SEND_DATA_BUF           0x8400                  // Internal Tx buffer address of W3100A\r
+#define        RECV_DATA_BUF           0x8600                  // Internal Rx buffer address of W3100A\r
+#endif   // I2CHIP_SHIFTED_ADDRESS\r
+\r
+#endif   // I2CHIP_MCS_DIRECT\r
+\r
+/* Internal register set of W3100A */\r
+#define        COMMAND(i)              ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, i)))\r
+#define        INT_STATUS(i)   ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, I2CHIP_C0_ISR + i)))\r
+#define        INT_REG                 ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, I2CHIP_IR)))\r
+#define        INTMASK         ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, I2CHIP_IMR)))\r
+#define        RESETSOCK      ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, 0x0A)))\r
+\r
+#define RX_PTR_BASE            I2CHIP_C0_RW_PR\r
+#define RX_PTR_SIZE            (I2CHIP_C1_RW_PR - I2CHIP_C0_RW_PR)\r
+\r
+#define        RX_WR_PTR(i)    ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, RX_PTR_BASE + RX_PTR_SIZE * i)))\r
+#define        RX_RD_PTR(i)    ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, RX_PTR_BASE + RX_PTR_SIZE * i + 0x04)))\r
+#define        RX_ACK_PTR(i)   ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, TX_PTR_BASE + TX_PTR_SIZE * i + 0x08)))\r
+\r
+#define TX_PTR_BASE            I2CHIP_C0_TW_PR\r
+#define TX_PTR_SIZE            (I2CHIP_C1_TW_PR - I2CHIP_C0_TW_PR)\r
+\r
+#define        TX_WR_PTR(i)    ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, TX_PTR_BASE + TX_PTR_SIZE * i)))\r
+#define        TX_RD_PTR(i)    ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, TX_PTR_BASE + TX_PTR_SIZE * i + 0x04)))\r
+#define        TX_ACK_PTR(i)   ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, RX_PTR_BASE + RX_PTR_SIZE * i + 0x08)))\r
+\r
+/* Shadow Register Pointer Define */\r
+/* For windowing purposes, these are definitely outside the first 256-byte Window...\r
+therefore, use the MK_FP_WINDOW macros instead. */\r
+#define SHADOW_RXWR_PTR(i)             ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, 0x1E0 + 3*i)))\r
+#define SHADOW_RXRD_PTR(i)             ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, 0x1E1 + 3*i)))\r
+#define SHADOW_TXACK_PTR(i)    ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, 0x1E2 + 3*i)))\r
+#define SHADOW_TXWR_PTR(i)             ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, 0x1F0 + 3*i)))\r
+#define SHADOW_TXRD_PTR(i)             ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, 0x1F1 + 3*i)))\r
+\r
+#define SOCK_BASE              I2CHIP_C0_SSR\r
+#define SOCK_SIZE              (I2CHIP_C1_SSR - I2CHIP_C0_SSR)\r
+\r
+#define SOCK_STATUS(i) ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, SOCK_BASE + SOCK_SIZE * i)))\r
+#define OPT_PROTOCOL(i)        ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, SOCK_BASE + SOCK_SIZE * i + 0x01)))\r
+#define DST_HA_PTR(i)  ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, SOCK_BASE + SOCK_SIZE * i + 0x02)))\r
+#define DST_IP_PTR(i)  ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, SOCK_BASE + SOCK_SIZE * i + 0x08)))\r
+#define DST_PORT_PTR(i)        ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, SOCK_BASE + SOCK_SIZE * i + 0x0C)))\r
+#define SRC_PORT_PTR(i)        ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, SOCK_BASE + SOCK_SIZE * i + 0x0E)))\r
+#define IP_PROTOCOL(i) ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, SOCK_BASE + SOCK_SIZE * i + 0x10)))\r
+#define TOS(i)                         ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG,SOCK_BASE + SOCK_SIZE * i + 0x11)))\r
+#define MSS(i)                         ((u_int far *)(MK_FP_WINDOW(COMMAND_BASE_SEG, SOCK_BASE + SOCK_SIZE * i + 0x12)))\r
+#define P_WINDOW(i)            ((u_int far *)(MK_FP_WINDOW(COMMAND_BASE_SEG,SOCK_BASE + SOCK_SIZE * i + 0x14)))\r
+#define WINDOW(i)                      ((u_int far*)(MK_FP_WINDOW(COMMAND_BASE_SEG, SOCK_BASE + SOCK_SIZE * i + 0x16)))\r
+\r
+#define GATEWAY_PTR            ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG,I2CHIP_GAR)))\r
+#define SUBNET_MASK_PTR        ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG,I2CHIP_SMR)))\r
+\r
+#define SRC_HA_PTR             ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG,I2CHIP_SHAR)))\r
+#define SRC_IP_PTR             ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG,I2CHIP_SIPR)))\r
+#define TIMEOUT_PTR            ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG,I2CHIP_IRTR)))\r
+\r
+#define RX_DMEM_SIZE           ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG,I2CHIP_RMSR)))\r
+#define TX_DMEM_SIZE           ((u_char far *)(MK_FP_WINDOW(COMMAND_BASE_SEG,I2CHIP_TMSR)))\r
+\r
+void i2chip_init(void);\r
+\r
+#endif  // _irchip_hw_h\r
diff --git a/Demo/WizNET_DEMO_TERN_186/include/utils/system_common.h b/Demo/WizNET_DEMO_TERN_186/include/utils/system_common.h
new file mode 100644 (file)
index 0000000..1a40cf8
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _SYSTEM_COMMON_H_\r
+#define _SYSTEM_COMMON_H_\r
+\r
+typedef unsigned char UCHAR8;\r
+typedef unsigned int  UINT16;\r
+\r
+#define RETURN_OK                       0    // Non-zero return values are always\r
+                                             // error values.\r
+#define RETURN_ILLEGAL                  1    // Some sort of illegal argument.\r
+#define RETURN_MEM                      2    // Out of memory space.\r
+\r
+#endif // _SYSTEM_COMMON_H_
\ No newline at end of file
diff --git a/Demo/WizNET_DEMO_TERN_186/main.c b/Demo/WizNET_DEMO_TERN_186/main.c
new file mode 100644 (file)
index 0000000..9a686d3
--- /dev/null
@@ -0,0 +1,196 @@
+/*\r
+       FreeRTOS V4.0.1 - Copyright (C) 2003-2006 Richard Barry.\r
+\r
+       This file is part of the FreeRTOS distribution.\r
+\r
+       FreeRTOS is free software; you can redistribute it and/or modify\r
+       it under the terms of the GNU General Public License as published by\r
+       the Free Software Foundation; either version 2 of the License, or\r
+       (at your option) any later version.\r
+\r
+       FreeRTOS is distributed in the hope that it will be useful,\r
+       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+       GNU General Public License for more details.\r
+\r
+       You should have received a copy of the GNU General Public License\r
+       along with FreeRTOS; if not, write to the Free Software\r
+       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+       A special exception to the GPL can be applied should you wish to distribute\r
+       a combined work that includes FreeRTOS, without being obliged to provide\r
+       the source code for any proprietary components.  See the licensing section\r
+       of http://www.FreeRTOS.org for full details of how and when the exception\r
+       can be applied.\r
+\r
+       ***************************************************************************\r
+       See http://www.FreeRTOS.org for documentation, latest information, license \r
+       and contact details.  Please ensure to read the configuration and relevant \r
+       port sections of the online documentation.\r
+       ***************************************************************************\r
+*/\r
+\r
+/*\r
+ * Creates all the demo application tasks then starts the scheduler.  In \r
+ * addition to the standard demo application tasks main() creates the \r
+ * HTTPServer task, and a "Check" task.  The Check task periodically inspects\r
+ * all the other tasks in the system to see if any errors have been reported.\r
+ * The error status is then displayed on the served WEB page.\r
+ */\r
+\r
+/* Tern includes. */\r
+#include <ae.h>\r
+#include <embedded.h>\r
+\r
+/* FreeRTOS.org includes. */\r
+#include <FreeRTOS.h>\r
+#include <task.h>\r
+\r
+/* Demo application includes. */\r
+#include "HTTPTask.h"\r
+#include "integer.h"\r
+#include "PollQ.h"\r
+#include "semtest.h"\r
+#include "dynamic.h"\r
+#include "BlockQ.h"\r
+#include "Death.h"\r
+#include "serial.h"\r
+#include "comtest.h"\r
+\r
+/* How often should the "check" task execute? */\r
+#define mainCHECK_DELAY                ( 3000 / portTICK_RATE_MS )\r
+\r
+/* Priorities allocated to the various tasks. */\r
+#define mainQUEUE_POLL_PRIORITY                ( tskIDLE_PRIORITY + 2 )\r
+#define mainCHECK_TASK_PRIORITY                ( tskIDLE_PRIORITY + 4 )\r
+#define mainSEM_TEST_PRIORITY          ( tskIDLE_PRIORITY + 1 )\r
+#define mainBLOCK_Q_PRIORITY           ( tskIDLE_PRIORITY + 2 )\r
+#define mainHTTP_TASK_PRIORITY         ( tskIDLE_PRIORITY + 3 )\r
+#define mainSUICIDE_TASKS_PRIORITY  ( tskIDLE_PRIORITY + 1 )\r
+#define mainCOM_TEST_PRIORITY          ( tskIDLE_PRIORITY + 2 )\r
+\r
+/* Used to indicate the error status.  A value of 0 means that an error has not\r
+been detected in any task.  A non zero value indicates which group of demo \r
+tasks has reported an error.  See prvCheckTask() for bit definitions. */\r
+unsigned portSHORT usCheckStatus = 0;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Setup any hardware required by the demo - other than the RTOS tick which\r
+ * is configured when the scheduler is started.\r
+ */\r
+static void prvSetupHardware( void );\r
+\r
+/*\r
+ * Periodically inspect all the other tasks, updating usCheckStatus should an\r
+ * error be discovered in any task.\r
+ */\r
+static void prvCheckTask( void *pvParameters );\r
+/*-----------------------------------------------------------*/\r
+\r
+void main(void)\r
+{\r
+       prvSetupHardware();\r
+\r
+    /* Start the HTTP server task. */\r
+       xTaskCreate( vHTTPTask, "WizNet", configMINIMAL_STACK_SIZE, NULL, mainHTTP_TASK_PRIORITY, NULL );\r
+\r
+       /* Start the demo/test application tasks.  See the demo application \r
+       section of the FreeRTOS.org WEB site for more information. */\r
+       vStartIntegerMathTasks( tskIDLE_PRIORITY );\r
+       vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );\r
+       vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );\r
+       vStartDynamicPriorityTasks();\r
+       vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );\r
+    vStartComTestTasks( mainCOM_TEST_PRIORITY, serCOM2, ser57600 );\r
+\r
+       /* Start the task that checks the other demo tasks for errors. */\r
+    xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );\r
+\r
+       /* The suicide tasks must be created last as they monitor the number of\r
+       tasks in the system to ensure there are no more or fewer than expected\r
+       compared to the number that were executing when the task started. */\r
+       vCreateSuicidalTasks( mainSUICIDE_TASKS_PRIORITY );\r
+        \r
+       /* Finally start the scheduler. */\r
+    vTaskStartScheduler();\r
+\r
+       /* Should not get here! */\r
+       for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvSetupHardware( void )\r
+{\r
+       ae_init();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCheckTask( void *pvParameters )\r
+{\r
+       ( void ) pvParameters;\r
+\r
+       /* Check all the demo tasks to ensure that they are all still running, and\r
+    that none of them have detected    an error. */\r
+    for( ;; )\r
+    {\r
+               /* Block until it is time to check again. */\r
+       vTaskDelay( mainCHECK_DELAY );\r
+        \r
+               if( xAreIntegerMathsTaskStillRunning() != pdTRUE )\r
+               {\r
+                       usCheckStatus |= 0x01;\r
+               }\r
+\r
+               if( xArePollingQueuesStillRunning() != pdTRUE )\r
+               {\r
+                       usCheckStatus |= 0x02;\r
+               }\r
+\r
+               if( xAreSemaphoreTasksStillRunning() != pdTRUE )\r
+               {\r
+                       usCheckStatus |= 0x04;\r
+               }\r
+\r
+               if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )\r
+               {\r
+                       usCheckStatus |= 0x08;\r
+               }\r
+\r
+               if( xAreBlockingQueuesStillRunning() != pdTRUE )\r
+               {\r
+                       usCheckStatus |= 0x10;\r
+               }\r
+\r
+        if( xIsCreateTaskStillRunning() != pdTRUE )\r
+        {\r
+               usCheckStatus |= 0x20;\r
+        }\r
+\r
+        if( xAreComTestTasksStillRunning() != pdTRUE )\r
+        {\r
+               usCheckStatus |= 0x40;\r
+        }\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* This is included to prevent link errors - allowing the 'full' version of\r
+the comtest tasks to be used.  It can be ignored. */\r
+void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend )\r
+{\r
+       ( void ) ppcMessageToSend;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
diff --git a/Demo/WizNET_DEMO_TERN_186/serial/serial.c b/Demo/WizNET_DEMO_TERN_186/serial/serial.c
new file mode 100644 (file)
index 0000000..628e147
--- /dev/null
@@ -0,0 +1,442 @@
+/*\r
+       FreeRTOS V4.0.1 - Copyright (C) 2003-2006 Richard Barry.\r
+\r
+       This file is part of the FreeRTOS distribution.\r
+\r
+       FreeRTOS is free software; you can redistribute it and/or modify\r
+       it under the terms of the GNU General Public License as published by\r
+       the Free Software Foundation; either version 2 of the License, or\r
+       (at your option) any later version.\r
+\r
+       FreeRTOS is distributed in the hope that it will be useful,\r
+       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+       GNU General Public License for more details.\r
+\r
+       You should have received a copy of the GNU General Public License\r
+       along with FreeRTOS; if not, write to the Free Software\r
+       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+       A special exception to the GPL can be applied should you wish to distribute\r
+       a combined work that includes FreeRTOS, without being obliged to provide\r
+       the source code for any proprietary components.  See the licensing section \r
+       of http://www.FreeRTOS.org for full details of how and when the exception\r
+       can be applied.\r
+\r
+       ***************************************************************************\r
+       See http://www.FreeRTOS.org for documentation, latest information, license \r
+       and contact details.  Please ensure to read the configuration and relevant \r
+       port sections of the online documentation.\r
+       ***************************************************************************\r
+*/\r
+\r
+\r
+#include <stdlib.h>\r
+#include <embedded.h>\r
+#include "FreeRTOS.h"\r
+#include "portasm.h"\r
+#include "queue.h"\r
+#include "task.h"\r
+#include "semphr.h"\r
+\r
+#define serMAX_PORTS                   ( ( unsigned portSHORT ) 2 )\r
+\r
+#define serPORT_0_INT_REG              ( 0xff44 )\r
+#define serPORT_0_BAUD_REG             ( 0xff88 )\r
+#define serPORT_0_RX_REG               ( 0xff86 )\r
+#define serPORT_0_TX_REG               ( 0xff84 )\r
+#define serPORT_0_STATUS_REG   ( 0xff82 )\r
+#define serPORT_0_CTRL_REG             ( 0xff80 )\r
+#define serPORT_0_IRQ                  ( 0x14 )\r
+\r
+#define serPORT_1_INT_REG              ( 0xff42 )\r
+#define serPORT_1_BAUD_REG             ( 0xff18 )\r
+#define serPORT_1_RX_REG               ( 0xff16 )\r
+#define serPORT_1_TX_REG               ( 0xff14 )\r
+#define serPORT_1_STATUS_REG   ( 0xff12 )\r
+#define serPORT_1_CTRL_REG             ( 0xff10 )\r
+#define serPORT_1_IRQ                  ( 0x11 )\r
+\r
+#define serTX_EMPTY                            ( ( unsigned portSHORT ) 0x40 )\r
+#define serRX_READY                            ( ( unsigned portSHORT ) 0x80 )\r
+\r
+#define serRESET_PIC( usEOI_TYPE )     portOUTPUT_WORD( ( unsigned portSHORT ) 0xff22, usEOI_TYPE )\r
+#define serTX_HOLD_EMPTY_INT           ( ( unsigned portSHORT ) 0x100 )\r
+\r
+#define serENABLE_INTERRUPTS           ( ( unsigned portSHORT ) 0x80 )\r
+#define serMODE                                                ( ( unsigned portSHORT ) 0x01 )\r
+#define serENABLE_TX_MACHINES          ( ( unsigned portSHORT ) 0x40 )\r
+#define serENABLE_RX_MACHINES          ( ( unsigned portSHORT ) 0x20 )\r
+#define serINTERRUPT_MASK                      ( ( unsigned portSHORT ) 0x08 )\r
+#define serCLEAR_ALL_STATUS_BITS       ( ( unsigned portSHORT ) 0x00 )\r
+#define serINTERRUPT_PRIORITY          ( ( unsigned portSHORT ) 0x01 ) /*< Just below the scheduler priority. */\r
+\r
+#define serDONT_BLOCK                          ( ( portTickType ) 0 )\r
+\r
+typedef enum\r
+{ \r
+       serCOM1 = 0, \r
+       serCOM2, \r
+       serCOM3, \r
+       serCOM4, \r
+       serCOM5, \r
+       serCOM6, \r
+       serCOM7, \r
+       serCOM8 \r
+} eCOMPort;\r
+\r
+typedef enum \r
+{ \r
+       serNO_PARITY, \r
+       serODD_PARITY, \r
+       serEVEN_PARITY, \r
+       serMARK_PARITY, \r
+       serSPACE_PARITY \r
+} eParity;\r
+\r
+typedef enum \r
+{ \r
+       serSTOP_1, \r
+       serSTOP_2 \r
+} eStopBits;\r
+\r
+typedef enum \r
+{\r
+       serBITS_5,\r
+       serBITS_6,\r
+       serBITS_7,\r
+       serBITS_8\r
+} eDataBits;\r
+\r
+typedef enum\r
+{\r
+       ser50 = 0,\r
+       ser75,\r
+       ser110,\r
+       ser134,\r
+       ser150,\r
+       ser200,\r
+       ser300,\r
+       ser600,\r
+       ser1200,\r
+       ser1800,\r
+       ser2400,\r
+       ser4800,\r
+       ser9600,\r
+       ser19200,\r
+       ser38400,\r
+       ser57600,\r
+       ser115200\r
+} eBaud;\r
+\r
+typedef struct xCOM_PORT\r
+{\r
+       /* Hardware parameters for this port. */\r
+       portSHORT sTxInterruptOn;\r
+       unsigned portSHORT usIntReg;\r
+       unsigned portSHORT usBaudReg;\r
+       unsigned portSHORT usRxReg;\r
+       unsigned portSHORT usTxReg;\r
+       unsigned portSHORT usStatusReg;\r
+       unsigned portSHORT usCtrlReg;\r
+\r
+       unsigned portSHORT usIRQVector;\r
+\r
+       /* Queues used for communications with com test task. */\r
+       xQueueHandle xRxedChars; \r
+       xQueueHandle xCharsForTx;\r
+\r
+       /* This semaphore does nothing useful except test a feature of the\r
+       scheduler. */\r
+       xSemaphoreHandle xTestSem;\r
+\r
+} xComPort;\r
+\r
+static xComPort xPorts[ serMAX_PORTS ] = \r
+{\r
+       { pdFALSE, serPORT_0_INT_REG, serPORT_0_BAUD_REG, serPORT_0_RX_REG, serPORT_0_TX_REG, serPORT_0_STATUS_REG, serPORT_0_CTRL_REG, serPORT_0_IRQ, NULL, NULL, NULL },\r
+       { pdFALSE, serPORT_1_INT_REG, serPORT_1_BAUD_REG, serPORT_1_RX_REG, serPORT_1_TX_REG, serPORT_1_STATUS_REG, serPORT_1_CTRL_REG, serPORT_1_IRQ, NULL, NULL, NULL }\r
+};\r
+\r
+typedef xComPort * xComPortHandle;\r
+\r
+/**\r
+ * Lookup the baud rate from the enum.\r
+ */\r
+static unsigned portLONG prvBaud( eBaud eWantedBaud ); \r
+\r
+/* These prototypes are repeated here so we don't have to include the serial header.  This allows\r
+the xComPortHandle structure details to be private to this file. */\r
+xComPortHandle xSerialPortInit( eCOMPort ePort, eBaud eWantedBaud, eParity eWantedParity, eDataBits eWantedDataBits, eStopBits eWantedStopBits, unsigned portBASE_TYPE uxBufferLength );\r
+portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, portCHAR *pcRxedChar, portTickType xBlockTime );\r
+portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, portCHAR cOutChar, portTickType xBlockTime );\r
+void vSerialClose( xComPortHandle xPort );\r
+portSHORT sSerialWaitForSemaphore( xComPortHandle xPort );\r
+/*-----------------------------------------------------------*/\r
+\r
+static portSHORT xComPortISR( xComPort * const pxPort );\r
+\r
+#define vInterruptOn( pxPort, usInterrupt )                                                                            \\r
+{                                                                                                                                                              \\r
+unsigned portSHORT usIn;                                                                                                               \\r
+                                                                                                                                                               \\r
+       portENTER_CRITICAL();                                                                                                           \\r
+       {                                                                                                                                                       \\r
+               if( pxPort->sTxInterruptOn == pdFALSE )                                                                 \\r
+               {                                                                                                                                               \\r
+                       usIn = portINPUT_WORD( pxPort->usCtrlReg );                                                     \\r
+                       portOUTPUT_WORD( pxPort->usCtrlReg, usIn | usInterrupt );                       \\r
+                                                                                                                                                               \\r
+                       pxPort->sTxInterruptOn = pdTRUE;                                                                        \\r
+               }                                                                                                                                               \\r
+       }                                                                                                                                                       \\r
+       portEXIT_CRITICAL();                                                                                                            \\r
+}                                                                                                                                                              \r
+/*-----------------------------------------------------------*/\r
+\r
+#define vInterruptOff( pxPort, usInterrupt )                                                                   \\r
+{                                                                                                                                                              \\r
+       unsigned portSHORT usIn = portINPUT_WORD( pxPort->usCtrlReg );                          \\r
+       if( usIn & usInterrupt )                                                                                                        \\r
+       {                                                                                                                                                       \\r
+               portOUTPUT_WORD( pxPort->usCtrlReg, usIn & ~usInterrupt);                               \\r
+               pxPort->sTxInterruptOn = pdFALSE;                                                                               \\r
+       }                                                                                                                                                       \\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+\r
+/* Define an interrupt handler for each port */\r
+#define COM_IRQ_WRAPPER(N)                                                                             \\r
+       static void __interrupt COM_IRQ##N##_WRAPPER( void )            \\r
+       {                                                                                                                       \\r
+        if( xComPortISR( &( xPorts[##N##] ) ) )                 \\r
+        {                                                       \\r
+                       portEND_SWITCHING_ISR();                            \\r
+               }                                                       \\r
+       }\r
+\r
+  \r
+\r
+COM_IRQ_WRAPPER( 0 )\r
+COM_IRQ_WRAPPER( 1 )\r
+\r
+static pxISR xISRs[ serMAX_PORTS ] = \r
+{\r
+       COM_IRQ0_WRAPPER, \r
+       COM_IRQ1_WRAPPER\r
+};\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+static unsigned portLONG prvBaud( eBaud eWantedBaud )\r
+{\r
+       switch( eWantedBaud )\r
+    {\r
+               case ser50                      :       return 50UL;\r
+               case ser75                      :       return 75UL;\r
+               case ser110                     :       return 110UL;\r
+               case ser134                     :       return 134UL;\r
+               case ser150                     :       return 150UL;\r
+               case ser200                     :       return 200UL;\r
+               case ser300                     :       return 300UL;\r
+               case ser600                     :       return 600UL;\r
+               case ser1200            :       return 1200UL;\r
+               case ser1800            :       return 1800UL;\r
+               case ser2400            :       return 2400UL;\r
+               case ser4800            :       return 4800UL;\r
+               case ser19200           :       return 19200UL;\r
+               case ser38400           :       return 38400UL;\r
+               case ser57600           :       return 57600UL;\r
+               case ser115200          :       return 115200UL;\r
+               default                         :       return 9600UL;\r
+    }\r
+}\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+xComPortHandle xSerialPortInit( eCOMPort ePort, eBaud eWantedBaud, eParity eWantedParity, eDataBits eWantedDataBits, eStopBits eWantedStopBits, unsigned portBASE_TYPE uxBufferLength )\r
+{\r
+unsigned portSHORT usPort;\r
+xComPortHandle pxPort = NULL;\r
+unsigned portLONG ulBaudDiv;\r
+\r
+       /* BAUDDIV = ( Microprocessor Clock / Baud Rate ) / 16 */\r
+    ulBaudDiv = ( configCPU_CLOCK_HZ / prvBaud( eWantedBaud ) ) / 16UL;\r
+\r
+       /* Only n, 8, 1 is supported so these parameters are not required for this\r
+       port. */\r
+       ( void ) eWantedParity;\r
+       ( void ) eWantedDataBits;\r
+    ( void ) eWantedStopBits;\r
+\r
+       /* Currently only n,8,1 is supported. */\r
+\r
+       usPort = ( unsigned portSHORT ) ePort;\r
+       \r
+       if( usPort < serMAX_PORTS )\r
+       {\r
+               pxPort = &( xPorts[ usPort ] );\r
+\r
+               portENTER_CRITICAL();\r
+               {\r
+                       unsigned portSHORT usInWord;\r
+\r
+                       /* Create the queues used by the com test task. */\r
+                       pxPort->xRxedChars = xQueueCreate( uxBufferLength, ( unsigned portBASE_TYPE ) sizeof( portCHAR ) );\r
+                       pxPort->xCharsForTx = xQueueCreate( uxBufferLength, ( unsigned portBASE_TYPE ) sizeof( portCHAR ) );\r
+\r
+                       /* Create the test semaphore.  This does nothing useful except test a feature of the scheduler. */\r
+                       vSemaphoreCreateBinary( pxPort->xTestSem );\r
+\r
+                       /* There is no ISR here already to restore later. */\r
+                       setvect( ( portSHORT ) pxPort->usIRQVector, xISRs[ usPort ] );\r
+\r
+                       usInWord = portINPUT_WORD( pxPort->usIntReg );\r
+                       usInWord &= ~serINTERRUPT_MASK;\r
+                       usInWord |= serINTERRUPT_PRIORITY;\r
+                       portOUTPUT_WORD( pxPort->usIntReg, usInWord );\r
+\r
+                       portOUTPUT_WORD( pxPort->usBaudReg, ( unsigned portSHORT ) ulBaudDiv );\r
+                       portOUTPUT_WORD( pxPort->usCtrlReg, serENABLE_INTERRUPTS | serMODE | serENABLE_TX_MACHINES | serENABLE_RX_MACHINES );\r
+\r
+                       portOUTPUT_WORD( pxPort->usStatusReg, serCLEAR_ALL_STATUS_BITS );\r
+               }\r
+               portEXIT_CRITICAL();\r
+       }\r
+\r
+       return pxPort;\r
+} /*lint !e715 Some parameters are not used as only a subset of the serial port functionality is currently implemented. */\r
+/*-----------------------------------------------------------*/\r
+\r
+void vSerialPutString( xComPortHandle pxPort, const portCHAR * const pcString, unsigned portSHORT usStringLength )\r
+{\r
+unsigned portSHORT usByte;\r
+portCHAR *pcNextChar;\r
+\r
+       pcNextChar = ( portCHAR * ) pcString;\r
+\r
+       for( usByte = 0; usByte < usStringLength; usByte++ )\r
+       {\r
+               xQueueSend( pxPort->xCharsForTx, pcNextChar, serDONT_BLOCK );\r
+               pcNextChar++;\r
+       }\r
+\r
+       vInterruptOn( pxPort, serTX_HOLD_EMPTY_INT );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, portCHAR *pcRxedChar, portTickType xBlockTime )\r
+{\r
+       /* Get the next character from the buffer, note that this routine is only \r
+       called having checked that the is (at least) one to get */\r
+       if( xQueueReceive( pxPort->xRxedChars, pcRxedChar, xBlockTime ) )\r
+       {\r
+               return pdTRUE;\r
+       }\r
+       else\r
+       {\r
+               return pdFALSE;\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, portCHAR cOutChar, portTickType xBlockTime )\r
+{\r
+       if( xQueueSend( pxPort->xCharsForTx, &cOutChar, xBlockTime ) != pdPASS )\r
+       {\r
+               return pdFAIL;\r
+       }\r
+\r
+       vInterruptOn( pxPort, serTX_HOLD_EMPTY_INT );\r
+\r
+       return pdPASS;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xSerialWaitForSemaphore( xComPortHandle xPort )\r
+{\r
+const portTickType xBlockTime = ( portTickType ) 0xffff;\r
+\r
+       /* This function does nothing interesting, but test the \r
+       semaphore from ISR mechanism. */\r
+       return xSemaphoreTake( xPort->xTestSem, xBlockTime );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vSerialClose( xComPortHandle xPort )\r
+{\r
+unsigned portSHORT usOutput;\r
+\r
+       /* Turn off the interrupts.  We may also want to delete the queues and/or\r
+       re-install the original ISR. */\r
+\r
+       portENTER_CRITICAL();\r
+       {\r
+               usOutput = portINPUT_WORD( xPort->usCtrlReg );\r
+\r
+               usOutput &= ~serENABLE_INTERRUPTS;\r
+               usOutput &= ~serENABLE_TX_MACHINES;\r
+               usOutput &= ~serENABLE_RX_MACHINES;\r
+               portOUTPUT_WORD( xPort->usCtrlReg, usOutput );\r
+\r
+               usOutput = portINPUT_WORD( xPort->usIntReg );\r
+               usOutput |= serINTERRUPT_MASK;\r
+               portOUTPUT_WORD( xPort->usIntReg, usOutput );\r
+       }\r
+       portEXIT_CRITICAL();\r
+}\r
+/*-----------------------------------------------------------*/\r
+unsigned short usStatus;\r
+static portBASE_TYPE xComPortISR( xComPort * const pxPort )\r
+{\r
+unsigned portSHORT usStatusRegister;\r
+portCHAR cChar;\r
+portBASE_TYPE xTaskWokenByPost = pdFALSE, xAnotherTaskWokenByPost = pdFALSE, xTaskWokenByTx = pdFALSE;\r
+\r
+       /* NOTE:  THIS IS NOT AN EFFICIENT ISR AS IT IS DESIGNED SOLELY TO TEST\r
+       THE SCHEDULER FUNCTIONALITY.  REAL APPLICATIONS SHOULD NOT USE THIS\r
+       FUNCTION. */\r
+\r
+       usStatusRegister = portINPUT_WORD( pxPort->usStatusReg );\r
+\r
+       if( usStatusRegister & serRX_READY )\r
+       {\r
+               cChar = ( portCHAR ) portINPUT_WORD( pxPort->usRxReg );\r
+               xTaskWokenByPost = xQueueSendFromISR( pxPort->xRxedChars, &cChar, xTaskWokenByPost );\r
+\r
+               /* Also release the semaphore - this does nothing interesting and is just a test. */\r
+               xAnotherTaskWokenByPost = xSemaphoreGiveFromISR( pxPort->xTestSem, xAnotherTaskWokenByPost );\r
+       }\r
+       else if( pxPort->sTxInterruptOn && ( usStatusRegister & serTX_EMPTY ) )\r
+       {\r
+               if( xQueueReceiveFromISR( pxPort->xCharsForTx, &cChar, &xTaskWokenByTx ) == pdTRUE )\r
+               {\r
+                       portOUTPUT_WORD( pxPort->usTxReg, ( unsigned portSHORT ) cChar );\r
+               }\r
+               else\r
+               {\r
+                       /* Queue empty, nothing to send */\r
+                       vInterruptOff( pxPort, serTX_HOLD_EMPTY_INT );\r
+               }\r
+       }\r
+\r
+    serRESET_PIC( pxPort->usIRQVector );\r
+\r
+       /* If posting to the queue woke a task that was blocked on the queue we may\r
+       want to switch to the woken task - depending on its priority relative to\r
+       the task interrupted by this ISR. */\r
+       if( xTaskWokenByPost || xAnotherTaskWokenByPost || xTaskWokenByTx)\r
+       {\r
+               return pdTRUE;\r
+       }\r
+       else\r
+       {\r
+               return pdFALSE;\r
+       }\r
+}\r
+\r
+\r
+\r
+\r
+\r
diff --git a/Demo/WizNET_DEMO_TERN_186/socket.c b/Demo/WizNET_DEMO_TERN_186/socket.c
new file mode 100644 (file)
index 0000000..b749b16
--- /dev/null
@@ -0,0 +1,1861 @@
+/*\r
+********************************************************************************\r
+* TERN, Inc.\r
+* (c) Copyright 2005, http://www.tern.com\r
+*\r
+* MODIFIED BY RICHARD BARRY TO ADD SEMAPHORE FOR COMMUNICATION BETWEEN THE \r
+* WIZnet ISR AND THE HTTP TASK.\r
+*\r
+* - Derived based on development version provided by Wiznet.\r
+*\r
+* Filename : socket.h\r
+* Programmer(s):\r
+* Created : 2002/06/20\r
+* Modified :\r
+*  2002/09/27 : - Renaming\r
+*                             INT_STATUS --> INT_REG\r
+*                             STATUS(i) --> INT_STATUS(i)\r
+*                             C_STATUS(i) --> SOCK_STATUS(i)\r
+*  2003/11/06 : Ported for use with TERN controller.  Note all byte access is at even addresses\r
+*  2005/10/8  : Modified constants for easier initialization.\r
+*\r
+* Description : Header file of W3100A for TERN embedded controller\r
+********************************************************************************\r
+*/\r
+/*\r
+###############################################################################\r
+File Include Section\r
+###############################################################################\r
+*/\r
+#include "i2chip_hw.h" \r
+#include "socket.h"\r
+#include "types.h"\r
+#include <string.h>\r
+#include <stdio.h>\r
+\r
+#include <FreeRTOS.h>\r
+#include <semphr.h>\r
+#include <portasm.h>\r
+\r
+\r
+/*\r
+###############################################################################\r
+Local Variable Declaration Section\r
+###############################################################################\r
+*/\r
+u_char I_STATUS[4];                            // Store Interrupt Status according to channels\r
+u_int Local_Port;                                 // Designate Local Port\r
+union un_l2cval        SEQ_NUM;                // Set initial sequence number\r
+\r
+u_long SMASK[MAX_SOCK_NUM];   // Variable to store MASK of Tx in each channel,\r
+                              // on setting dynamic memory size.\r
+u_long RMASK[MAX_SOCK_NUM];   // Variable to store MASK of Rx in each channel,\r
+                              // on setting dynamic memory size.\r
+int SSIZE[MAX_SOCK_NUM];      // Maximun Tx memory size by each channel\r
+int RSIZE[MAX_SOCK_NUM];      // Maximun Rx memory size by each channel\r
+\r
+u_int SBUFBASEADDRESS[MAX_SOCK_NUM];   // Maximun Tx memory base address by each channel\r
+u_int RBUFBASEADDRESS[MAX_SOCK_NUM];   // Maximun Rx memory base address by each channel\r
+\r
+/*\r
+###############################################################################\r
+Function Implementation Section\r
+###############################################################################\r
+*/\r
+\r
+/*\r
+********************************************************************************\r
+*               Interrupt handling function of the W3100A\r
+*\r
+* Description :\r
+*   Stores the status information that each function waits for in the global variable I_STATUS\r
+*   for transfer. I_STATUS stores the interrupt status value for each channel.\r
+* Arguments   : None\r
+* Returns     : None\r
+* Note        : Internal Function\r
+********************************************************************************\r
+*/\r
+\r
+portBASE_TYPE prvProcessISR( void )\r
+{\r
+unsigned char status;\r
+extern xSemaphoreHandle xTCPSemaphore;\r
+portBASE_TYPE xSwitchRequired = pdFALSE;\r
+\r
+#ifdef I2CHIP_WINDOW\r
+u_int current_window = i2chip_get_window();\r
+#endif\r
+\r
+status = READ_VALUE(INT_REG);\r
+\r
+\r
+if (status)\r
+  {\r
+  xSwitchRequired = pdTRUE;\r
+  // channel 0 interrupt(sysinit, sockinit, established, closed, timeout, send_ok, recv_ok)\r
+  if (status & 0x01)\r
+    {\r
+        I_STATUS[0] = READ_VALUE(INT_STATUS(0));\r
+\r
+//      if (I_STATUS[0] & SESTABLISHED)\r
+//    ISR_ESTABLISHED(0);\r
+//      if (I_STATUS[0] & SCLOSED)\r
+//    ISR_CLOSED(0);\r
+\r
+        WRITE_VALUE(INT_REG, 0x01);\r
+        }\r
+\r
+  // channel 1 interrupt(sysinit, sockinit, established, closed, timeout, send_ok, recv_ok)\r
+  if (status & 0x02)\r
+    {\r
+        I_STATUS[1] = READ_VALUE(INT_STATUS(1));\r
+\r
+//      if (I_STATUS[1] & SESTABLISHED)\r
+//    ISR_ESTABLISHED(1);\r
+//      if (I_STATUS[1] & SCLOSED)\r
+//    ISR_CLOSED(1);\r
+\r
+        WRITE_VALUE(INT_REG, 0x02);\r
+        }\r
+\r
+  // channel 2 interrupt(sysinit, sockinit, established, closed, timeout, send_ok, recv_ok)\r
+  if (status & 0x04)\r
+    {\r
+        I_STATUS[2] = READ_VALUE(INT_STATUS(2));\r
+\r
+//      if (I_STATUS[2] & SESTABLISHED)\r
+//    ISR_ESTABLISHED(2);\r
+//      if (I_STATUS[2] & SCLOSED)\r
+//    ISR_CLOSED(2);\r
+\r
+        WRITE_VALUE(INT_REG, 0x04);\r
+        }\r
+\r
+  // channel 3 interrupt(sysinit, sockinit, established, closed, timeout, send_ok, recv_ok)\r
+  if (status & 0x08)\r
+    {\r
+        I_STATUS[3] = READ_VALUE(INT_STATUS(3));\r
+\r
+//      if (I_STATUS[3] & SESTABLISHED) ISR_ESTABLISHED(3);\r
+//      if (I_STATUS[3] & SCLOSED) ISR_CLOSED(3);\r
+\r
+        WRITE_VALUE(INT_REG, 0x08);\r
+        }\r
+\r
+  // channel 0 receive interrupt\r
+  if (status & 0x10)\r
+    {\r
+//      ISR_RX(0);\r
+        WRITE_VALUE(INT_REG, 0x10);\r
+        }\r
+\r
+  // channel 1 receive interrupt\r
+  if (status & 0x20)\r
+    {\r
+//      ISR_RX(1);\r
+        WRITE_VALUE(INT_REG, 0x20);\r
+        }\r
+\r
+  // channel 2 receive interrupt\r
+  if (status & 0x40)\r
+    {\r
+//      ISR_RX(2);\r
+        WRITE_VALUE(INT_REG, 0x40);\r
+        }\r
+\r
+  // channel 3 receive interrupt\r
+  if (status & 0x80)\r
+    {\r
+//      ISR_RX(3);\r
+        WRITE_VALUE(INT_REG, 0x80);\r
+        }\r
+  status = READ_VALUE(INT_REG);\r
+  }\r
+\r
+WRITE_VALUE(INT_REG, 0xFF);\r
+\r
+#ifdef I2CHIP_WINDOW\r
+i2chip_set_window(current_window);\r
+#endif\r
+\r
+       if( xSwitchRequired == pdTRUE )\r
+    {\r
+               xSwitchRequired = xSemaphoreGiveFromISR( xTCPSemaphore, pdFALSE );\r
+    }\r
+\r
+       return xSwitchRequired;\r
+}\r
+\r
+void far interrupt in4_isr_i2chip(void)\r
+{\r
+       if( prvProcessISR() == pdTRUE )\r
+    {\r
+               portEND_SWITCHING_ISR();\r
+    }\r
+\r
+    INT_EOI;\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*               Established connection interrupt handling function.\r
+*\r
+* Description :\r
+*   Called upon connection establishment, and may be inserted in user code if needed by\r
+*   the programmer.\r
+* Arguments   : None\r
+* Returns     : None\r
+* Note        : Internal Function\r
+****************************************************************************************************\r
+*/\r
+/*\r
+void ISR_ESTABLISHED(SOCKET s)\r
+{\r
+// TO ADD YOUR CODE\r
+}\r
+*/\r
+\r
+/*\r
+****************************************************************************************************\r
+*               Closed connection interrupt handling function\r
+*\r
+* Description :\r
+*   Called upon connection closure, and may be inserted in user code if needed by the programmer.\r
+* Arguments   : None\r
+* Returns     : None\r
+* Note        : Internal Function\r
+****************************************************************************************************\r
+*/\r
+/*\r
+void ISR_CLOSED(SOCKET s)\r
+{\r
+// TO ADD YOUR CODE\r
+}\r
+*/\r
+\r
+/*\r
+****************************************************************************************************\r
+*               Received data interrupt handling function\r
+*\r
+* Description :\r
+*   Called upon receiving data, and may be inserted in user code if needed by the programmer.\r
+* Arguments   : None\r
+* Returns     : None\r
+* Note        : Internal Function\r
+****************************************************************************************************\r
+*/\r
+/*\r
+void ISR_RX(SOCKET s)\r
+{\r
+// TO ADD YOUR CODE\r
+}\r
+*/\r
+\r
+/*\r
+****************************************************************************************************\r
+*              W3100A Initialization Function\r
+*\r
+* Description:  Reset of W3100A S/W and Registeration of i386 interrupt\r
+* Arguments  : None.\r
+* Returns    : None.\r
+* Note       :\r
+****************************************************************************************************\r
+*/\r
+void initW3100A(void)\r
+{\r
+\r
+// Install interrupt handler for i2Chip\r
+INT_INIT(in4_isr_i2chip);\r
+\r
+\r
+Local_Port = 1000;         // This default value will be set if you didn't designate it when you\r
+                           // create a socket. If you don't designate port number and create a\r
+                           // socket continuously, the port number will be assigned with\r
+                           // incremented by one to Local_Port\r
+SEQ_NUM.lVal = 4294967293ul;   // Sets the initial SEQ# to be used for TCP communication.\r
+                           // (It should be ramdom value)\r
+WRITE_VALUE(COMMAND(0), CSW_RESET);   // Software RESET\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*               W3100A initialization function\r
+*\r
+* Description :\r
+*   Sets the Tx, Rx memory size by each channel, source MAC, source IP, gateway, and subnet mask\r
+*   to be used by the W3100A to the designated values.\r
+*   May be called when reflecting modified network information or Tx, Rx memory size on the W3100A\r
+*   Include Ping Request for ARP update (In case that a device embedding W3100A is directly\r
+*     connected to Router)\r
+* Arguments  : sbufsize - Tx memory size (00 - 1KByte, 01- 2KBtye, 10 - 4KByte, 11 - 8KByte)\r
+*                          bit 1-0 : Tx memory size of channel #0\r
+*                          bit 3-2 : Tx memory size of channel #1\r
+*                          bit 5-4 : Tx memory size of channel #2\r
+*                          bit 7-6 : Tx memory size of channel #3\r
+*              rbufsize - Rx memory size (00 - 1KByte, 01- 2KBtye, 10 - 4KByte, 11 - 8KByte)\r
+*                          bit 1-0 : Rx memory size of channel #0\r
+*                          bit 3-2 : Rx memory size of channel #1\r
+*                          bit 5-4 : Rx memory size of channel #2\r
+*                          bit 7-6 : Rx memory size of channel #3\r
+* Returns    : None\r
+* Note       : API Function\r
+*              Maximum memory size for Tx, Rx in W3100A is 8KBytes,\r
+*              In the range of 8KBytes, the memory size could be allocated dynamically by\r
+*              each channel\r
+*              Be attentive to sum of memory size shouldn't exceed 8Kbytes\r
+*              and to data transmission and receiption from non-allocated channel may cause\r
+*              some problems.\r
+*              If 8KBytes memory already is assigned to centain channel, other 3 channels\r
+*                couldn't be used, for there's no available memory.\r
+*              If two 4KBytes memory are assigned to two each channels, other 2 channels couldn't\r
+*                be used, for there's no available memory.\r
+*              (Example of memory assignment)\r
+*               sbufsize => 00000011, rbufsize => 00000011 :\r
+*                 Assign 8KBytes for Tx and Rx to channel #0, Cannot use channel #1,#2,#3\r
+*               sbufsize => 00001010, rbufsize => 00001010 :\r
+*                 Assign 4KBytes for Tx and Rx to each channel #0,#1 respectively. Cannot use\r
+*                 channel #2,#3\r
+*               sbufsize => 01010101, rbufsize => 01010101 :\r
+*                 Assign 2KBytes for Tx and Rx to each all channels respectively.\r
+*               sbufsize => 00010110, rbufsize => 01010101 :\r
+*                 Assign 4KBytes for Tx, 2KBytes for Rx to channel #0\r
+*       s          2KBytes for Tx, 2KBytes for Rx to channel #1\r
+*                 2KBytes for Tx, 2KBytes for Rx to channel #2\r
+*                 2KBytes is available exclusively for Rx in channel #3. There's no memory for Tx.\r
+****************************************************************************************************\r
+*/\r
+void sysinit(u_char sbufsize, u_char rbufsize)\r
+{\r
+char i;\r
+int ssum,rsum;\r
+\r
+ssum = 0;\r
+rsum = 0;\r
+\r
+// Set Tx memory size for each channel\r
+WRITE_VALUE(TX_DMEM_SIZE, sbufsize);\r
+\r
+// Set Rx memory size for each channel\r
+WRITE_VALUE(RX_DMEM_SIZE, rbufsize);\r
+\r
+// Set Base Address of Tx memory for channel #0\r
+SBUFBASEADDRESS[0] = 0;\r
+\r
+// Set Base Address of Rx memory for channel #0\r
+RBUFBASEADDRESS[0] = 0;\r
+\r
+// Set maximum memory size for Tx and Rx, mask, base address of memory by each channel\r
+for(i = 0 ; i < MAX_SOCK_NUM; i++)\r
+  {\r
+  SSIZE[i] = 0;\r
+  RSIZE[i] = 0;\r
+  if(ssum < 8192)\r
+        {\r
+        switch((sbufsize >> i*2) & 0x03) // Set maximum Tx memory size\r
+               {\r
+               case 0:\r
+                 SSIZE[i] = 1024;\r
+                 SMASK[i] = 0x000003FF;\r
+                 break;\r
+\r
+               case 1:\r
+                 SSIZE[i] = 2048;\r
+                 SMASK[i] = 0x000007FF;\r
+                 break;\r
+\r
+               case 2:\r
+                 SSIZE[i] = 4096;\r
+                 SMASK[i] = 0x00000FFF;\r
+                 break;\r
+\r
+               case 3:\r
+                 SSIZE[i] = 8192;\r
+                 SMASK[i] = 0x00001FFF;\r
+                 break;\r
+               }\r
+        }\r
+  if(rsum < 8192)\r
+        {\r
+        switch((rbufsize >> i*2) & 0x03)  // Set maximum Rx memory size\r
+               {\r
+               case 0:\r
+                 RSIZE[i] = 1024;\r
+                 RMASK[i] = 0x000003FF;\r
+                 break;\r
+\r
+               case 1:\r
+                 RSIZE[i] = 2048;\r
+                 RMASK[i] = 0x000007FF;\r
+                 break;\r
+\r
+               case 2:\r
+                 RSIZE[i] = 4096;\r
+                 RMASK[i] = 0x00000FFF;\r
+                 break;\r
+\r
+               case 3:\r
+                 RSIZE[i] = 8192;\r
+                 RMASK[i] = 0x00001FFF;\r
+                 break;\r
+               }\r
+        }\r
+  ssum += SSIZE[i];\r
+  rsum += RSIZE[i];\r
+\r
+  // Set base address of Tx and Rx memory for channel #1,#2,#3\r
+  if(i != 0)\r
+    {\r
+    SBUFBASEADDRESS[i] = ssum - SSIZE[i];\r
+    RBUFBASEADDRESS[i] = rsum - RSIZE[i];\r
+    }\r
+  }\r
+\r
+  WRITE_VALUE(COMMAND(0), CSYS_INIT);\r
+\r
+while(!(I_STATUS[0] & SSYS_INIT_OK))\r
+  I2CHIP_POLL_ISR(in4_isr_i2chip);\r
+\r
+#ifdef __PING__\r
+  {\r
+  u_char xdata pingbuf[8];\r
+  setIPprotocol(0, IPPROTO_ICMP);\r
+  socket(0, SOCK_IPL_RAW, 3000,0);     // Create a socket for ARP update\r
+\r
+  pingbuf[0] = 8;                      // ICMP TYPE\r
+  pingbuf[1] = 0;                      // ICMP CODE\r
+  pingbuf[2] = 0xf7;                   // CHECKSUM (already calculated)\r
+  pingbuf[3] = 0xfd;\r
+  pingbuf[4] = 0;                      // ID\r
+  pingbuf[5] = 1;\r
+  pingbuf[6] = 0;                      // SEQ #\r
+  pingbuf[7] = 1;\r
+  pingbuf[8] = 0;                      // Data 1 Byte\r
+\r
+  sendto(0, pingbuf, 9, GATEWAY_PTR,3000);  // Ping Request\r
+  close(0);\r
+  printf("Route MAC Update Success");\r
+  }\r
+#endif\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*              Function to set subnet mask\r
+*\r
+* Description:\r
+* Arguments  : addr--> Pointer that has the value to be set\r
+* Returns    : None.\r
+* Note       :\r
+****************************************************************************************************\r
+*/\r
+void setsubmask(u_char * addr)\r
+{\r
+u_char i;\r
+u_char far* sm_ptr = SUBNET_MASK_PTR;   // We can only convert to 'regular'\r
+                                   // pointer if we're confident arithmetic\r
+                                   // won't take us out of current window.\r
+\r
+for (i = 0; i < 4; i++)\r
+  {\r
+  WRITE_VALUE(sm_ptr + SA_OFFSET(i), addr[i]);\r
+  }\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*               Function to set gateway IP\r
+*\r
+* Description:\r
+* Arguments  : addr--> Pointer that has Gateway IP to be set\r
+* Returns    : None.\r
+* Note       :\r
+****************************************************************************************************\r
+*/\r
+void setgateway(u_char * addr)\r
+{\r
+u_char i;\r
+u_char far* gw_ptr = GATEWAY_PTR;   // We can only convert to 'regular'\r
+                                   // pointer if we're confident arithmetic\r
+                                   // won't take us out of current window.\r
+for (i = 0; i < 4; i++)\r
+  {\r
+  WRITE_VALUE(gw_ptr + SA_OFFSET(i), addr[i]);\r
+  }\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*                 Function to set W3100A IP\r
+*\r
+* Description:\r
+* Arguments  : addr--> Pointer that has Source IP to be set\r
+* Returns    : None.\r
+* Note       :\r
+****************************************************************************************************\r
+*/\r
+void setIP(u_char * addr)\r
+{\r
+u_char i;\r
+u_char far* src_ptr = SRC_IP_PTR;   // We can only convert to 'regular'\r
+                                   // pointer if we're confident arithmetic\r
+                                   // won't take us out of current window.\r
+\r
+for (i = 0; i < 4; i++)\r
+  {\r
+  WRITE_VALUE(src_ptr + SA_OFFSET(i), addr[i]);\r
+  }\r
+}\r
+\r
+// DEBUG\r
+void getIP(u_char* addr)\r
+{\r
+u_char i;\r
+u_char far* src_ptr = SRC_IP_PTR;   // We can only convert to 'regular'\r
+                                   // pointer if we're confident arithmetic\r
+                                   // won't take us out of current window.\r
+\r
+for (i = 0; i < 4; i++)\r
+       addr[i] = READ_VALUE(src_ptr + SA_OFFSET(i));\r
+}\r
+\r
+\r
+/*\r
+****************************************************************************************************\r
+*                Function to set MAC\r
+*\r
+* Description:\r
+* Arguments  : addr--> Pointer that has MAC to be set\r
+* Returns    : None.\r
+* Note       :\r
+****************************************************************************************************\r
+*/\r
+void setMACAddr(u_char * addr)\r
+{\r
+u_char i;\r
+u_char far* ha_ptr = SRC_HA_PTR;   // We can only convert to 'regular'\r
+                                   // pointer if we're confident arithmetic\r
+                                   // won't take us out of current window.\r
+\r
+for (i = 0; i < 6; i++)\r
+  {\r
+  WRITE_VALUE(ha_ptr + SA_OFFSET(i), addr[i]);\r
+  }\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*                  Function to set TCP timeout\r
+*\r
+* Description: The function that used to adjust time to resend TCP\r
+* Arguments  : val     --> Pointer that has the value to be set\r
+*                                      Upper 2 byte:Initial timeout value\r
+*                                      Last 1 byte:The count to retry till timeout\r
+* Returns    : None.\r
+* Note       :\r
+****************************************************************************************************\r
+*/\r
+void settimeout(u_char * val)\r
+{\r
+u_char i;\r
+u_char far* tout_ptr = TIMEOUT_PTR;   // We can only convert to 'regular'\r
+                                   // pointer if we're confident arithmetic\r
+                                   // won't take us out of current window.\r
+\r
+for (i = 0; i < 3; i++)\r
+  {\r
+  WRITE_VALUE(tout_ptr + SA_OFFSET(i), val[i]);\r
+  }\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*                 Function to set interrupt mask.\r
+*\r
+* Description:\r
+* Arguments  : mask--> Mask value to be set ('1'-> interrupt )\r
+* Returns    : None.\r
+* Note       :\r
+****************************************************************************************************\r
+*/\r
+void setINTMask(u_char mask)\r
+{\r
+WRITE_VALUE(INTMASK, mask);\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*                  Function to set enable in sending and receiving of broadcast data\r
+*\r
+* Description:  Enable to process of broadcating data in UDP or IP RAW mode.\r
+* Arguments  : s       --> Channel No. to be set\r
+* Returns    : None.\r
+* Note       :\r
+****************************************************************************************************\r
+*/\r
+void setbroadcast(SOCKET s)\r
+{\r
+u_char val = READ_VALUE(OPT_PROTOCOL(s));\r
+WRITE_VALUE(OPT_PROTOCOL(s), val | SOCKOPT_BROADCAST);\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*                Function to set process protocol  in IP RAW mode.\r
+*\r
+* Description:\r
+* Arguments  : s--> Channel No. to be set\r
+*              tos-->Protocol Value to be set\r
+* Returns    : None.\r
+* Note       :\r
+****************************************************************************************************\r
+*/\r
+void setTOS(SOCKET s, u_char tos)\r
+{\r
+WRITE_VALUE(TOS(s), tos);\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*               Upper layer protocol setup function in IP RAW Mode\r
+*\r
+* Description : Upper layer protocol setup function in protocol field of IP header when\r
+*                    developing upper layer protocol like ICMP, IGMP, EGP etc. by using IP Protocol\r
+* Arguments   : s          - Channel number\r
+*               ipprotocol - Upper layer protocol setting value of IP Protocol\r
+*                            (Possible to use designated IPPROTO_ in header file)\r
+* Returns     : None\r
+* Note        : API Function\r
+*                  This function should be called before calling socket() that is, before\r
+*                  socket initialization.\r
+****************************************************************************************************\r
+*/\r
+void setIPprotocol(SOCKET s, u_char ipprotocol)\r
+{\r
+WRITE_VALUE(IP_PROTOCOL(s), ipprotocol);\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*              Initialization function to appropriate channel\r
+*\r
+* Description : Initialize designated channel and wait until W3100 has done.\r
+* Arguments   : s - channel number\r
+*               protocol - designate protocol for channel\r
+*                          SOCK_STREAM(0x01) -> TCP.\r
+*                          SOCK_DGRAM(0x02)  -> UDP.\r
+*                          SOCK_IPL_RAW(0x03) -> IP LAYER RAW.\r
+*                          SOCK_MACL_RAW(0x04) -> MAC LAYER RAW.\r
+*               port     - designate source port for appropriate channel\r
+*               flag     - designate option to be used in appropriate.\r
+*                          SOCKOPT_BROADCAST(0x80) -> Send/receive broadcast message in UDP\r
+*                          SOCKOPT_NDTIMEOUT(0x40) -> Use register value which designated TIMEOUT\r
+*                            value\r
+*                          SOCKOPT_NDACK(0x20)     -> When not using no delayed ack\r
+*                          SOCKOPT_SWS(0x10)       -> When not using silly window syndrome\r
+* Returns     : When succeeded : Channel number, failed :-1\r
+* Note        : API Function\r
+****************************************************************************************************\r
+*/\r
+char socket(SOCKET s, u_char protocol, u_int port, u_char flag)\r
+{\r
+u_char k;\r
+\r
+//Designate socket protocol and option\r
+WRITE_VALUE(OPT_PROTOCOL(s), protocol | flag);\r
+\r
+// setup designated port number\r
+if (port != 0)\r
+  {\r
+  k = (u_char)((port & 0xff00) >> 8);\r
+  WRITE_VALUE(SRC_PORT_PTR(s), k);\r
+  k = (u_char)(port & 0x00ff);\r
+  WRITE_VALUE(SRC_PORT_PTR(s) + SA_OFFSET(1), k);\r
+  }\r
+else\r
+  {\r
+  // Designate random port number which is managed by local when you didn't designate source port\r
+  Local_Port++;\r
+\r
+  WRITE_VALUE(SRC_PORT_PTR(s), (u_char)((Local_Port & 0xff00) >> 8));\r
+  WRITE_VALUE(SRC_PORT_PTR(s) + SA_OFFSET(1), (u_char)(Local_Port & 0x00ff));\r
+  }\r
+\r
+// SOCK_INIT\r
+I_STATUS[s] = 0;\r
+WRITE_VALUE(COMMAND(s), CSOCK_INIT);\r
+\r
+// Waiting Interrupt to CSOCK_INIT\r
+while (I_STATUS[s] == 0)\r
+       I2CHIP_POLL_ISR(in4_isr_i2chip);\r
+\r
+if (!(I_STATUS[s] & SSOCK_INIT_OK))\r
+  return(-1);\r
+\r
+initseqnum(s);                                                 //  Use initial seq# with random number\r
+\r
+return(s);\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*               Connection establishing function to designated peer.\r
+*\r
+* Description : This function establish a connection to the peer by designated channel,\r
+*     and wait until the connection is established successfully. (TCP client mode)\r
+* Arguments   : s    - channel number\r
+*               addr - destination IP Address\r
+*               port - destination Port Number\r
+* Returns     : when succeeded : 1, failed : -1\r
+* Note        : API Function\r
+****************************************************************************************************\r
+*/\r
+char connect(SOCKET s, u_char far * addr, u_int port)\r
+{\r
+\r
+if (port != 0)\r
+  {                                            //designate destination port\r
+  WRITE_VALUE(DST_PORT_PTR(s), (u_char)((port & 0xff00) >> 8));\r
+  WRITE_VALUE(DST_PORT_PTR(s) + SA_OFFSET(1), (u_char)(port & 0x00ff));\r
+  }\r
+else\r
+  return(-1);\r
+\r
+  WRITE_VALUE(DST_IP_PTR(s), addr[0]);                         //designate destination IP address\r
+  WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(1), addr[1]);\r
+  WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(2), addr[2]);\r
+  WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(3), addr[3]);\r
+\r
+I_STATUS[s] = 0;\r
+\r
+  WRITE_VALUE(COMMAND(s), CCONNECT);                                   // CONNECT\r
+  I2CHIP_POLL_ISR(in4_isr_i2chip);\r
+\r
+// Wait until connection is established successfully\r
+while (I_STATUS[s] == 0)\r
+  {\r
+  // When failed, appropriate channel will be closed and return an error\r
+  if (select(s, SEL_CONTROL) == SOCK_CLOSED)\r
+    return -1;\r
+  }\r
+\r
+if (!(I_STATUS[s] & SESTABLISHED))\r
+  return(-1);\r
+\r
+return(1);\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*               Connection establishing function to designated peer. (Non-blocking Mode)\r
+*\r
+* Description : This function establish a connection to the peer by designated channel.\r
+*\r
+* Arguments   : s    - channel number\r
+*               addr - destination IP Address\r
+*               port - destination Port Number\r
+* Returns     : when succeeded : 1, failed : -1\r
+* Note        : API Function\r
+****************************************************************************************************\r
+*/\r
+char NBconnect(SOCKET s, u_char far * addr, u_int port)\r
+{\r
+\r
+if (port != 0)\r
+  {                                            //designate destination port\r
+       WRITE_VALUE(DST_PORT_PTR(s), (u_char) ((port & 0xff00) >> 8) );\r
+   WRITE_VALUE(DST_PORT_PTR(s) + SA_OFFSET(1), (u_char)(port & 0x00ff));\r
+  }\r
+else\r
+  return(-1);\r
+\r
+  WRITE_VALUE(DST_IP_PTR(s), addr[0]);                         //designate destination IP address\r
+  WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(1), addr[1]);\r
+  WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(2), addr[2]);\r
+  WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(3), addr[3]);\r
+\r
+I_STATUS[s] = 0;\r
+\r
+WRITE_VALUE(COMMAND(s), CCONNECT);                                     // CONNECT\r
+return(1);\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*            Waits for connection request from a peer (Blocking Mode)\r
+*\r
+* Description : Wait for connection request from a peer through designated channel (TCP Server mode)\r
+* Arguments   : s    - channel number\r
+*               addr - IP Address of the peer when a connection is established\r
+*               port - Port number of the peer when a connection is established\r
+* Returns     : When succeeded : 1, failed : -1\r
+* Note        : API Function\r
+****************************************************************************************************\r
+*/\r
+/*\r
+char listen(SOCKET s, u_char far * addr, u_int far * port)\r
+{\r
+u_int i;\r
+\r
+I_STATUS[s] = 0;\r
+\r
+// LISTEN\r
+COMMAND(s) = CLISTEN;\r
+\r
+// Wait until connection is established\r
+while (I_STATUS[s] == 0)\r
+  {\r
+  // When failed to connect, the designated channel will be closed and return an error.\r
+  if (select(s, SEL_CONTROL) == SOCK_CLOSED)\r
+    return -1;\r
+  }\r
+\r
+// Receive IP address and port number of the peer connected\r
+if (I_STATUS[s] & SESTABLISHED)\r
+  {\r
+  i = *DST_PORT_PTR(s);\r
+  *port = (u_int)((i & 0xff00) >> 8);\r
+  i = *(DST_PORT_PTR(s) + 2);\r
+  i = (u_int)(i & 0x00ff);\r
+  *port += (i << 8);\r
+\r
+  addr[0] = *DST_IP_PTR(s);\r
+  addr[1] = *(DST_IP_PTR(s) + 2);\r
+  addr[2] = *(DST_IP_PTR(s) + 4);\r
+  addr[3] = *(DST_IP_PTR(s) + 6);\r
+  }\r
+else\r
+  return(-1);\r
+\r
+return(1);\r
+}\r
+*/\r
+\r
+/*\r
+****************************************************************************************************\r
+*                Waits for connection request from a peer (Non-blocking Mode)\r
+*\r
+* Description : Wait for connection request from a peer through designated channel (TCP Server mode)\r
+* Arguments   : s - channel number\r
+* Returns     : None\r
+* Note        : API Function\r
+****************************************************************************************************\r
+*/\r
+char NBlisten(SOCKET s)\r
+{\r
+I_STATUS[s] = 0;\r
+\r
+// LISTEN\r
+WRITE_VALUE(COMMAND(s), CLISTEN);\r
+\r
+return(1);\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*               Create random value for initial Seq# when establishing TCP connection\r
+*\r
+* Description : In this function, you can add some source codes to create random number for\r
+*     initial Seq#. In real, TCP initial SEQ# should be random value.\r
+*               (Currently, we're using static value in EVB/DK.)\r
+* Arguments   : s - channel number\r
+* Returns     : None\r
+* Note        : API Function\r
+****************************************************************************************************\r
+*/\r
+void initseqnum(SOCKET s)\r
+{\r
+// Designate initial seq#\r
+// If you have random number generation function, assign random number instead of SEQ_NUM.lVal++.\r
+SEQ_NUM.lVal++;\r
+\r
+//randomize();\r
+//SEQ_NUM.lVal = rand();\r
+\r
+WRITE_VALUE(TX_WR_PTR(s), SEQ_NUM.cVal[0]);\r
+WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(1), SEQ_NUM.cVal[1]);\r
+WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(2), SEQ_NUM.cVal[2]);\r
+WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(3), SEQ_NUM.cVal[3]);\r
+delay0(2);\r
+\r
+WRITE_VALUE(TX_RD_PTR(s), SEQ_NUM.cVal[0]);\r
+WRITE_VALUE(TX_RD_PTR(s) + SA_OFFSET(1), SEQ_NUM.cVal[1]);\r
+WRITE_VALUE(TX_RD_PTR(s) + SA_OFFSET(2), SEQ_NUM.cVal[2]);\r
+WRITE_VALUE(TX_RD_PTR(s) + SA_OFFSET(3), SEQ_NUM.cVal[3]);\r
+delay0(2);\r
+\r
+WRITE_VALUE(TX_ACK_PTR(s), SEQ_NUM.cVal[0]);\r
+WRITE_VALUE(TX_ACK_PTR(s) + SA_OFFSET(1), SEQ_NUM.cVal[1]);\r
+WRITE_VALUE(TX_ACK_PTR(s) + SA_OFFSET(2), SEQ_NUM.cVal[2]);\r
+WRITE_VALUE(TX_ACK_PTR(s) + SA_OFFSET(3), SEQ_NUM.cVal[3]);\r
+delay0(2);\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*              Function for sending TCP data.\r
+*\r
+* Description : Function for sending TCP data and Composed of the send() and send_in() functions.\r
+*     The send() function is an application I/F function.\r
+*     It continues to call the send_in() function to complete the sending of the data up to the\r
+*     size of the data to be sent when the application is called.\r
+*     The send_in() function receives the return value (the size of the data sent), calculates\r
+*     the size of the data to be sent, and calls the send_in() function again if there is any\r
+*     data left to be sent.\r
+* Arguments   : s   - channel number\r
+*               buf - Pointer pointing data to send\r
+*               len - data size to send\r
+* Returns     : Succeed: sent data size, Failed:  -1;\r
+* Note        : API Function\r
+****************************************************************************************************\r
+*/\r
+int send(SOCKET s, u_char far * buf, u_int len)\r
+{\r
+int ptr, size;\r
+u_char huge* huge_buf = (u_char huge*)buf;\r
+u_char far*  local_buf = (u_char far*)huge_buf;    \r
+\r
+if (len <= 0)\r
+  return (0);\r
+else\r
+  {\r
+  ptr = 0;\r
+  do\r
+    {\r
+        size = send_in(s, local_buf + ptr, len);\r
+        if (size == -1)\r
+      return -1;\r
+        len = len - size;\r
+        ptr += size;\r
+        } while ( len > 0);\r
+  }\r
+return ptr;\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*              Internal function for sending TCP data.\r
+*\r
+* Description : Called by the send() function for TCP transmission.\r
+*    It first calculates the free transmit buffer size\r
+*    and compares it with the size of the data to be transmitted to determine the transmission size.\r
+*    After calculating the data size, it copies data from TX_WR_PTR.\r
+*    It waits if there is a previous send command in process.\r
+*    When the send command is cleared, it updates the TX_WR_PTR up to the size to be transmitted\r
+     and performs the send command.\r
+* Arguments   : s   - channel number\r
+*               buf - Pointer pointing data to send\r
+*               len - data size to send\r
+* Returns     : Succeeded: sent data size, Failed: -1\r
+* Note        : Internal Function\r
+****************************************************************************************************\r
+*/\r
+int send_in(SOCKET s, u_char far * buf, u_int len)\r
+{\r
+u_char k;\r
+u_int size;\r
+union un_l2cval wr_ptr, ack_ptr;\r
+unsigned int offset;\r
+\r
+S_START:\r
+disable();            // CT: Shadow register access should not conflict with ISR.\r
+k = READ_VALUE(SHADOW_TXWR_PTR(s));\r
+WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.\r
+delay0(2);\r
+wr_ptr.cVal[3] = READ_VALUE(TX_WR_PTR(s));\r
+wr_ptr.cVal[2] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(1));\r
+wr_ptr.cVal[1] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(2));\r
+wr_ptr.cVal[0] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(3));\r
+\r
+k = READ_VALUE(SHADOW_TXACK_PTR(s));\r
+WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.\r
+delay0(2);\r
+ack_ptr.cVal[3] = READ_VALUE(TX_ACK_PTR(s));\r
+ack_ptr.cVal[2] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(1));\r
+ack_ptr.cVal[1] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(2));\r
+ack_ptr.cVal[0] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(3));\r
+enable();\r
+\r
+// Suppress compiler errors that k is not used\r
+k = k;\r
+\r
+//  Calculate send free buffer size\r
+if (wr_ptr.lVal >= ack_ptr.lVal)\r
+  size = (u_int)(SSIZE[s] - (wr_ptr.lVal - ack_ptr.lVal));\r
+else\r
+  size = (u_int)(SSIZE[s] - (0 - ack_ptr.lVal + wr_ptr.lVal));\r
+\r
+// Recalulate after some delay because of error in pointer calculation\r
+if (size > SSIZE[s])\r
+  {\r
+  if (select(s, SEL_CONTROL) != SOCK_ESTABLISHED)\r
+    return -1;\r
+  delay_ms(1);\r
+        goto S_START;\r
+  }\r
+\r
+// Wait when previous sending has not finished yet and there's no free buffer\r
+if (size == 0)\r
+  {\r
+  if (select(s, SEL_CONTROL) != SOCK_ESTABLISHED)\r
+    return -1;\r
+\r
+  delay_ms(1);\r
+  goto S_START;\r
+  }\r
+else if (size < len)\r
+  {\r
+  len = size;\r
+  }\r
+\r
+//  Calculate pointer to data copy\r
+offset = (UINT)(wr_ptr.lVal & SMASK[s]);\r
+\r
+// copy data\r
+write_data(s, buf, offset, len);\r
+\r
+while (READ_VALUE(COMMAND(s)) & CSEND)\r
+  {\r
+  // Confirm previous send command\r
+  if (select(s, SEL_CONTROL) != SOCK_ESTABLISHED)\r
+    return -1;\r
+  }\r
+\r
+//  update tx_wr_ptr\r
+wr_ptr.lVal = wr_ptr.lVal + len;\r
+WRITE_VALUE(TX_WR_PTR(s), wr_ptr.cVal[3]);\r
+WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(1), wr_ptr.cVal[2]);\r
+WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(2), wr_ptr.cVal[1]);\r
+WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(3), wr_ptr.cVal[0]);\r
+\r
+delay0(1);\r
+\r
+// SEND\r
+WRITE_VALUE(COMMAND(s), CSEND);\r
+\r
+return(len);\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*              TCP data receiving function.\r
+*\r
+* Description : This function is to clear out any received TCP data.\r
+* Arguments   : s   - channel number\r
+* Returns     : None\r
+* Note        : API Fcuntion\r
+****************************************************************************************************\r
+*/\r
+void recv_clear(SOCKET s)\r
+{\r
+u_char k;\r
+u_int size;\r
+union un_l2cval wr_ptr, rd_ptr;\r
+\r
+disable();\r
+k = READ_VALUE(SHADOW_RXWR_PTR(s));\r
+WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.\r
+delay0(2);\r
+wr_ptr.cVal[3] = READ_VALUE(RX_WR_PTR(s));\r
+wr_ptr.cVal[2] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(1));\r
+wr_ptr.cVal[1] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(2));\r
+wr_ptr.cVal[0] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(3));\r
+\r
+k = READ_VALUE(SHADOW_RXRD_PTR(s));\r
+WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.\r
+delay0(2);\r
+rd_ptr.cVal[3] = READ_VALUE(RX_RD_PTR(s));\r
+rd_ptr.cVal[2] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(1));\r
+rd_ptr.cVal[1] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(2));\r
+rd_ptr.cVal[0] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(3));\r
+enable();\r
+\r
+// Suppress compiler errors that k is not used\r
+k = k;\r
+\r
+//  calculate received data size\r
+if (wr_ptr.lVal >= rd_ptr.lVal)\r
+  size = (u_int)(wr_ptr.lVal - rd_ptr.lVal);\r
+else\r
+  size = (u_int)(0 - rd_ptr.lVal + wr_ptr.lVal);\r
+\r
+// Update rx_rd_ptr\r
+rd_ptr.lVal += size;\r
+WRITE_VALUE(RX_RD_PTR(s), rd_ptr.cVal[3]);\r
+WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(1), rd_ptr.cVal[2]);\r
+WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(2), rd_ptr.cVal[1]);\r
+WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(3), rd_ptr.cVal[0]);\r
+\r
+// RECV\r
+ WRITE_VALUE(COMMAND(s), CRECV);\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*              TCP data receiving function.\r
+*\r
+* Description : This function is for receiving TCP data.\r
+*     The recv() function is an application I/F function. It will read up to len chars if there are\r
+      enough characters in the buffer, otherwise will onl read the number of characters availiable\r
+* Arguments   : s   - channel number\r
+*               buf - Pointer where the data to be received is copied\r
+*               len - Size of the data to be received\r
+* Returns     : Succeeded: received data size, Failed: -1\r
+* Note        : API Fcuntion\r
+****************************************************************************************************\r
+*/\r
+int recv(SOCKET s, u_char far * buf, u_int len)\r
+{\r
+u_char k;\r
+u_int size;\r
+union un_l2cval wr_ptr, rd_ptr;\r
+unsigned int offset;\r
+\r
+// If out length is 0, then we do not need to do anything\r
+if (len <= 0)\r
+  return (0);\r
+\r
+disable();\r
+k = READ_VALUE(SHADOW_RXWR_PTR(s));\r
+WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.\r
+delay0(2);\r
+wr_ptr.cVal[3] = READ_VALUE(RX_WR_PTR(s));\r
+wr_ptr.cVal[2] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(1));\r
+wr_ptr.cVal[1] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(2));\r
+wr_ptr.cVal[0] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(3));\r
+\r
+k = READ_VALUE(SHADOW_RXRD_PTR(s));\r
+WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.\r
+delay0(2);\r
+rd_ptr.cVal[3] = READ_VALUE(RX_RD_PTR(s));\r
+rd_ptr.cVal[2] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(1));\r
+rd_ptr.cVal[1] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(2));\r
+rd_ptr.cVal[0] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(3));\r
+enable();\r
+\r
+// Suppress compiler errors that k is not used\r
+k = k;\r
+\r
+//  calculate IIM7010A received data size\r
+if (wr_ptr.lVal == rd_ptr.lVal)\r
+  return(0);\r
+else if (wr_ptr.lVal >= rd_ptr.lVal)\r
+  size = (u_int)(wr_ptr.lVal - rd_ptr.lVal);\r
+else\r
+  size = (u_int)(0 - rd_ptr.lVal + wr_ptr.lVal);\r
+\r
+// Make sure we do not try to read more characters than what is availiable in the IIM7010 buffer\r
+if (size < len)\r
+  len = size;\r
+\r
+// Calculate pointer to be copied received data\r
+offset = ((UINT)(rd_ptr.lVal & RMASK[s]));\r
+\r
+// Copy received data\r
+size = read_data(s, offset, buf, len);\r
+\r
+// Update rx_rd_ptr\r
+rd_ptr.lVal += size;\r
+WRITE_VALUE(RX_RD_PTR(s), rd_ptr.cVal[3]);\r
+WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(1), rd_ptr.cVal[2]);\r
+WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(2), rd_ptr.cVal[1]);\r
+WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(3), rd_ptr.cVal[0]);\r
+\r
+// RECV\r
+ WRITE_VALUE(COMMAND(s), CRECV);\r
+return(size);\r
+}\r
+\r
+\r
+/*\r
+****************************************************************************************************\r
+*               UDP data sending function.\r
+*\r
+* Description : Composed of the sendto()and sendto_in() functions.\r
+*    The send() function is an application I/F function.\r
+*    It continues to call the send_in() function to complete the sending of the data up to the\r
+*    size of the data to be sent\r
+*    when the application is called.Unlike TCP transmission, it designates the destination address\r
+*    and the port.\r
+* Arguments   : s    - channel port\r
+*               buf  - Pointer pointing data to send\r
+*               len  - data size to send\r
+*               addr - destination IP address to send data\r
+*               port - destination port number to send data\r
+* Returns     : Sent data size\r
+* Note        : API Function\r
+****************************************************************************************************\r
+*/\r
+u_int sendto(SOCKET s, u_char far * buf, u_int len, u_char * addr, u_int port)\r
+{\r
+//char val;\r
+u_int ptr, size;\r
+\r
+// Wait until previous send commnad has completed.\r
+while(READ_VALUE(COMMAND(s)) & CSEND)\r
+  {\r
+  if(select(s, SEL_CONTROL) == SOCK_CLOSED)\r
+    return -1; // Error.\r
+  }\r
+\r
+// Designate destination port number.\r
+if (port != 0)\r
+  {\r
+  WRITE_VALUE(DST_PORT_PTR(s), (u_char)((port & 0xff00) >> 8));\r
+  WRITE_VALUE(DST_PORT_PTR(s) + SA_OFFSET(1), (u_char)(port & 0x00ff));\r
+  }\r
+\r
+//  Designate destination IP address\r
+WRITE_VALUE(DST_IP_PTR(s), addr[0]);\r
+WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(1), addr[1]);\r
+WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(2), addr[2]);\r
+WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(3), addr[3]);\r
+\r
+if (len <= 0)\r
+  return (0);\r
+else\r
+  {\r
+  ptr = 0;\r
+  do\r
+    {\r
+        size = sendto_in(s, buf + ptr, len);\r
+        len = len - size;\r
+        ptr += size;\r
+        } while ( len > 0);\r
+  }\r
+return ptr;\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*            UDP data sending function.\r
+*\r
+* Description : An internal function that is the same as the send_in() function of the TCP.\r
+* Arguments   : s   - Channel number\r
+*               buf - Pointer indicating the data to send\r
+*               len - data size to send\r
+* Returns     : Sent data size\r
+* Note        : Internal Function\r
+****************************************************************************************************\r
+*/\r
+u_int sendto_in(SOCKET s, u_char far * buf, u_int len)\r
+{\r
+u_char k;\r
+u_int size;\r
+union un_l2cval wr_ptr, rd_ptr;\r
+unsigned int offset;\r
+\r
+S2_START:\r
+disable();\r
+k = READ_VALUE(SHADOW_TXWR_PTR(s));\r
+WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.\r
+delay0(2);\r
+wr_ptr.cVal[3] = READ_VALUE(TX_WR_PTR(s));\r
+wr_ptr.cVal[2] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(1));\r
+wr_ptr.cVal[1] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(2));\r
+wr_ptr.cVal[0] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(3));\r
+\r
+k = READ_VALUE(SHADOW_TXRD_PTR(s));\r
+WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.\r
+delay0(2);\r
+rd_ptr.cVal[3] = READ_VALUE(TX_RD_PTR(s));\r
+rd_ptr.cVal[2] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(1));\r
+rd_ptr.cVal[1] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(2));\r
+rd_ptr.cVal[0] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(3));\r
+enable();\r
+\r
+// Suppress compiler errors that k is not used\r
+k = k;\r
+\r
+//  Calculate free buffer size to send\r
+if (wr_ptr.lVal >= rd_ptr.lVal)\r
+  size = (u_int)(SSIZE[s] - (wr_ptr.lVal - rd_ptr.lVal));\r
+else\r
+  size = (u_int)(SSIZE[s] - (0 - rd_ptr.lVal + wr_ptr.lVal));\r
+\r
+//  Recalulate after some delay because of error in pointer caluation\r
+if (size > SSIZE[s])\r
+  {\r
+  delay_ms(1);\r
+  goto S2_START;\r
+  }\r
+\r
+// Wait when previous sending has not finished yet and there's no free buffer\r
+if (size == 0)\r
+  {\r
+  delay_ms(1);\r
+  goto S2_START;\r
+\r
+  }\r
+else if (size < len)\r
+  {\r
+  len = size;\r
+  }\r
+\r
+// Calculate pointer to copy data pointer\r
+offset =(UINT)(wr_ptr.lVal & SMASK[s]);\r
+\r
+// copy data\r
+write_data(s, buf, offset, len);\r
+\r
+// Confirm previous send command\r
+while (READ_VALUE(COMMAND(s)) & CSEND)\r
+  {\r
+  if(select(s, SEL_CONTROL)==SOCK_CLOSED)\r
+    return -1;                  // Error\r
+  }\r
+\r
+// update tx_wr_ptr\r
+wr_ptr.lVal = wr_ptr.lVal + len;\r
+WRITE_VALUE(TX_WR_PTR(s), wr_ptr.cVal[3]);\r
+WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(1), wr_ptr.cVal[2]);\r
+WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(2), wr_ptr.cVal[1]);\r
+WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(3), wr_ptr.cVal[0]);\r
+\r
+delay0(1);\r
+\r
+// SEND\r
+WRITE_VALUE(COMMAND(s), CSEND);\r
+\r
+return(len);\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*             UDP data receiving function.\r
+*\r
+* Description : Function for receiving UDP and IP layer RAW mode data, and handling the data header.\r
+* Arguments   : s    - channel number\r
+*               buf  - Pointer where the data to be received is copied\r
+*               len  - Size of the data to be received\r
+*               addr - Peer IP address for receiving\r
+*               port - Peer port number for receiving\r
+* Returns     : Received data size\r
+* Note        : API Function\r
+****************************************************************************************************\r
+*/\r
+u_int recvfrom(SOCKET s, u_char far *buf, u_int len, u_char *addr, u_int *port)\r
+{\r
+struct _UDPHeader                                                                      // When receiving UDP data, header added by W3100A\r
+  {\r
+  union\r
+        {\r
+        struct\r
+               {\r
+               u_int size;\r
+               u_char addr[4];\r
+               u_int port;\r
+               } header;\r
+        u_char stream[8];\r
+    } u;\r
+  } UDPHeader;\r
+\r
+u_int ret;\r
+union un_l2cval wr_ptr, rd_ptr;\r
+u_long size;\r
+u_char k;\r
+unsigned int offset;\r
+\r
+if(select(s,SEL_CONTROL)==SOCK_CLOSED)\r
+  return -1;\r
+\r
+disable();\r
+k = READ_VALUE(SHADOW_RXWR_PTR(s));\r
+WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.\r
+delay0(2);\r
+wr_ptr.cVal[3] = READ_VALUE(RX_WR_PTR(s));\r
+wr_ptr.cVal[2] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(1));\r
+wr_ptr.cVal[1] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(2));\r
+wr_ptr.cVal[0] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(3));\r
+\r
+k = READ_VALUE(SHADOW_RXRD_PTR(s));\r
+WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.\r
+delay0(2);\r
+rd_ptr.cVal[3] = READ_VALUE(RX_RD_PTR(s));\r
+rd_ptr.cVal[2] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(1));\r
+rd_ptr.cVal[1] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(2));\r
+rd_ptr.cVal[0] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(3));\r
+enable();\r
+\r
+// Suppress compiler errors that k is not used\r
+k = k;\r
+\r
+// Calculate received data size\r
+if (len <= 0)\r
+  return (0);\r
+else if (wr_ptr.lVal >= rd_ptr.lVal)\r
+  size = wr_ptr.lVal - rd_ptr.lVal;\r
+else\r
+  size = 0 - rd_ptr.lVal + wr_ptr.lVal;\r
+\r
+if (size == 0)\r
+  return 0;\r
+\r
+  // Calulate received data pointer\r
+offset = ((UINT)(rd_ptr.lVal & RMASK[s]));\r
+\r
+// When UDP data\r
+if (( READ_VALUE(OPT_PROTOCOL(s)) & 0x07) == SOCK_DGRAM)\r
+  {\r
+  // Copy W3100A UDP header\r
+  read_data(s, offset, UDPHeader.u.stream, 8);\r
+\r
+  // Read UDP Packet size\r
+  size = UDPHeader.u.stream[0];\r
+  size = (size << 8) + UDPHeader.u.stream[1];\r
+\r
+  // Read IP address of the peer\r
+  addr[0] = UDPHeader.u.header.addr[0];\r
+  addr[1] = UDPHeader.u.header.addr[1];\r
+  addr[2] = UDPHeader.u.header.addr[2];\r
+  addr[3] = UDPHeader.u.header.addr[3];\r
+\r
+  // Read Port number of the peer\r
+  *port = UDPHeader.u.stream[6];\r
+  *port = (*port << 8) + UDPHeader.u.stream[7];\r
+\r
+  // Increase read pointer by 8, because already read as UDP header size\r
+  rd_ptr.lVal += 8;\r
+\r
+  // Calculate UDP data copy pointer\r
+  offset = ((UINT)(rd_ptr.lVal & RMASK[s]));\r
+\r
+  // Calculate data size of current UDP Packet from UDP header\r
+  size = size - 8;\r
+\r
+  // Copy one UDP data packet to user-specific buffer\r
+  ret = read_data(s, offset, buf, (u_int)size);\r
+\r
+  // Increase read pointer by UDP packet data size\r
+  rd_ptr.lVal += ret;\r
+  }\r
+else if ((READ_VALUE(OPT_PROTOCOL(s)) & 0x07) == SOCK_IPL_RAW)  // When IP layer RAW mode data\r
+  {\r
+  // Copy W3100A IP Raw header\r
+  read_data(s, offset, UDPHeader.u.stream, 6);\r
+\r
+  // Read IP layer RAW Packet size\r
+  size = UDPHeader.u.stream[0];\r
+  size = (size << 8) + UDPHeader.u.stream[1];\r
+\r
+  // Read IP address of the peer\r
+  addr[0] = UDPHeader.u.header.addr[0];\r
+  addr[1] = UDPHeader.u.header.addr[1];\r
+  addr[2] = UDPHeader.u.header.addr[2];\r
+  addr[3] = UDPHeader.u.header.addr[3];\r
+\r
+  // Increase read pointer by 6, because already read as IP RAW header size\r
+  rd_ptr.lVal += 6;\r
+\r
+  // Calculate IP layer raw mode data pointer\r
+  offset = ((UINT)(rd_ptr.lVal & RMASK[s]));\r
+\r
+  // Copy one IP Raw data packet to user-specific buffer\r
+  ret = read_data(s, offset, buf, (u_int)size);\r
+  rd_ptr.lVal = rd_ptr.lVal + (ret - 4);\r
+  }\r
+\r
+  // Update rx_rd_ptr\r
+  WRITE_VALUE(RX_RD_PTR(s), rd_ptr.cVal[3]);\r
+  WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(1), rd_ptr.cVal[2]);\r
+  WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(2), rd_ptr.cVal[1]);\r
+  WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(3), rd_ptr.cVal[0]);\r
+\r
+  // RECV\r
+  WRITE_VALUE(COMMAND(s), CRECV);\r
+\r
+// Real received size return\r
+return(ret);\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*              Channel closing function.\r
+*\r
+* Description : Function for closing the connection of the designated channel.\r
+* Arguments   : s - channel number\r
+* Returns     : None\r
+* Note        : API Function\r
+****************************************************************************************************\r
+*/\r
+void close(SOCKET s)\r
+{\r
+u_int len;\r
+\r
+I_STATUS[s] = 0;\r
+\r
+if (select(s, SEL_CONTROL) == SOCK_CLOSED)\r
+  return;         // Already closed\r
+\r
+// When closing, if there's data which have not processed, Insert some source codes to handle this\r
+// Or before application call close(), handle those data first and call close() later.\r
+\r
+len = select(s, SEL_SEND);\r
+if (len == SSIZE[s])\r
+  {\r
+  // CLOSE\r
+  WRITE_VALUE(COMMAND(s), CCLOSE);\r
+  // TODO: The 'SCLOSED' status value is only set briefly as part of the close,\r
+  // and will otherwise quickly return to normal.  That means your code might\r
+  // become 'stuck' at this point even if the packet has closed normally.\r
+  // Rather than a while() call, it might be preferred to time out on this\r
+  // close check and return to the application after some time.\r
+  while(!(I_STATUS[s] & SCLOSED))\r
+         I2CHIP_POLL_ISR(in4_isr_i2chip);\r
+  }\r
+}\r
+\r
+u_char tx_empty(SOCKET s)\r
+{\r
+       return (select(s, SEL_SEND) == SSIZE[s]);\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*              Channel closing function.\r
+*\r
+* Description : Function for closing the connection of the designated channel.\r
+* Arguments   : s - channel number\r
+* Returns     : None\r
+* Note        : API Function\r
+****************************************************************************************************\r
+*/\r
+char reset_sock(SOCKET s)\r
+{\r
+u_char c;\r
+\r
+c = 1 << s;\r
+\r
+// RESET\r
+WRITE_VALUE(RESETSOCK, c);\r
+return (1);\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*             Function handling the channel socket information.\r
+*\r
+* Description : Return socket information of designated channel\r
+* Arguments   : s    - channel number\r
+*               func - SEL_CONTROL(0x00) -> return socket status\r
+*                      SEL_SEND(0x01)    -> return free transmit buffer size\r
+*                      SEL_RECV(0x02)    -> return received data size\r
+* Returns     : socket status or free transmit buffer size or received data size\r
+* Note        : API Function\r
+****************************************************************************************************\r
+*/\r
+u_int select(SOCKET s, u_char func)\r
+{\r
+u_int val;\r
+union un_l2cval rd_ptr, wr_ptr, ack_ptr;\r
+u_char k;\r
+\r
+switch (func)\r
+  {\r
+  // socket status information\r
+  case SEL_CONTROL :\r
+        val = READ_VALUE(SOCK_STATUS(s));\r
+        break;\r
+\r
+  // Calculate send free buffer size\r
+  case SEL_SEND :\r
+        disable();\r
+        k = READ_VALUE(SHADOW_TXWR_PTR(s));\r
+        WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.\r
+        delay0(2);\r
+        wr_ptr.cVal[3] = READ_VALUE(TX_WR_PTR(s));\r
+        wr_ptr.cVal[2] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(1));\r
+        wr_ptr.cVal[1] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(2));\r
+        wr_ptr.cVal[0] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(3));\r
+\r
+        if (( READ_VALUE(OPT_PROTOCOL(s)) & 0x07) == SOCK_STREAM)      // TCP\r
+               {\r
+               k = READ_VALUE(SHADOW_TXACK_PTR(s));\r
+               WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.\r
+               delay0(2);\r
+               ack_ptr.cVal[3] = READ_VALUE(TX_ACK_PTR(s));\r
+               ack_ptr.cVal[2] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(1));\r
+               ack_ptr.cVal[1] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(2));\r
+               ack_ptr.cVal[0] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(3));\r
+               enable();\r
+\r
+               if (wr_ptr.lVal >= ack_ptr.lVal)\r
+        val = (u_int)(SSIZE[s] - (wr_ptr.lVal - ack_ptr.lVal));\r
+               else\r
+        val = (u_int)(SSIZE[s] - (0 - ack_ptr.lVal + wr_ptr.lVal));\r
+               }\r
+        else                                                                                   // UDP, IP RAW ... (except TCP)\r
+               {\r
+               k = READ_VALUE(SHADOW_TXRD_PTR(s));\r
+               WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.\r
+               delay0(2);\r
+               rd_ptr.cVal[3] = READ_VALUE(TX_RD_PTR(s));\r
+               rd_ptr.cVal[2] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(1));\r
+               rd_ptr.cVal[1] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(2));\r
+               rd_ptr.cVal[0] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(3));\r
+               enable();\r
+\r
+               if (wr_ptr.lVal >= rd_ptr.lVal)\r
+        val = (u_int)(SSIZE[s] - (wr_ptr.lVal - rd_ptr.lVal));\r
+               else\r
+        val = (u_int)(SSIZE[s] - (0 - rd_ptr.lVal + wr_ptr.lVal));\r
+               }\r
+        break;\r
+\r
+  //  Calculate received data size\r
+  case SEL_RECV :\r
+        disable();\r
+        k = READ_VALUE(SHADOW_RXWR_PTR(s));\r
+        WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.\r
+        delay0(2);\r
+        wr_ptr.cVal[3] = READ_VALUE(RX_WR_PTR(s));\r
+        wr_ptr.cVal[2] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(1));\r
+        wr_ptr.cVal[1] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(2));\r
+        wr_ptr.cVal[0] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(3));\r
+\r
+        k = READ_VALUE(SHADOW_RXRD_PTR(s));\r
+    WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.\r
+        delay0(2);\r
+        rd_ptr.cVal[3] = READ_VALUE(RX_RD_PTR(s));\r
+        rd_ptr.cVal[2] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(1));\r
+        rd_ptr.cVal[1] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(2));\r
+        rd_ptr.cVal[0] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(3));\r
+        enable();\r
+\r
+        if (wr_ptr.lVal == rd_ptr.lVal)\r
+      val = 0;\r
+        else if (wr_ptr.lVal > rd_ptr.lVal)\r
+      val = (u_int)(wr_ptr.lVal - rd_ptr.lVal);\r
+        else\r
+      val = (u_int)(0 - rd_ptr.lVal + wr_ptr.lVal);\r
+        break;\r
+\r
+  default :\r
+        val = -1;\r
+        break;\r
+  }\r
+// Suppress compiler errors that k is not used\r
+k = k;\r
+return(val);\r
+}\r
+\r
+//\r
+//     unsigned char dma_read_i2chip (unsigned int i2_segm, unsigned int i2_offs,\r
+//     unsigned int cnt, unsigned int des_segm, unsigned int des_offs);\r
+//     Using DMA0 to read data from i2chip buffer into destination SRAM.\r
+//     where:\r
+//             unsigned int cnt = number of sectors, 512-byte per sector\r
+//             unsigned int des_segm = segment of destination SRAM data memory\r
+//             unsigned int des_offs = offset of destination SRAM data memory\r
+//             unsigned int i2_segm = segment of i2chip buffer mapped in memory\r
+//             unsigned int i2_offs = offset of i2chip buffer mapped in memory\r
+//      return DMA counter value\r
+//\r
+unsigned int dma_read_i2chip(u_char far* i2_src, u_char far* des, u_int cnt)\r
+{\r
+       u_int des_segm, des_offs;\r
+   u_int i2_segm, i2_offs;\r
+   u_long temp;\r
+\r
+   temp = ((long)FP_SEG(des) << 4) + ((long)FP_OFF(des));\r
+   des_segm = (u_int)(temp >> 16);\r
+   des_offs = (u_int)(temp & 0xffff);\r
+\r
+   temp = ((long)FP_SEG(i2_src) << 4) + ((long)FP_OFF(i2_src));\r
+   i2_segm = (u_int)(temp >> 16);\r
+   i2_offs = (u_int)(temp & 0xffff);\r
+\r
+       outport(0xffc6, des_segm);   /* D0DSTH destination SRAM segment */\r
+       outport(0xffc4, des_offs);   /* D0DSTL destination SRAM offset */\r
+       outport(0xffc2, i2_segm);   /* D0SRCH=SP0RD */\r
+       outport(0xffc0, i2_offs);   /* D0SRCL=SP0RD */\r
+       outport(0xffc8, cnt);   // D0TC counter\r
+       outport(0xfff8,0x0504); // PLLCON, 0203=10M,050f=40M, 051f=80MHz\r
+// DMA0 mem-mem, 16-bit, unsync, Start moving data line below\r
+       outport(0xffca, 0xb60e);   /* D0CON 1011 0110 0000 1111 */\r
+//     outport(0xffca, 0xb42e);         // 1011 0100 0010 1110\r
+       while( inport(0xffc8) ); /* D0TC counter=0, DMA complete */\r
+       outport(0xfff8,0x051f); // PLLCON, 0203=10M,050f=40M, 051f=80MHz\r
+return( inport(0xffc8) ); // counter\r
+}\r
+\r
+//\r
+//     unsigned int dma_write_i2chip (unsigned int src_segm, unsigned int src_offs,\r
+//     unsigned int cnt, unsigned int i2_segm, unsigned int i2_offs);\r
+//     Using DMA0 to write data from memory into i2chip.\r
+//     where:\r
+//             unsigned int cnt = number of 16-bit DMA transfers\r
+//             unsigned int src_segm = segment of the source SRAM data memory\r
+//             unsigned int src_offs = offset of the source SRAM data memory\r
+//             unsigned int i2_segm = segment of i2chip buffer mapped in memory\r
+//             unsigned int i2_offs = offset of i2chip buffer mapped in memory\r
+//      return DMA counter value\r
+//\r
+unsigned int dma_write_i2chip(u_char far* src, u_char far* i2_dest, u_int cnt)\r
+{\r
+       u_int src_segm, src_offs;\r
+   u_int i2_segm, i2_offs;\r
+   u_long temp;\r
+\r
+   temp = (FP_SEG(src) << 4) + (FP_OFF(src));\r
+   src_segm = (u_int)(temp >> 4);\r
+   src_offs = (u_int)(temp & 0xffff);\r
+\r
+   temp = (FP_SEG(i2_dest) << 4) + (FP_OFF(i2_dest));\r
+   i2_segm = (u_int)(temp >> 4);\r
+   i2_offs = (u_int)(temp & 0xffff);\r
+\r
+       outport(0xffc8, cnt);   // D0TC counter\r
+       outport(0xffc6, i2_segm); // D0DSTH=i2chip buffer segment\r
+       outport(0xffc4, i2_offs); // D0DSTL=i2chip buffer offset\r
+       outport(0xffc2, src_segm);   /* D0SRCH=SP0RD */\r
+       outport(0xffc0, src_offs);   /* D0SRCL=SP0RD */\r
+//     outport(0xfff8,0x050f); // PLLCON, 0203=10M,050f=40M, 051f=80MHz\r
+// DMA0 mem-mem, 16-bit, unsync, Start moving data line below\r
+       outport(0xffca, 0xb60f);   /* D0CON 1011 0110 0000 1111 */\r
+       while( inport(0xffc8) ); /* D0TC counter=0, DMA complete */\r
+//     outport(0xfff8,0x051f); // PLLCON, 0203=10M,050f=40M, 051f=80MHz\r
+\r
+return( inport(0xffc8) ); // counter\r
+}\r
+\r
+/*\r
+****************************************************************************************************\r
+*              Copies the receive buffer data of the W3100A to the system buffer.\r
+*\r
+* Description : Copies the receive buffer data of the W3100A to the system buffer.\r
+*    It is called from the recv()or recvfrom() function.\r
+* Arguments   : s   - channel number\r
+*               src - receive buffer pointer of W3100A\r
+*               dst - system buffer pointer\r
+*               len - data size to copy\r
+* Returns     : copied data size\r
+* Note        : Internal Function\r
+****************************************************************************************************\r
+*/\r
+u_int read_data(SOCKET s, u_int offset, u_char far * dst, u_int len)\r
+{\r
+       u_int i, size, size1;\r
+   u_char far* src = (u_char far*)(MK_FP_WINDOW(RECV_DATA_BUF,\r
+                                        RBUFBASEADDRESS[s] + offset));\r
+//   src = (u_char far*)(MK_FP_WINDOW(RECV_DATA_BUF,\r
+//                                        0));\r
+\r
+       if (len == 0)\r
+   {\r
+       WINDOW_RESTORE_BASE;    // Needed whenever we do a call to MK_FP_WINDOW.\r
+               return 0;\r
+   }\r
+\r
+   if ((offset + len) > RSIZE[s])\r
+   {\r
+               size = (u_int)(RSIZE[s] - offset);\r
+\r
+               if (size > TERN_RDMA_THRES)\r
+               {\r
+                       dma_read_i2chip(src, dst, size);\r
+               }\r
+               else\r
+      {\r
+                       for (i = 0; i < size; i++)\r
+               {\r
+                               *dst++ = READ_VALUE(src);\r
+            WINDOW_PTR_INC(src);\r
+\r
+                       }\r
+               }\r
+\r
+         size1 = len - size;\r
+     src = (u_char far *)(MK_FP_WINDOW(RECV_DATA_BUF, (RBUFBASEADDRESS[s])));\r
+\r
+     if (size1 > TERN_RDMA_THRES)\r
+     {\r
+               dma_read_i2chip(src, dst, size);\r
+         }\r
+     else\r
+         {\r
+                       for (i = 0; i < size1; i++)\r
+               {\r
+                               *dst++ = READ_VALUE(src);\r
+            WINDOW_PTR_INC(src);\r
+               }\r
+               }\r
+       }\r
+   else\r
+   {\r
+        if (len > TERN_RDMA_THRES)\r
+    {\r
+               dma_read_i2chip(src, dst, size);\r
+    }\r
+    else\r
+    {\r
+               for (i = 0; i < len; i++)\r
+       {\r
+                       *dst++ = READ_VALUE(src);\r
+         WINDOW_PTR_INC(src);\r
+               }\r
+    }\r
+   }\r
+   WINDOW_RESTORE_BASE;    // Needed whenever we do a call to MK_FP_WINDOW.\r
+       return len;\r
+}\r
+\r
+\r
+/*\r
+****************************************************************************************************\r
+*              Copies the system buffer data to the transmit buffer of the W3100A.\r
+*\r
+* Description : Copies the system buffer data to the transmit buffer of the W3100A.\r
+*               It is called from the send_in()or sendto_in() function.\r
+* Arguments   : s   - channel number\r
+*               src - system buffer pointer\r
+*               dst - send buffer pointer of W3100A\r
+*               len - data size to copy\r
+* Returns     : copied data size\r
+* Note        : Internal Function\r
+****************************************************************************************************\r
+*/\r
+u_int write_data(SOCKET s, u_char far * src, u_int offset, u_int len)\r
+{\r
+       u_int i, size, size1;\r
+       u_char far* dst = (u_char far*)MK_FP_WINDOW(SEND_DATA_BUF,\r
+                                  SBUFBASEADDRESS[s] + offset);\r
+\r
+       if (len == 0)\r
+   {\r
+       WINDOW_RESTORE_BASE;    // Needed whenever we do a call to MK_FP_WINDOW.\r
+               return 0;\r
+   }\r
+\r
+       if ((offset + len) > SSIZE[s])\r
+   {\r
+               size = (u_int)(SSIZE[s] - offset);\r
+\r
+               for (i = 0; i < size; i++)\r
+       {\r
+                       WRITE_VALUE(dst, *src++);\r
+         WINDOW_PTR_INC(dst);\r
+               }\r
+\r
+               size1 = len - size;\r
+               dst = (u_char far *)(MK_FP_WINDOW(SEND_DATA_BUF, (SBUFBASEADDRESS[s])));\r
+\r
+               for (i = 0; i < size1; i++)\r
+       {\r
+                       WRITE_VALUE(dst, *src++);\r
+         WINDOW_PTR_INC(dst);\r
+               }\r
+  }\r
+  else\r
+  {\r
+       for (i = 0; i < len; i++)\r
+       {\r
+                       WRITE_VALUE(dst, *src++);\r
+         WINDOW_PTR_INC(dst);\r
+               }\r
+       }\r
+   WINDOW_RESTORE_BASE;    // Needed whenever we do a call to MK_FP_WINDOW.\r
+       return len;\r
+}\r
+\r
+\r
+\r