From: richardbarry Date: Sat, 27 May 2006 13:55:53 +0000 (+0000) Subject: New Demo files for Tern E-Engine controller port. X-Git-Tag: V4.0.2~5 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=4ba06834483c4c480ac3f16e71d6f3073b9363e1;p=freertos New Demo files for Tern E-Engine controller port. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@7 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- diff --git a/Demo/WizNET_DEMO_TERN_186/186.cfg b/Demo/WizNET_DEMO_TERN_186/186.cfg new file mode 100644 index 000000000..f7e61706c --- /dev/null +++ b/Demo/WizNET_DEMO_TERN_186/186.cfg @@ -0,0 +1,145 @@ +// 186.cfg +// You must select RAM, ROM for your controller 04-26-2000 +// Your TERN controller is installed with SRAM and ROM with different sizes. +// For debug, 128K or 512K SRAM can be selected +// For build a ROM, you need to select the ROM size. +// How to select ? +// 1) commend out the unwanted #define RAM size line with "//" +// 2) delete the "//" preceding the wanted #define RAM size line +// + +// #define RAM 32 // 32KB SRAM installed +#define RAM 128 // 128KB SRAM installed +// #define RAM 512 // 512KB SRAM installed + +// #define ROM 32 // Use 32KB ROM chip 27C256-70 +#define ROM 64 // Use 64KB ROM chip 27C512-70 +// #define ROM 128 // Use 128KB ROM chip 27C010-70 +// #define ROM 256 // Use 256KB ROM chip 27C020-70 +// #define ROM 512 // Use 512KB ROM chip 27C040-70, Change Jumper on board + + +cputype Am186ES // AMD188/6 based controllers + +#if defined(__PDREMOTE__) + +#if RAM == 32 +map 0x00000 to 0x00fff as reserved // interrupt vector table +map 0x01000 to 0x03fff as rdwr // System RAM area (60KB RAM) +map 0x04000 to 0x07fff as rdonly // Simulated EPROM area (64KB RAM) +map 0x08000 to 0xfffff as reserved // No access allowed +#define CODE_START 0x0400 // Start of application code, STEP2 ! + +#elif RAM == 128 +map 0x00000 to 0x00fff as reserved // interrupt vector table +map 0x01000 to 0x07fff as rdwr // System RAM area (60KB RAM) +map 0x08000 to 0x1ffff as rdonly // Simulated EPROM area (64KB RAM) +map 0x20000 to 0xfffff as reserved // No access allowed +#define CODE_START 0x0800 // Start of application code + +#elif RAM == 512 +map 0x00000 to 0x00fff as reserved // interrupt vector table +map 0x01000 to 0x07fff as rdwr // System RAM area (60KB RAM) +map 0x08000 to 0x7ffff as rdonly // Simulated EPROM area(480KB RAM) +map 0x80000 to 0xfffff as reserved // No access allowed +#define CODE_START 0x0800 // Start of application code +#endif + +#define DATA_START 0x0100 // Start of application data +#define BOOT_START 0x1fc0 // Start of initialization code + +#else +#if ROM == 32 +map 0x00000 to 0x1ffff as rdwr // 128KB RAM address space +map 0x20000 to 0xf7fff as reserved // No access +map 0xF8000 to 0xfffff as rdonly // 32KB EPROM address space +#define CODE_START 0xF800 // Start of application code +#elif ROM == 64 +map 0x00000 to 0x1ffff as rdwr // 128KB RAM address space +map 0x20000 to 0xEffff as reserved // No access +map 0xF0000 to 0xfffff as rdonly // 64KB EPROM address space +#define CODE_START 0xF000 // Start of application code +#elif ROM == 128 +map 0x00000 to 0x1ffff as rdwr // 128KB RAM address space +map 0x20000 to 0xDffff as reserved // No access +map 0xE0000 to 0xfffff as rdonly // 128KB EPROM address space +#define CODE_START 0xE000 // Start of application code +#elif ROM == 256 +map 0x00000 to 0x1ffff as rdwr // 128KB RAM address space +map 0x20000 to 0xBffff as reserved // No access +map 0xC0000 to 0xfffff as rdonly // 256KB EPROM address space +#define CODE_START 0xC000 // Start of application code +#elif ROM == 512 +map 0x00000 to 0x1ffff as rdwr // 128KB RAM address space +map 0x20000 to 0x7ffff as reserved // No access +map 0x80000 to 0xfffff as rdonly // 512KB EPROM address space +#define CODE_START 0x8000 // Start of application code +#endif + +#define DATA_START 0x0040 // Start of application data +#define BOOT_START 0xffc0 // Start of initialization code + +initcode reset \ // Reset vector to program entry point + umcs = 0x80bf \ // 512K ROM, 3 wait states + lmcs = 0x7fbf \ // 512K RAM, 3 wait states + mpcs = 0xa0bf \ + mmcs = 0x81ff \ + pacs = 0x007f + +class ??LOCATE = BOOT_START // Chip select initialization +output ??LOCATE + +#if ROM == 32 // 27C256-90 EPROM or FLASH +hexfile binary offset=0xf8000 size=32 // for 27C256, bin file +#elif ROM == 64 // 27C512-90 EPROM or FLASH +hexfile binary offset=0xF0000 size=64 // for 27C512 +#elif ROM == 128 // 27C010-90 EPROM or FLASH +hexfile binary offset=0xE0000 size=128 // for 27C010 +#elif ROM == 256 // 27C020-90 EPROM or FLASH +hexfile binary offset=0xC0000 size=256 // for 27C020 +#elif ROM == 512 // 27C040-90 EPROM or FLASH +hexfile Intel86 offset=0x80000 size=512 // for 27C040, output .HEX file +#endif + +#endif + + +// +// Start of common configuration file settings. +// + +absfile axe86 // Paradigm C++ debugging output +listfile segments // Absolute segment map + +dup DATA ROMDATA // Make a copy of initialized data +dup FAR_DATA ROMFARDATA // Make a copy of far initialized data + +#if defined(__COMPFARDATA__) // Compress and display results +compress ROMFARDATA +display compression +#endif + +class CODE = CODE_START // Application code +class DATA = DATA_START // Application data + +order DATA \ // RAM class organization + BSS \ + NVRAM \ + EDATA \ + STACK \ + FAR_DATA ENDFAR_DATA \ + FAR_BSS ENDFAR_BSS \ + FAR_HEAP ENDFAR_HEAP + +order CODE \ // EPROM class organization + INITDATA EXITDATA \ + FAR_CONST ENDFAR_CONST \ + ROMDATA ENDROMDATA \ + ROMFARDATA ENDROMFARDATA + +output CODE \ // Classes in the output file(s) + INITDATA EXITDATA \ + FAR_CONST ENDFAR_CONST \ + ROMDATA ENDROMDATA \ + ROMFARDATA ENDROMFARDATA + \ No newline at end of file diff --git a/Demo/WizNET_DEMO_TERN_186/AE.LIB b/Demo/WizNET_DEMO_TERN_186/AE.LIB new file mode 100644 index 000000000..dcfffa152 Binary files /dev/null and b/Demo/WizNET_DEMO_TERN_186/AE.LIB differ diff --git a/Demo/WizNET_DEMO_TERN_186/FreeRTOSConfig.h b/Demo/WizNET_DEMO_TERN_186/FreeRTOSConfig.h new file mode 100644 index 000000000..2a1e99c35 --- /dev/null +++ b/Demo/WizNET_DEMO_TERN_186/FreeRTOSConfig.h @@ -0,0 +1,77 @@ +/* + FreeRTOS V4.0.1 - Copyright (C) 2003-2006 Richard Barry. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + FreeRTOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with FreeRTOS; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + A special exception to the GPL can be applied should you wish to distribute + a combined work that includes FreeRTOS, without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details of how and when the exception + can be applied. + + *************************************************************************** + See http://www.FreeRTOS.org for documentation, latest information, license + and contact details. Please ensure to read the configuration and relevant + port sections of the online documentation. + *************************************************************************** +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 80000000 ) +#define configTICK_RATE_HZ ( ( portTickType ) 1000 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 256 ) /* This can be made smaller if required. */ +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 20 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 16 ) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 + + + + +#endif /* FREERTOS_CONFIG_H */ diff --git a/Demo/WizNET_DEMO_TERN_186/HTTPTask.c b/Demo/WizNET_DEMO_TERN_186/HTTPTask.c new file mode 100644 index 000000000..c3384d430 --- /dev/null +++ b/Demo/WizNET_DEMO_TERN_186/HTTPTask.c @@ -0,0 +1,289 @@ +/* + FreeRTOS V4.0.1 - Copyright (C) 2003-2006 Richard Barry. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + FreeRTOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with FreeRTOS; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + A special exception to the GPL can be applied should you wish to distribute + a combined work that includes FreeRTOS, without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details of how and when the exception + can be applied. + + *************************************************************************** + See http://www.FreeRTOS.org for documentation, latest information, license + and contact details. Please ensure to read the configuration and relevant + port sections of the online documentation. + *************************************************************************** +*/ + +/* + * Very simple task that responds with a single WEB page to http requests. + * + * The WEB page displays task and system status. A semaphore is used to + * wake the task when there is processing to perform as determined by the + * interrupts generated by the Ethernet interface. + */ + +/* Standard includes. */ +#include +#include + +/* Tern includes. */ +#include "utils\system_common.h" +#include "i2chip_hw.h" +#include "socket.h" + +/* FreeRTOS.org includes. */ +#include +#include +#include + +/* The standard http port on which we are going to listen. */ +#define httpPORT 80 + +#define httpTX_WAIT 2 + +/* Network address configuration. */ +const unsigned portCHAR ucMacAddress[] = { 12, 128, 12, 34, 56, 78 }; +const unsigned portCHAR ucGatewayAddress[] = { 192, 168, 2, 1 }; +const unsigned portCHAR ucIPAddress[] = { 172, 25, 218, 210 }; +const unsigned portCHAR ucSubnetMask[] = { 255, 255, 255, 0 }; + +/* The number of sockets this task is going to handle. */ +#define httpSOCKET_NUM 3 +unsigned portCHAR ucConnection[ httpSOCKET_NUM ]; + +/* The maximum data buffer size we can handle. */ +#define httpSOCKET_BUFFER_SIZE 2048 + +/* Standard HTTP response. */ +#define httpOUTPUT_OK "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" + +/* Hard coded HTML components. Other data is generated dynamically. */ +#define HTML_OUTPUT_BEGIN "\ +\ +

FreeRTOS.orgtm + Tern E-Enginetm

\ +FreeRTOS.org Homepage

\ +


Task status table:\r\n\ +

Task          State  Priority  Stack	#
\ +************************************************
" + +#define HTML_OUTPUT_END "\ +
" + +/*-----------------------------------------------------------*/ + +/* + * Initialise the data structures used to hold the socket status. + */ +static void prvHTTPInit( void ); + +/* + * Setup the Ethernet interface with the network addressing information. + */ +static void prvNetifInit( void ); + +/* + * Generate the dynamic components of the served WEB page and transmit the + * entire page through the socket. + */ +static void prvTransmitHTTP( unsigned portCHAR socket ); +/*-----------------------------------------------------------*/ + +/* This variable is simply incremented by the idle task hook so the number of +iterations the idle task has performed can be displayed as part of the served +page. */ +unsigned portLONG ulIdleLoops = 0UL; + +/* Data buffer shared by sockets. */ +unsigned portCHAR ucSocketBuffer[ httpSOCKET_BUFFER_SIZE ]; + +/* The semaphore used by the Ethernet ISR to signal that the task should wake +and process whatever caused the interrupt. */ +xSemaphoreHandle xTCPSemaphore = NULL; + +/*-----------------------------------------------------------*/ +void vHTTPTask( void * pvParameters ) +{ +portSHORT i, sLen; +unsigned portCHAR ucState; + + ( void ) pvParameters; + + /* Create the semaphore used to communicate between this task and the + WIZnet ISR. */ + vSemaphoreCreateBinary( xTCPSemaphore ); + + /* Make sure everything is setup before we start. */ + prvNetifInit(); + prvHTTPInit(); + + for( ;; ) + { + /* Wait until the ISR tells us there is something to do. */ + xSemaphoreTake( xTCPSemaphore, portMAX_DELAY ); + + /* Check each socket. */ + for( i = 0; i < httpSOCKET_NUM; i++ ) + { + ucState = select( i, SEL_CONTROL ); + + switch (ucState) + { + case SOCK_ESTABLISHED : /* new connection established. */ + + if( ( sLen = select( i, SEL_RECV ) ) > 0 ) + { + if( sLen > httpSOCKET_BUFFER_SIZE ) + { + sLen = httpSOCKET_BUFFER_SIZE; + } + + disable(); + + sLen = recv( i, ucSocketBuffer, sLen ); + + if( ucConnection[ i ] == 1 ) + { + /* This is our first time processing a HTTP + request on this connection. */ + prvTransmitHTTP( i ); + ucConnection[i] = 0; + } + enable(); + } + break; + + case SOCK_CLOSE_WAIT : + + close(i); + break; + + case SOCK_CLOSED : + + ucConnection[i] = 1; + socket( i, SOCK_STREAM, 80, 0x00 ); + NBlisten( i ); /* reinitialize socket. */ + break; + } + } + } +} +/*-----------------------------------------------------------*/ + +static void prvHTTPInit( void ) +{ +unsigned portCHAR ucIndex; + + /* There are 4 total sockets available; we will claim 3 for HTTP. */ + for(ucIndex = 0; ucIndex < httpSOCKET_NUM; ucIndex++) + { + socket( ucIndex, SOCK_STREAM, httpPORT, 0x00 ); + NBlisten( ucIndex ); + ucConnection[ ucIndex ] = 1; + } +} +/*-----------------------------------------------------------*/ + +static void prvNetifInit( void ) +{ + i2chip_init(); + initW3100A(); + + setMACAddr( ( unsigned portCHAR * ) ucMacAddress ); + setgateway( ( unsigned portCHAR * ) ucGatewayAddress ); + setsubmask( ( unsigned portCHAR * ) ucSubnetMask ); + setIP( ( unsigned portCHAR * ) ucIPAddress ); + + /* See definition of 'sysinit' in socket.c + - 8 KB transmit buffer, and 8 KB receive buffer available. These buffers + are shared by all 4 channels. + - (0x55, 0x55) configures the send and receive buffers at + httpSOCKET_BUFFER_SIZE bytes for each of the 4 channels. */ + sysinit( 0x55, 0x55 ); +} +/*-----------------------------------------------------------*/ + +static void prvTransmitHTTP(unsigned portCHAR socket) +{ +extern portSHORT usCheckStatus; + + /* Send the http and html headers. */ + send( socket, ( unsigned portCHAR * ) httpOUTPUT_OK, strlen( httpOUTPUT_OK ) ); + send( socket, ( unsigned portCHAR * ) HTML_OUTPUT_BEGIN, strlen( HTML_OUTPUT_BEGIN ) ); + + /* Generate then send the table showing the status of each task. */ + vTaskList( ucSocketBuffer ); + send( socket, ( unsigned portCHAR * ) ucSocketBuffer, strlen( ucSocketBuffer ) ); + + /* Send the number of times the idle task has looped. */ + sprintf( ucSocketBuffer, "


The idle task has looped 0x%08lx times
", ulIdleLoops ); + send( socket, ( unsigned portCHAR * ) ucSocketBuffer, strlen( ucSocketBuffer ) ); + + /* Send the tick count. */ + sprintf( ucSocketBuffer, "The tick count is 0x%08lx
", xTaskGetTickCount() ); + send( socket, ( unsigned portCHAR * ) ucSocketBuffer, strlen( ucSocketBuffer ) ); + + /* Show a message indicating whether or not the check task has discovered + an error in any of the standard demo tasks. */ + if( usCheckStatus == 0 ) + { + sprintf( ucSocketBuffer, "No errors detected." ); + send( socket, ( unsigned portCHAR * ) ucSocketBuffer, strlen( ucSocketBuffer ) ); + } + else + { + sprintf( ucSocketBuffer, "An error has been detected in at least one task %x.

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