--- /dev/null
+// 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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+#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
--- /dev/null
+/*\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
--- /dev/null
+#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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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