+++ /dev/null
-/*\r
-********************************************************************************\r
-* TERN, Inc.\r
-* (c) Copyright 2005, http://www.tern.com\r
-*\r
-* MODIFIED BY RICHARD BARRY TO ADD SEMAPHORE FOR COMMUNICATION BETWEEN THE \r
-* WIZnet ISR AND THE HTTP TASK.\r
-*\r
-* - Derived based on development version provided by Wiznet.\r
-*\r
-* Filename : socket.h\r
-* Programmer(s):\r
-* Created : 2002/06/20\r
-* Modified :\r
-* 2002/09/27 : - Renaming\r
-* INT_STATUS --> INT_REG\r
-* STATUS(i) --> INT_STATUS(i)\r
-* C_STATUS(i) --> SOCK_STATUS(i)\r
-* 2003/11/06 : Ported for use with TERN controller. Note all byte access is at even addresses\r
-* 2005/10/8 : Modified constants for easier initialization.\r
-*\r
-* Description : Header file of W3100A for TERN embedded controller\r
-********************************************************************************\r
-*/\r
-/*\r
-###############################################################################\r
-File Include Section\r
-###############################################################################\r
-*/\r
-#include "i2chip_hw.h" \r
-#include "socket.h"\r
-#include "types.h"\r
-#include <string.h>\r
-#include <stdio.h>\r
-\r
-#include <FreeRTOS.h>\r
-#include <semphr.h>\r
-#include <portasm.h>\r
-\r
-\r
-/*\r
-###############################################################################\r
-Local Variable Declaration Section\r
-###############################################################################\r
-*/\r
-u_char I_STATUS[4]; // Store Interrupt Status according to channels\r
-u_int Local_Port; // Designate Local Port\r
-union un_l2cval SEQ_NUM; // Set initial sequence number\r
-\r
-u_long SMASK[MAX_SOCK_NUM]; // Variable to store MASK of Tx in each channel,\r
- // on setting dynamic memory size.\r
-u_long RMASK[MAX_SOCK_NUM]; // Variable to store MASK of Rx in each channel,\r
- // on setting dynamic memory size.\r
-int SSIZE[MAX_SOCK_NUM]; // Maximun Tx memory size by each channel\r
-int RSIZE[MAX_SOCK_NUM]; // Maximun Rx memory size by each channel\r
-\r
-u_int SBUFBASEADDRESS[MAX_SOCK_NUM]; // Maximun Tx memory base address by each channel\r
-u_int RBUFBASEADDRESS[MAX_SOCK_NUM]; // Maximun Rx memory base address by each channel\r
-\r
-/*\r
-###############################################################################\r
-Function Implementation Section\r
-###############################################################################\r
-*/\r
-\r
-/*\r
-********************************************************************************\r
-* Interrupt handling function of the W3100A\r
-*\r
-* Description :\r
-* Stores the status information that each function waits for in the global variable I_STATUS\r
-* for transfer. I_STATUS stores the interrupt status value for each channel.\r
-* Arguments : None\r
-* Returns : None\r
-* Note : Internal Function\r
-********************************************************************************\r
-*/\r
-\r
-portBASE_TYPE prvProcessISR( void )\r
-{\r
-unsigned char status;\r
-extern xSemaphoreHandle xTCPSemaphore;\r
-portBASE_TYPE xSwitchRequired = pdFALSE;\r
-\r
-#ifdef I2CHIP_WINDOW\r
-u_int current_window = i2chip_get_window();\r
-#endif\r
-\r
-status = READ_VALUE(INT_REG);\r
-\r
-\r
-if (status)\r
- {\r
- xSwitchRequired = pdTRUE;\r
- // channel 0 interrupt(sysinit, sockinit, established, closed, timeout, send_ok, recv_ok)\r
- if (status & 0x01)\r
- {\r
- I_STATUS[0] = READ_VALUE(INT_STATUS(0));\r
-\r
-// if (I_STATUS[0] & SESTABLISHED)\r
-// ISR_ESTABLISHED(0);\r
-// if (I_STATUS[0] & SCLOSED)\r
-// ISR_CLOSED(0);\r
-\r
- WRITE_VALUE(INT_REG, 0x01);\r
- }\r
-\r
- // channel 1 interrupt(sysinit, sockinit, established, closed, timeout, send_ok, recv_ok)\r
- if (status & 0x02)\r
- {\r
- I_STATUS[1] = READ_VALUE(INT_STATUS(1));\r
-\r
-// if (I_STATUS[1] & SESTABLISHED)\r
-// ISR_ESTABLISHED(1);\r
-// if (I_STATUS[1] & SCLOSED)\r
-// ISR_CLOSED(1);\r
-\r
- WRITE_VALUE(INT_REG, 0x02);\r
- }\r
-\r
- // channel 2 interrupt(sysinit, sockinit, established, closed, timeout, send_ok, recv_ok)\r
- if (status & 0x04)\r
- {\r
- I_STATUS[2] = READ_VALUE(INT_STATUS(2));\r
-\r
-// if (I_STATUS[2] & SESTABLISHED)\r
-// ISR_ESTABLISHED(2);\r
-// if (I_STATUS[2] & SCLOSED)\r
-// ISR_CLOSED(2);\r
-\r
- WRITE_VALUE(INT_REG, 0x04);\r
- }\r
-\r
- // channel 3 interrupt(sysinit, sockinit, established, closed, timeout, send_ok, recv_ok)\r
- if (status & 0x08)\r
- {\r
- I_STATUS[3] = READ_VALUE(INT_STATUS(3));\r
-\r
-// if (I_STATUS[3] & SESTABLISHED) ISR_ESTABLISHED(3);\r
-// if (I_STATUS[3] & SCLOSED) ISR_CLOSED(3);\r
-\r
- WRITE_VALUE(INT_REG, 0x08);\r
- }\r
-\r
- // channel 0 receive interrupt\r
- if (status & 0x10)\r
- {\r
-// ISR_RX(0);\r
- WRITE_VALUE(INT_REG, 0x10);\r
- }\r
-\r
- // channel 1 receive interrupt\r
- if (status & 0x20)\r
- {\r
-// ISR_RX(1);\r
- WRITE_VALUE(INT_REG, 0x20);\r
- }\r
-\r
- // channel 2 receive interrupt\r
- if (status & 0x40)\r
- {\r
-// ISR_RX(2);\r
- WRITE_VALUE(INT_REG, 0x40);\r
- }\r
-\r
- // channel 3 receive interrupt\r
- if (status & 0x80)\r
- {\r
-// ISR_RX(3);\r
- WRITE_VALUE(INT_REG, 0x80);\r
- }\r
- status = READ_VALUE(INT_REG);\r
- }\r
-\r
-WRITE_VALUE(INT_REG, 0xFF);\r
-\r
-#ifdef I2CHIP_WINDOW\r
-i2chip_set_window(current_window);\r
-#endif\r
-\r
- if( xSwitchRequired == pdTRUE )\r
- {\r
- xSwitchRequired = xSemaphoreGiveFromISR( xTCPSemaphore, pdFALSE );\r
- }\r
-\r
- return xSwitchRequired;\r
-}\r
-\r
-void far interrupt in4_isr_i2chip(void)\r
-{\r
- if( prvProcessISR() == pdTRUE )\r
- {\r
- portEND_SWITCHING_ISR();\r
- }\r
-\r
- INT_EOI;\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* Established connection interrupt handling function.\r
-*\r
-* Description :\r
-* Called upon connection establishment, and may be inserted in user code if needed by\r
-* the programmer.\r
-* Arguments : None\r
-* Returns : None\r
-* Note : Internal Function\r
-****************************************************************************************************\r
-*/\r
-/*\r
-void ISR_ESTABLISHED(SOCKET s)\r
-{\r
-// TO ADD YOUR CODE\r
-}\r
-*/\r
-\r
-/*\r
-****************************************************************************************************\r
-* Closed connection interrupt handling function\r
-*\r
-* Description :\r
-* Called upon connection closure, and may be inserted in user code if needed by the programmer.\r
-* Arguments : None\r
-* Returns : None\r
-* Note : Internal Function\r
-****************************************************************************************************\r
-*/\r
-/*\r
-void ISR_CLOSED(SOCKET s)\r
-{\r
-// TO ADD YOUR CODE\r
-}\r
-*/\r
-\r
-/*\r
-****************************************************************************************************\r
-* Received data interrupt handling function\r
-*\r
-* Description :\r
-* Called upon receiving data, and may be inserted in user code if needed by the programmer.\r
-* Arguments : None\r
-* Returns : None\r
-* Note : Internal Function\r
-****************************************************************************************************\r
-*/\r
-/*\r
-void ISR_RX(SOCKET s)\r
-{\r
-// TO ADD YOUR CODE\r
-}\r
-*/\r
-\r
-/*\r
-****************************************************************************************************\r
-* W3100A Initialization Function\r
-*\r
-* Description: Reset of W3100A S/W and Registeration of i386 interrupt\r
-* Arguments : None.\r
-* Returns : None.\r
-* Note :\r
-****************************************************************************************************\r
-*/\r
-void initW3100A(void)\r
-{\r
-\r
-// Install interrupt handler for i2Chip\r
-INT_INIT(in4_isr_i2chip);\r
-\r
-\r
-Local_Port = 1000; // This default value will be set if you didn't designate it when you\r
- // create a socket. If you don't designate port number and create a\r
- // socket continuously, the port number will be assigned with\r
- // incremented by one to Local_Port\r
-SEQ_NUM.lVal = 4294967293ul; // Sets the initial SEQ# to be used for TCP communication.\r
- // (It should be ramdom value)\r
-WRITE_VALUE(COMMAND(0), CSW_RESET); // Software RESET\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* W3100A initialization function\r
-*\r
-* Description :\r
-* Sets the Tx, Rx memory size by each channel, source MAC, source IP, gateway, and subnet mask\r
-* to be used by the W3100A to the designated values.\r
-* May be called when reflecting modified network information or Tx, Rx memory size on the W3100A\r
-* Include Ping Request for ARP update (In case that a device embedding W3100A is directly\r
-* connected to Router)\r
-* Arguments : sbufsize - Tx memory size (00 - 1KByte, 01- 2KBtye, 10 - 4KByte, 11 - 8KByte)\r
-* bit 1-0 : Tx memory size of channel #0\r
-* bit 3-2 : Tx memory size of channel #1\r
-* bit 5-4 : Tx memory size of channel #2\r
-* bit 7-6 : Tx memory size of channel #3\r
-* rbufsize - Rx memory size (00 - 1KByte, 01- 2KBtye, 10 - 4KByte, 11 - 8KByte)\r
-* bit 1-0 : Rx memory size of channel #0\r
-* bit 3-2 : Rx memory size of channel #1\r
-* bit 5-4 : Rx memory size of channel #2\r
-* bit 7-6 : Rx memory size of channel #3\r
-* Returns : None\r
-* Note : API Function\r
-* Maximum memory size for Tx, Rx in W3100A is 8KBytes,\r
-* In the range of 8KBytes, the memory size could be allocated dynamically by\r
-* each channel\r
-* Be attentive to sum of memory size shouldn't exceed 8Kbytes\r
-* and to data transmission and receiption from non-allocated channel may cause\r
-* some problems.\r
-* If 8KBytes memory already is assigned to centain channel, other 3 channels\r
-* couldn't be used, for there's no available memory.\r
-* If two 4KBytes memory are assigned to two each channels, other 2 channels couldn't\r
-* be used, for there's no available memory.\r
-* (Example of memory assignment)\r
-* sbufsize => 00000011, rbufsize => 00000011 :\r
-* Assign 8KBytes for Tx and Rx to channel #0, Cannot use channel #1,#2,#3\r
-* sbufsize => 00001010, rbufsize => 00001010 :\r
-* Assign 4KBytes for Tx and Rx to each channel #0,#1 respectively. Cannot use\r
-* channel #2,#3\r
-* sbufsize => 01010101, rbufsize => 01010101 :\r
-* Assign 2KBytes for Tx and Rx to each all channels respectively.\r
-* sbufsize => 00010110, rbufsize => 01010101 :\r
-* Assign 4KBytes for Tx, 2KBytes for Rx to channel #0\r
-* s 2KBytes for Tx, 2KBytes for Rx to channel #1\r
-* 2KBytes for Tx, 2KBytes for Rx to channel #2\r
-* 2KBytes is available exclusively for Rx in channel #3. There's no memory for Tx.\r
-****************************************************************************************************\r
-*/\r
-void sysinit(u_char sbufsize, u_char rbufsize)\r
-{\r
-char i;\r
-int ssum,rsum;\r
-\r
-ssum = 0;\r
-rsum = 0;\r
-\r
-// Set Tx memory size for each channel\r
-WRITE_VALUE(TX_DMEM_SIZE, sbufsize);\r
-\r
-// Set Rx memory size for each channel\r
-WRITE_VALUE(RX_DMEM_SIZE, rbufsize);\r
-\r
-// Set Base Address of Tx memory for channel #0\r
-SBUFBASEADDRESS[0] = 0;\r
-\r
-// Set Base Address of Rx memory for channel #0\r
-RBUFBASEADDRESS[0] = 0;\r
-\r
-// Set maximum memory size for Tx and Rx, mask, base address of memory by each channel\r
-for(i = 0 ; i < MAX_SOCK_NUM; i++)\r
- {\r
- SSIZE[i] = 0;\r
- RSIZE[i] = 0;\r
- if(ssum < 8192)\r
- {\r
- switch((sbufsize >> i*2) & 0x03) // Set maximum Tx memory size\r
- {\r
- case 0:\r
- SSIZE[i] = 1024;\r
- SMASK[i] = 0x000003FF;\r
- break;\r
-\r
- case 1:\r
- SSIZE[i] = 2048;\r
- SMASK[i] = 0x000007FF;\r
- break;\r
-\r
- case 2:\r
- SSIZE[i] = 4096;\r
- SMASK[i] = 0x00000FFF;\r
- break;\r
-\r
- case 3:\r
- SSIZE[i] = 8192;\r
- SMASK[i] = 0x00001FFF;\r
- break;\r
- }\r
- }\r
- if(rsum < 8192)\r
- {\r
- switch((rbufsize >> i*2) & 0x03) // Set maximum Rx memory size\r
- {\r
- case 0:\r
- RSIZE[i] = 1024;\r
- RMASK[i] = 0x000003FF;\r
- break;\r
-\r
- case 1:\r
- RSIZE[i] = 2048;\r
- RMASK[i] = 0x000007FF;\r
- break;\r
-\r
- case 2:\r
- RSIZE[i] = 4096;\r
- RMASK[i] = 0x00000FFF;\r
- break;\r
-\r
- case 3:\r
- RSIZE[i] = 8192;\r
- RMASK[i] = 0x00001FFF;\r
- break;\r
- }\r
- }\r
- ssum += SSIZE[i];\r
- rsum += RSIZE[i];\r
-\r
- // Set base address of Tx and Rx memory for channel #1,#2,#3\r
- if(i != 0)\r
- {\r
- SBUFBASEADDRESS[i] = ssum - SSIZE[i];\r
- RBUFBASEADDRESS[i] = rsum - RSIZE[i];\r
- }\r
- }\r
-\r
- WRITE_VALUE(COMMAND(0), CSYS_INIT);\r
-\r
-while(!(I_STATUS[0] & SSYS_INIT_OK))\r
- I2CHIP_POLL_ISR(in4_isr_i2chip);\r
-\r
-#ifdef __PING__\r
- {\r
- u_char xdata pingbuf[8];\r
- setIPprotocol(0, IPPROTO_ICMP);\r
- socket(0, SOCK_IPL_RAW, 3000,0); // Create a socket for ARP update\r
-\r
- pingbuf[0] = 8; // ICMP TYPE\r
- pingbuf[1] = 0; // ICMP CODE\r
- pingbuf[2] = 0xf7; // CHECKSUM (already calculated)\r
- pingbuf[3] = 0xfd;\r
- pingbuf[4] = 0; // ID\r
- pingbuf[5] = 1;\r
- pingbuf[6] = 0; // SEQ #\r
- pingbuf[7] = 1;\r
- pingbuf[8] = 0; // Data 1 Byte\r
-\r
- sendto(0, pingbuf, 9, GATEWAY_PTR,3000); // Ping Request\r
- close(0);\r
- printf("Route MAC Update Success");\r
- }\r
-#endif\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* Function to set subnet mask\r
-*\r
-* Description:\r
-* Arguments : addr--> Pointer that has the value to be set\r
-* Returns : None.\r
-* Note :\r
-****************************************************************************************************\r
-*/\r
-void setsubmask(u_char * addr)\r
-{\r
-u_char i;\r
-u_char far* sm_ptr = SUBNET_MASK_PTR; // We can only convert to 'regular'\r
- // pointer if we're confident arithmetic\r
- // won't take us out of current window.\r
-\r
-for (i = 0; i < 4; i++)\r
- {\r
- WRITE_VALUE(sm_ptr + SA_OFFSET(i), addr[i]);\r
- }\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* Function to set gateway IP\r
-*\r
-* Description:\r
-* Arguments : addr--> Pointer that has Gateway IP to be set\r
-* Returns : None.\r
-* Note :\r
-****************************************************************************************************\r
-*/\r
-void setgateway(u_char * addr)\r
-{\r
-u_char i;\r
-u_char far* gw_ptr = GATEWAY_PTR; // We can only convert to 'regular'\r
- // pointer if we're confident arithmetic\r
- // won't take us out of current window.\r
-for (i = 0; i < 4; i++)\r
- {\r
- WRITE_VALUE(gw_ptr + SA_OFFSET(i), addr[i]);\r
- }\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* Function to set W3100A IP\r
-*\r
-* Description:\r
-* Arguments : addr--> Pointer that has Source IP to be set\r
-* Returns : None.\r
-* Note :\r
-****************************************************************************************************\r
-*/\r
-void setIP(u_char * addr)\r
-{\r
-u_char i;\r
-u_char far* src_ptr = SRC_IP_PTR; // We can only convert to 'regular'\r
- // pointer if we're confident arithmetic\r
- // won't take us out of current window.\r
-\r
-for (i = 0; i < 4; i++)\r
- {\r
- WRITE_VALUE(src_ptr + SA_OFFSET(i), addr[i]);\r
- }\r
-}\r
-\r
-// DEBUG\r
-void getIP(u_char* addr)\r
-{\r
-u_char i;\r
-u_char far* src_ptr = SRC_IP_PTR; // We can only convert to 'regular'\r
- // pointer if we're confident arithmetic\r
- // won't take us out of current window.\r
-\r
-for (i = 0; i < 4; i++)\r
- addr[i] = READ_VALUE(src_ptr + SA_OFFSET(i));\r
-}\r
-\r
-\r
-/*\r
-****************************************************************************************************\r
-* Function to set MAC\r
-*\r
-* Description:\r
-* Arguments : addr--> Pointer that has MAC to be set\r
-* Returns : None.\r
-* Note :\r
-****************************************************************************************************\r
-*/\r
-void setMACAddr(u_char * addr)\r
-{\r
-u_char i;\r
-u_char far* ha_ptr = SRC_HA_PTR; // We can only convert to 'regular'\r
- // pointer if we're confident arithmetic\r
- // won't take us out of current window.\r
-\r
-for (i = 0; i < 6; i++)\r
- {\r
- WRITE_VALUE(ha_ptr + SA_OFFSET(i), addr[i]);\r
- }\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* Function to set TCP timeout\r
-*\r
-* Description: The function that used to adjust time to resend TCP\r
-* Arguments : val --> Pointer that has the value to be set\r
-* Upper 2 byte:Initial timeout value\r
-* Last 1 byte:The count to retry till timeout\r
-* Returns : None.\r
-* Note :\r
-****************************************************************************************************\r
-*/\r
-void settimeout(u_char * val)\r
-{\r
-u_char i;\r
-u_char far* tout_ptr = TIMEOUT_PTR; // We can only convert to 'regular'\r
- // pointer if we're confident arithmetic\r
- // won't take us out of current window.\r
-\r
-for (i = 0; i < 3; i++)\r
- {\r
- WRITE_VALUE(tout_ptr + SA_OFFSET(i), val[i]);\r
- }\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* Function to set interrupt mask.\r
-*\r
-* Description:\r
-* Arguments : mask--> Mask value to be set ('1'-> interrupt )\r
-* Returns : None.\r
-* Note :\r
-****************************************************************************************************\r
-*/\r
-void setINTMask(u_char mask)\r
-{\r
-WRITE_VALUE(INTMASK, mask);\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* Function to set enable in sending and receiving of broadcast data\r
-*\r
-* Description: Enable to process of broadcating data in UDP or IP RAW mode.\r
-* Arguments : s --> Channel No. to be set\r
-* Returns : None.\r
-* Note :\r
-****************************************************************************************************\r
-*/\r
-void setbroadcast(SOCKET s)\r
-{\r
-u_char val = READ_VALUE(OPT_PROTOCOL(s));\r
-WRITE_VALUE(OPT_PROTOCOL(s), val | SOCKOPT_BROADCAST);\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* Function to set process protocol in IP RAW mode.\r
-*\r
-* Description:\r
-* Arguments : s--> Channel No. to be set\r
-* tos-->Protocol Value to be set\r
-* Returns : None.\r
-* Note :\r
-****************************************************************************************************\r
-*/\r
-void setTOS(SOCKET s, u_char tos)\r
-{\r
-WRITE_VALUE(TOS(s), tos);\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* Upper layer protocol setup function in IP RAW Mode\r
-*\r
-* Description : Upper layer protocol setup function in protocol field of IP header when\r
-* developing upper layer protocol like ICMP, IGMP, EGP etc. by using IP Protocol\r
-* Arguments : s - Channel number\r
-* ipprotocol - Upper layer protocol setting value of IP Protocol\r
-* (Possible to use designated IPPROTO_ in header file)\r
-* Returns : None\r
-* Note : API Function\r
-* This function should be called before calling socket() that is, before\r
-* socket initialization.\r
-****************************************************************************************************\r
-*/\r
-void setIPprotocol(SOCKET s, u_char ipprotocol)\r
-{\r
-WRITE_VALUE(IP_PROTOCOL(s), ipprotocol);\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* Initialization function to appropriate channel\r
-*\r
-* Description : Initialize designated channel and wait until W3100 has done.\r
-* Arguments : s - channel number\r
-* protocol - designate protocol for channel\r
-* SOCK_STREAM(0x01) -> TCP.\r
-* SOCK_DGRAM(0x02) -> UDP.\r
-* SOCK_IPL_RAW(0x03) -> IP LAYER RAW.\r
-* SOCK_MACL_RAW(0x04) -> MAC LAYER RAW.\r
-* port - designate source port for appropriate channel\r
-* flag - designate option to be used in appropriate.\r
-* SOCKOPT_BROADCAST(0x80) -> Send/receive broadcast message in UDP\r
-* SOCKOPT_NDTIMEOUT(0x40) -> Use register value which designated TIMEOUT\r
-* value\r
-* SOCKOPT_NDACK(0x20) -> When not using no delayed ack\r
-* SOCKOPT_SWS(0x10) -> When not using silly window syndrome\r
-* Returns : When succeeded : Channel number, failed :-1\r
-* Note : API Function\r
-****************************************************************************************************\r
-*/\r
-char socket(SOCKET s, u_char protocol, u_int port, u_char flag)\r
-{\r
-u_char k;\r
-\r
-//Designate socket protocol and option\r
-WRITE_VALUE(OPT_PROTOCOL(s), protocol | flag);\r
-\r
-// setup designated port number\r
-if (port != 0)\r
- {\r
- k = (u_char)((port & 0xff00) >> 8);\r
- WRITE_VALUE(SRC_PORT_PTR(s), k);\r
- k = (u_char)(port & 0x00ff);\r
- WRITE_VALUE(SRC_PORT_PTR(s) + SA_OFFSET(1), k);\r
- }\r
-else\r
- {\r
- // Designate random port number which is managed by local when you didn't designate source port\r
- Local_Port++;\r
-\r
- WRITE_VALUE(SRC_PORT_PTR(s), (u_char)((Local_Port & 0xff00) >> 8));\r
- WRITE_VALUE(SRC_PORT_PTR(s) + SA_OFFSET(1), (u_char)(Local_Port & 0x00ff));\r
- }\r
-\r
-// SOCK_INIT\r
-I_STATUS[s] = 0;\r
-WRITE_VALUE(COMMAND(s), CSOCK_INIT);\r
-\r
-// Waiting Interrupt to CSOCK_INIT\r
-while (I_STATUS[s] == 0)\r
- I2CHIP_POLL_ISR(in4_isr_i2chip);\r
-\r
-if (!(I_STATUS[s] & SSOCK_INIT_OK))\r
- return(-1);\r
-\r
-initseqnum(s); // Use initial seq# with random number\r
-\r
-return(s);\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* Connection establishing function to designated peer.\r
-*\r
-* Description : This function establish a connection to the peer by designated channel,\r
-* and wait until the connection is established successfully. (TCP client mode)\r
-* Arguments : s - channel number\r
-* addr - destination IP Address\r
-* port - destination Port Number\r
-* Returns : when succeeded : 1, failed : -1\r
-* Note : API Function\r
-****************************************************************************************************\r
-*/\r
-char connect(SOCKET s, u_char far * addr, u_int port)\r
-{\r
-\r
-if (port != 0)\r
- { //designate destination port\r
- WRITE_VALUE(DST_PORT_PTR(s), (u_char)((port & 0xff00) >> 8));\r
- WRITE_VALUE(DST_PORT_PTR(s) + SA_OFFSET(1), (u_char)(port & 0x00ff));\r
- }\r
-else\r
- return(-1);\r
-\r
- WRITE_VALUE(DST_IP_PTR(s), addr[0]); //designate destination IP address\r
- WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(1), addr[1]);\r
- WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(2), addr[2]);\r
- WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(3), addr[3]);\r
-\r
-I_STATUS[s] = 0;\r
-\r
- WRITE_VALUE(COMMAND(s), CCONNECT); // CONNECT\r
- I2CHIP_POLL_ISR(in4_isr_i2chip);\r
-\r
-// Wait until connection is established successfully\r
-while (I_STATUS[s] == 0)\r
- {\r
- // When failed, appropriate channel will be closed and return an error\r
- if (select(s, SEL_CONTROL) == SOCK_CLOSED)\r
- return -1;\r
- }\r
-\r
-if (!(I_STATUS[s] & SESTABLISHED))\r
- return(-1);\r
-\r
-return(1);\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* Connection establishing function to designated peer. (Non-blocking Mode)\r
-*\r
-* Description : This function establish a connection to the peer by designated channel.\r
-*\r
-* Arguments : s - channel number\r
-* addr - destination IP Address\r
-* port - destination Port Number\r
-* Returns : when succeeded : 1, failed : -1\r
-* Note : API Function\r
-****************************************************************************************************\r
-*/\r
-char NBconnect(SOCKET s, u_char far * addr, u_int port)\r
-{\r
-\r
-if (port != 0)\r
- { //designate destination port\r
- WRITE_VALUE(DST_PORT_PTR(s), (u_char) ((port & 0xff00) >> 8) );\r
- WRITE_VALUE(DST_PORT_PTR(s) + SA_OFFSET(1), (u_char)(port & 0x00ff));\r
- }\r
-else\r
- return(-1);\r
-\r
- WRITE_VALUE(DST_IP_PTR(s), addr[0]); //designate destination IP address\r
- WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(1), addr[1]);\r
- WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(2), addr[2]);\r
- WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(3), addr[3]);\r
-\r
-I_STATUS[s] = 0;\r
-\r
-WRITE_VALUE(COMMAND(s), CCONNECT); // CONNECT\r
-return(1);\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* Waits for connection request from a peer (Blocking Mode)\r
-*\r
-* Description : Wait for connection request from a peer through designated channel (TCP Server mode)\r
-* Arguments : s - channel number\r
-* addr - IP Address of the peer when a connection is established\r
-* port - Port number of the peer when a connection is established\r
-* Returns : When succeeded : 1, failed : -1\r
-* Note : API Function\r
-****************************************************************************************************\r
-*/\r
-/*\r
-char listen(SOCKET s, u_char far * addr, u_int far * port)\r
-{\r
-u_int i;\r
-\r
-I_STATUS[s] = 0;\r
-\r
-// LISTEN\r
-COMMAND(s) = CLISTEN;\r
-\r
-// Wait until connection is established\r
-while (I_STATUS[s] == 0)\r
- {\r
- // When failed to connect, the designated channel will be closed and return an error.\r
- if (select(s, SEL_CONTROL) == SOCK_CLOSED)\r
- return -1;\r
- }\r
-\r
-// Receive IP address and port number of the peer connected\r
-if (I_STATUS[s] & SESTABLISHED)\r
- {\r
- i = *DST_PORT_PTR(s);\r
- *port = (u_int)((i & 0xff00) >> 8);\r
- i = *(DST_PORT_PTR(s) + 2);\r
- i = (u_int)(i & 0x00ff);\r
- *port += (i << 8);\r
-\r
- addr[0] = *DST_IP_PTR(s);\r
- addr[1] = *(DST_IP_PTR(s) + 2);\r
- addr[2] = *(DST_IP_PTR(s) + 4);\r
- addr[3] = *(DST_IP_PTR(s) + 6);\r
- }\r
-else\r
- return(-1);\r
-\r
-return(1);\r
-}\r
-*/\r
-\r
-/*\r
-****************************************************************************************************\r
-* Waits for connection request from a peer (Non-blocking Mode)\r
-*\r
-* Description : Wait for connection request from a peer through designated channel (TCP Server mode)\r
-* Arguments : s - channel number\r
-* Returns : None\r
-* Note : API Function\r
-****************************************************************************************************\r
-*/\r
-char NBlisten(SOCKET s)\r
-{\r
-I_STATUS[s] = 0;\r
-\r
-// LISTEN\r
-WRITE_VALUE(COMMAND(s), CLISTEN);\r
-\r
-return(1);\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* Create random value for initial Seq# when establishing TCP connection\r
-*\r
-* Description : In this function, you can add some source codes to create random number for\r
-* initial Seq#. In real, TCP initial SEQ# should be random value.\r
-* (Currently, we're using static value in EVB/DK.)\r
-* Arguments : s - channel number\r
-* Returns : None\r
-* Note : API Function\r
-****************************************************************************************************\r
-*/\r
-void initseqnum(SOCKET s)\r
-{\r
-// Designate initial seq#\r
-// If you have random number generation function, assign random number instead of SEQ_NUM.lVal++.\r
-SEQ_NUM.lVal++;\r
-\r
-//randomize();\r
-//SEQ_NUM.lVal = rand();\r
-\r
-WRITE_VALUE(TX_WR_PTR(s), SEQ_NUM.cVal[0]);\r
-WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(1), SEQ_NUM.cVal[1]);\r
-WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(2), SEQ_NUM.cVal[2]);\r
-WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(3), SEQ_NUM.cVal[3]);\r
-delay0(2);\r
-\r
-WRITE_VALUE(TX_RD_PTR(s), SEQ_NUM.cVal[0]);\r
-WRITE_VALUE(TX_RD_PTR(s) + SA_OFFSET(1), SEQ_NUM.cVal[1]);\r
-WRITE_VALUE(TX_RD_PTR(s) + SA_OFFSET(2), SEQ_NUM.cVal[2]);\r
-WRITE_VALUE(TX_RD_PTR(s) + SA_OFFSET(3), SEQ_NUM.cVal[3]);\r
-delay0(2);\r
-\r
-WRITE_VALUE(TX_ACK_PTR(s), SEQ_NUM.cVal[0]);\r
-WRITE_VALUE(TX_ACK_PTR(s) + SA_OFFSET(1), SEQ_NUM.cVal[1]);\r
-WRITE_VALUE(TX_ACK_PTR(s) + SA_OFFSET(2), SEQ_NUM.cVal[2]);\r
-WRITE_VALUE(TX_ACK_PTR(s) + SA_OFFSET(3), SEQ_NUM.cVal[3]);\r
-delay0(2);\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* Function for sending TCP data.\r
-*\r
-* Description : Function for sending TCP data and Composed of the send() and send_in() functions.\r
-* The send() function is an application I/F function.\r
-* It continues to call the send_in() function to complete the sending of the data up to the\r
-* size of the data to be sent when the application is called.\r
-* The send_in() function receives the return value (the size of the data sent), calculates\r
-* the size of the data to be sent, and calls the send_in() function again if there is any\r
-* data left to be sent.\r
-* Arguments : s - channel number\r
-* buf - Pointer pointing data to send\r
-* len - data size to send\r
-* Returns : Succeed: sent data size, Failed: -1;\r
-* Note : API Function\r
-****************************************************************************************************\r
-*/\r
-int send(SOCKET s, u_char far * buf, u_int len)\r
-{\r
-int ptr, size;\r
-u_char huge* huge_buf = (u_char huge*)buf;\r
-u_char far* local_buf = (u_char far*)huge_buf; \r
-\r
-if (len <= 0)\r
- return (0);\r
-else\r
- {\r
- ptr = 0;\r
- do\r
- {\r
- size = send_in(s, local_buf + ptr, len);\r
- if (size == -1)\r
- return -1;\r
- len = len - size;\r
- ptr += size;\r
- } while ( len > 0);\r
- }\r
-return ptr;\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* Internal function for sending TCP data.\r
-*\r
-* Description : Called by the send() function for TCP transmission.\r
-* It first calculates the free transmit buffer size\r
-* and compares it with the size of the data to be transmitted to determine the transmission size.\r
-* After calculating the data size, it copies data from TX_WR_PTR.\r
-* It waits if there is a previous send command in process.\r
-* When the send command is cleared, it updates the TX_WR_PTR up to the size to be transmitted\r
- and performs the send command.\r
-* Arguments : s - channel number\r
-* buf - Pointer pointing data to send\r
-* len - data size to send\r
-* Returns : Succeeded: sent data size, Failed: -1\r
-* Note : Internal Function\r
-****************************************************************************************************\r
-*/\r
-int send_in(SOCKET s, u_char far * buf, u_int len)\r
-{\r
-u_char k;\r
-u_int size;\r
-union un_l2cval wr_ptr, ack_ptr;\r
-unsigned int offset;\r
-\r
-S_START:\r
-disable(); // CT: Shadow register access should not conflict with ISR.\r
-k = READ_VALUE(SHADOW_TXWR_PTR(s));\r
-WINDOW_RESTORE_BASE; // Needed whenever we touch a shadow ptr; different window.\r
-delay0(2);\r
-wr_ptr.cVal[3] = READ_VALUE(TX_WR_PTR(s));\r
-wr_ptr.cVal[2] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(1));\r
-wr_ptr.cVal[1] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(2));\r
-wr_ptr.cVal[0] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(3));\r
-\r
-k = READ_VALUE(SHADOW_TXACK_PTR(s));\r
-WINDOW_RESTORE_BASE; // Needed whenever we touch a shadow ptr; different window.\r
-delay0(2);\r
-ack_ptr.cVal[3] = READ_VALUE(TX_ACK_PTR(s));\r
-ack_ptr.cVal[2] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(1));\r
-ack_ptr.cVal[1] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(2));\r
-ack_ptr.cVal[0] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(3));\r
-enable();\r
-\r
-// Suppress compiler errors that k is not used\r
-k = k;\r
-\r
-// Calculate send free buffer size\r
-if (wr_ptr.lVal >= ack_ptr.lVal)\r
- size = (u_int)(SSIZE[s] - (wr_ptr.lVal - ack_ptr.lVal));\r
-else\r
- size = (u_int)(SSIZE[s] - (0 - ack_ptr.lVal + wr_ptr.lVal));\r
-\r
-// Recalulate after some delay because of error in pointer calculation\r
-if (size > SSIZE[s])\r
- {\r
- if (select(s, SEL_CONTROL) != SOCK_ESTABLISHED)\r
- return -1;\r
- delay_ms(1);\r
- goto S_START;\r
- }\r
-\r
-// Wait when previous sending has not finished yet and there's no free buffer\r
-if (size == 0)\r
- {\r
- if (select(s, SEL_CONTROL) != SOCK_ESTABLISHED)\r
- return -1;\r
-\r
- delay_ms(1);\r
- goto S_START;\r
- }\r
-else if (size < len)\r
- {\r
- len = size;\r
- }\r
-\r
-// Calculate pointer to data copy\r
-offset = (UINT)(wr_ptr.lVal & SMASK[s]);\r
-\r
-// copy data\r
-write_data(s, buf, offset, len);\r
-\r
-while (READ_VALUE(COMMAND(s)) & CSEND)\r
- {\r
- // Confirm previous send command\r
- if (select(s, SEL_CONTROL) != SOCK_ESTABLISHED)\r
- return -1;\r
- }\r
-\r
-// update tx_wr_ptr\r
-wr_ptr.lVal = wr_ptr.lVal + len;\r
-WRITE_VALUE(TX_WR_PTR(s), wr_ptr.cVal[3]);\r
-WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(1), wr_ptr.cVal[2]);\r
-WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(2), wr_ptr.cVal[1]);\r
-WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(3), wr_ptr.cVal[0]);\r
-\r
-delay0(1);\r
-\r
-// SEND\r
-WRITE_VALUE(COMMAND(s), CSEND);\r
-\r
-return(len);\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* TCP data receiving function.\r
-*\r
-* Description : This function is to clear out any received TCP data.\r
-* Arguments : s - channel number\r
-* Returns : None\r
-* Note : API Fcuntion\r
-****************************************************************************************************\r
-*/\r
-void recv_clear(SOCKET s)\r
-{\r
-u_char k;\r
-u_int size;\r
-union un_l2cval wr_ptr, rd_ptr;\r
-\r
-disable();\r
-k = READ_VALUE(SHADOW_RXWR_PTR(s));\r
-WINDOW_RESTORE_BASE; // Needed whenever we touch a shadow ptr; different window.\r
-delay0(2);\r
-wr_ptr.cVal[3] = READ_VALUE(RX_WR_PTR(s));\r
-wr_ptr.cVal[2] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(1));\r
-wr_ptr.cVal[1] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(2));\r
-wr_ptr.cVal[0] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(3));\r
-\r
-k = READ_VALUE(SHADOW_RXRD_PTR(s));\r
-WINDOW_RESTORE_BASE; // Needed whenever we touch a shadow ptr; different window.\r
-delay0(2);\r
-rd_ptr.cVal[3] = READ_VALUE(RX_RD_PTR(s));\r
-rd_ptr.cVal[2] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(1));\r
-rd_ptr.cVal[1] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(2));\r
-rd_ptr.cVal[0] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(3));\r
-enable();\r
-\r
-// Suppress compiler errors that k is not used\r
-k = k;\r
-\r
-// calculate received data size\r
-if (wr_ptr.lVal >= rd_ptr.lVal)\r
- size = (u_int)(wr_ptr.lVal - rd_ptr.lVal);\r
-else\r
- size = (u_int)(0 - rd_ptr.lVal + wr_ptr.lVal);\r
-\r
-// Update rx_rd_ptr\r
-rd_ptr.lVal += size;\r
-WRITE_VALUE(RX_RD_PTR(s), rd_ptr.cVal[3]);\r
-WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(1), rd_ptr.cVal[2]);\r
-WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(2), rd_ptr.cVal[1]);\r
-WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(3), rd_ptr.cVal[0]);\r
-\r
-// RECV\r
- WRITE_VALUE(COMMAND(s), CRECV);\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* TCP data receiving function.\r
-*\r
-* Description : This function is for receiving TCP data.\r
-* The recv() function is an application I/F function. It will read up to len chars if there are\r
- enough characters in the buffer, otherwise will onl read the number of characters availiable\r
-* Arguments : s - channel number\r
-* buf - Pointer where the data to be received is copied\r
-* len - Size of the data to be received\r
-* Returns : Succeeded: received data size, Failed: -1\r
-* Note : API Fcuntion\r
-****************************************************************************************************\r
-*/\r
-int recv(SOCKET s, u_char far * buf, u_int len)\r
-{\r
-u_char k;\r
-u_int size;\r
-union un_l2cval wr_ptr, rd_ptr;\r
-unsigned int offset;\r
-\r
-// If out length is 0, then we do not need to do anything\r
-if (len <= 0)\r
- return (0);\r
-\r
-disable();\r
-k = READ_VALUE(SHADOW_RXWR_PTR(s));\r
-WINDOW_RESTORE_BASE; // Needed whenever we touch a shadow ptr; different window.\r
-delay0(2);\r
-wr_ptr.cVal[3] = READ_VALUE(RX_WR_PTR(s));\r
-wr_ptr.cVal[2] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(1));\r
-wr_ptr.cVal[1] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(2));\r
-wr_ptr.cVal[0] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(3));\r
-\r
-k = READ_VALUE(SHADOW_RXRD_PTR(s));\r
-WINDOW_RESTORE_BASE; // Needed whenever we touch a shadow ptr; different window.\r
-delay0(2);\r
-rd_ptr.cVal[3] = READ_VALUE(RX_RD_PTR(s));\r
-rd_ptr.cVal[2] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(1));\r
-rd_ptr.cVal[1] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(2));\r
-rd_ptr.cVal[0] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(3));\r
-enable();\r
-\r
-// Suppress compiler errors that k is not used\r
-k = k;\r
-\r
-// calculate IIM7010A received data size\r
-if (wr_ptr.lVal == rd_ptr.lVal)\r
- return(0);\r
-else if (wr_ptr.lVal >= rd_ptr.lVal)\r
- size = (u_int)(wr_ptr.lVal - rd_ptr.lVal);\r
-else\r
- size = (u_int)(0 - rd_ptr.lVal + wr_ptr.lVal);\r
-\r
-// Make sure we do not try to read more characters than what is availiable in the IIM7010 buffer\r
-if (size < len)\r
- len = size;\r
-\r
-// Calculate pointer to be copied received data\r
-offset = ((UINT)(rd_ptr.lVal & RMASK[s]));\r
-\r
-// Copy received data\r
-size = read_data(s, offset, buf, len);\r
-\r
-// Update rx_rd_ptr\r
-rd_ptr.lVal += size;\r
-WRITE_VALUE(RX_RD_PTR(s), rd_ptr.cVal[3]);\r
-WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(1), rd_ptr.cVal[2]);\r
-WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(2), rd_ptr.cVal[1]);\r
-WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(3), rd_ptr.cVal[0]);\r
-\r
-// RECV\r
- WRITE_VALUE(COMMAND(s), CRECV);\r
-return(size);\r
-}\r
-\r
-\r
-/*\r
-****************************************************************************************************\r
-* UDP data sending function.\r
-*\r
-* Description : Composed of the sendto()and sendto_in() functions.\r
-* The send() function is an application I/F function.\r
-* It continues to call the send_in() function to complete the sending of the data up to the\r
-* size of the data to be sent\r
-* when the application is called.Unlike TCP transmission, it designates the destination address\r
-* and the port.\r
-* Arguments : s - channel port\r
-* buf - Pointer pointing data to send\r
-* len - data size to send\r
-* addr - destination IP address to send data\r
-* port - destination port number to send data\r
-* Returns : Sent data size\r
-* Note : API Function\r
-****************************************************************************************************\r
-*/\r
-u_int sendto(SOCKET s, u_char far * buf, u_int len, u_char * addr, u_int port)\r
-{\r
-//char val;\r
-u_int ptr, size;\r
-\r
-// Wait until previous send commnad has completed.\r
-while(READ_VALUE(COMMAND(s)) & CSEND)\r
- {\r
- if(select(s, SEL_CONTROL) == SOCK_CLOSED)\r
- return -1; // Error.\r
- }\r
-\r
-// Designate destination port number.\r
-if (port != 0)\r
- {\r
- WRITE_VALUE(DST_PORT_PTR(s), (u_char)((port & 0xff00) >> 8));\r
- WRITE_VALUE(DST_PORT_PTR(s) + SA_OFFSET(1), (u_char)(port & 0x00ff));\r
- }\r
-\r
-// Designate destination IP address\r
-WRITE_VALUE(DST_IP_PTR(s), addr[0]);\r
-WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(1), addr[1]);\r
-WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(2), addr[2]);\r
-WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(3), addr[3]);\r
-\r
-if (len <= 0)\r
- return (0);\r
-else\r
- {\r
- ptr = 0;\r
- do\r
- {\r
- size = sendto_in(s, buf + ptr, len);\r
- len = len - size;\r
- ptr += size;\r
- } while ( len > 0);\r
- }\r
-return ptr;\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* UDP data sending function.\r
-*\r
-* Description : An internal function that is the same as the send_in() function of the TCP.\r
-* Arguments : s - Channel number\r
-* buf - Pointer indicating the data to send\r
-* len - data size to send\r
-* Returns : Sent data size\r
-* Note : Internal Function\r
-****************************************************************************************************\r
-*/\r
-u_int sendto_in(SOCKET s, u_char far * buf, u_int len)\r
-{\r
-u_char k;\r
-u_int size;\r
-union un_l2cval wr_ptr, rd_ptr;\r
-unsigned int offset;\r
-\r
-S2_START:\r
-disable();\r
-k = READ_VALUE(SHADOW_TXWR_PTR(s));\r
-WINDOW_RESTORE_BASE; // Needed whenever we touch a shadow ptr; different window.\r
-delay0(2);\r
-wr_ptr.cVal[3] = READ_VALUE(TX_WR_PTR(s));\r
-wr_ptr.cVal[2] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(1));\r
-wr_ptr.cVal[1] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(2));\r
-wr_ptr.cVal[0] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(3));\r
-\r
-k = READ_VALUE(SHADOW_TXRD_PTR(s));\r
-WINDOW_RESTORE_BASE; // Needed whenever we touch a shadow ptr; different window.\r
-delay0(2);\r
-rd_ptr.cVal[3] = READ_VALUE(TX_RD_PTR(s));\r
-rd_ptr.cVal[2] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(1));\r
-rd_ptr.cVal[1] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(2));\r
-rd_ptr.cVal[0] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(3));\r
-enable();\r
-\r
-// Suppress compiler errors that k is not used\r
-k = k;\r
-\r
-// Calculate free buffer size to send\r
-if (wr_ptr.lVal >= rd_ptr.lVal)\r
- size = (u_int)(SSIZE[s] - (wr_ptr.lVal - rd_ptr.lVal));\r
-else\r
- size = (u_int)(SSIZE[s] - (0 - rd_ptr.lVal + wr_ptr.lVal));\r
-\r
-// Recalulate after some delay because of error in pointer caluation\r
-if (size > SSIZE[s])\r
- {\r
- delay_ms(1);\r
- goto S2_START;\r
- }\r
-\r
-// Wait when previous sending has not finished yet and there's no free buffer\r
-if (size == 0)\r
- {\r
- delay_ms(1);\r
- goto S2_START;\r
-\r
- }\r
-else if (size < len)\r
- {\r
- len = size;\r
- }\r
-\r
-// Calculate pointer to copy data pointer\r
-offset =(UINT)(wr_ptr.lVal & SMASK[s]);\r
-\r
-// copy data\r
-write_data(s, buf, offset, len);\r
-\r
-// Confirm previous send command\r
-while (READ_VALUE(COMMAND(s)) & CSEND)\r
- {\r
- if(select(s, SEL_CONTROL)==SOCK_CLOSED)\r
- return -1; // Error\r
- }\r
-\r
-// update tx_wr_ptr\r
-wr_ptr.lVal = wr_ptr.lVal + len;\r
-WRITE_VALUE(TX_WR_PTR(s), wr_ptr.cVal[3]);\r
-WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(1), wr_ptr.cVal[2]);\r
-WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(2), wr_ptr.cVal[1]);\r
-WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(3), wr_ptr.cVal[0]);\r
-\r
-delay0(1);\r
-\r
-// SEND\r
-WRITE_VALUE(COMMAND(s), CSEND);\r
-\r
-return(len);\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* UDP data receiving function.\r
-*\r
-* Description : Function for receiving UDP and IP layer RAW mode data, and handling the data header.\r
-* Arguments : s - channel number\r
-* buf - Pointer where the data to be received is copied\r
-* len - Size of the data to be received\r
-* addr - Peer IP address for receiving\r
-* port - Peer port number for receiving\r
-* Returns : Received data size\r
-* Note : API Function\r
-****************************************************************************************************\r
-*/\r
-u_int recvfrom(SOCKET s, u_char far *buf, u_int len, u_char *addr, u_int *port)\r
-{\r
-struct _UDPHeader // When receiving UDP data, header added by W3100A\r
- {\r
- union\r
- {\r
- struct\r
- {\r
- u_int size;\r
- u_char addr[4];\r
- u_int port;\r
- } header;\r
- u_char stream[8];\r
- } u;\r
- } UDPHeader;\r
-\r
-u_int ret;\r
-union un_l2cval wr_ptr, rd_ptr;\r
-u_long size;\r
-u_char k;\r
-unsigned int offset;\r
-\r
-if(select(s,SEL_CONTROL)==SOCK_CLOSED)\r
- return -1;\r
-\r
-disable();\r
-k = READ_VALUE(SHADOW_RXWR_PTR(s));\r
-WINDOW_RESTORE_BASE; // Needed whenever we touch a shadow ptr; different window.\r
-delay0(2);\r
-wr_ptr.cVal[3] = READ_VALUE(RX_WR_PTR(s));\r
-wr_ptr.cVal[2] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(1));\r
-wr_ptr.cVal[1] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(2));\r
-wr_ptr.cVal[0] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(3));\r
-\r
-k = READ_VALUE(SHADOW_RXRD_PTR(s));\r
-WINDOW_RESTORE_BASE; // Needed whenever we touch a shadow ptr; different window.\r
-delay0(2);\r
-rd_ptr.cVal[3] = READ_VALUE(RX_RD_PTR(s));\r
-rd_ptr.cVal[2] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(1));\r
-rd_ptr.cVal[1] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(2));\r
-rd_ptr.cVal[0] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(3));\r
-enable();\r
-\r
-// Suppress compiler errors that k is not used\r
-k = k;\r
-\r
-// Calculate received data size\r
-if (len <= 0)\r
- return (0);\r
-else if (wr_ptr.lVal >= rd_ptr.lVal)\r
- size = wr_ptr.lVal - rd_ptr.lVal;\r
-else\r
- size = 0 - rd_ptr.lVal + wr_ptr.lVal;\r
-\r
-if (size == 0)\r
- return 0;\r
-\r
- // Calulate received data pointer\r
-offset = ((UINT)(rd_ptr.lVal & RMASK[s]));\r
-\r
-// When UDP data\r
-if (( READ_VALUE(OPT_PROTOCOL(s)) & 0x07) == SOCK_DGRAM)\r
- {\r
- // Copy W3100A UDP header\r
- read_data(s, offset, UDPHeader.u.stream, 8);\r
-\r
- // Read UDP Packet size\r
- size = UDPHeader.u.stream[0];\r
- size = (size << 8) + UDPHeader.u.stream[1];\r
-\r
- // Read IP address of the peer\r
- addr[0] = UDPHeader.u.header.addr[0];\r
- addr[1] = UDPHeader.u.header.addr[1];\r
- addr[2] = UDPHeader.u.header.addr[2];\r
- addr[3] = UDPHeader.u.header.addr[3];\r
-\r
- // Read Port number of the peer\r
- *port = UDPHeader.u.stream[6];\r
- *port = (*port << 8) + UDPHeader.u.stream[7];\r
-\r
- // Increase read pointer by 8, because already read as UDP header size\r
- rd_ptr.lVal += 8;\r
-\r
- // Calculate UDP data copy pointer\r
- offset = ((UINT)(rd_ptr.lVal & RMASK[s]));\r
-\r
- // Calculate data size of current UDP Packet from UDP header\r
- size = size - 8;\r
-\r
- // Copy one UDP data packet to user-specific buffer\r
- ret = read_data(s, offset, buf, (u_int)size);\r
-\r
- // Increase read pointer by UDP packet data size\r
- rd_ptr.lVal += ret;\r
- }\r
-else if ((READ_VALUE(OPT_PROTOCOL(s)) & 0x07) == SOCK_IPL_RAW) // When IP layer RAW mode data\r
- {\r
- // Copy W3100A IP Raw header\r
- read_data(s, offset, UDPHeader.u.stream, 6);\r
-\r
- // Read IP layer RAW Packet size\r
- size = UDPHeader.u.stream[0];\r
- size = (size << 8) + UDPHeader.u.stream[1];\r
-\r
- // Read IP address of the peer\r
- addr[0] = UDPHeader.u.header.addr[0];\r
- addr[1] = UDPHeader.u.header.addr[1];\r
- addr[2] = UDPHeader.u.header.addr[2];\r
- addr[3] = UDPHeader.u.header.addr[3];\r
-\r
- // Increase read pointer by 6, because already read as IP RAW header size\r
- rd_ptr.lVal += 6;\r
-\r
- // Calculate IP layer raw mode data pointer\r
- offset = ((UINT)(rd_ptr.lVal & RMASK[s]));\r
-\r
- // Copy one IP Raw data packet to user-specific buffer\r
- ret = read_data(s, offset, buf, (u_int)size);\r
- rd_ptr.lVal = rd_ptr.lVal + (ret - 4);\r
- }\r
-\r
- // Update rx_rd_ptr\r
- WRITE_VALUE(RX_RD_PTR(s), rd_ptr.cVal[3]);\r
- WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(1), rd_ptr.cVal[2]);\r
- WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(2), rd_ptr.cVal[1]);\r
- WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(3), rd_ptr.cVal[0]);\r
-\r
- // RECV\r
- WRITE_VALUE(COMMAND(s), CRECV);\r
-\r
-// Real received size return\r
-return(ret);\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* Channel closing function.\r
-*\r
-* Description : Function for closing the connection of the designated channel.\r
-* Arguments : s - channel number\r
-* Returns : None\r
-* Note : API Function\r
-****************************************************************************************************\r
-*/\r
-void close(SOCKET s)\r
-{\r
-u_int len;\r
-\r
-I_STATUS[s] = 0;\r
-\r
-if (select(s, SEL_CONTROL) == SOCK_CLOSED)\r
- return; // Already closed\r
-\r
-// When closing, if there's data which have not processed, Insert some source codes to handle this\r
-// Or before application call close(), handle those data first and call close() later.\r
-\r
-len = select(s, SEL_SEND);\r
-if (len == SSIZE[s])\r
- {\r
- // CLOSE\r
- WRITE_VALUE(COMMAND(s), CCLOSE);\r
- // TODO: The 'SCLOSED' status value is only set briefly as part of the close,\r
- // and will otherwise quickly return to normal. That means your code might\r
- // become 'stuck' at this point even if the packet has closed normally.\r
- // Rather than a while() call, it might be preferred to time out on this\r
- // close check and return to the application after some time.\r
- while(!(I_STATUS[s] & SCLOSED))\r
- I2CHIP_POLL_ISR(in4_isr_i2chip);\r
- }\r
-}\r
-\r
-u_char tx_empty(SOCKET s)\r
-{\r
- return (select(s, SEL_SEND) == SSIZE[s]);\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* Channel closing function.\r
-*\r
-* Description : Function for closing the connection of the designated channel.\r
-* Arguments : s - channel number\r
-* Returns : None\r
-* Note : API Function\r
-****************************************************************************************************\r
-*/\r
-char reset_sock(SOCKET s)\r
-{\r
-u_char c;\r
-\r
-c = 1 << s;\r
-\r
-// RESET\r
-WRITE_VALUE(RESETSOCK, c);\r
-return (1);\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* Function handling the channel socket information.\r
-*\r
-* Description : Return socket information of designated channel\r
-* Arguments : s - channel number\r
-* func - SEL_CONTROL(0x00) -> return socket status\r
-* SEL_SEND(0x01) -> return free transmit buffer size\r
-* SEL_RECV(0x02) -> return received data size\r
-* Returns : socket status or free transmit buffer size or received data size\r
-* Note : API Function\r
-****************************************************************************************************\r
-*/\r
-u_int select(SOCKET s, u_char func)\r
-{\r
-u_int val;\r
-union un_l2cval rd_ptr, wr_ptr, ack_ptr;\r
-u_char k;\r
-\r
-switch (func)\r
- {\r
- // socket status information\r
- case SEL_CONTROL :\r
- val = READ_VALUE(SOCK_STATUS(s));\r
- break;\r
-\r
- // Calculate send free buffer size\r
- case SEL_SEND :\r
- disable();\r
- k = READ_VALUE(SHADOW_TXWR_PTR(s));\r
- WINDOW_RESTORE_BASE; // Needed whenever we touch a shadow ptr; different window.\r
- delay0(2);\r
- wr_ptr.cVal[3] = READ_VALUE(TX_WR_PTR(s));\r
- wr_ptr.cVal[2] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(1));\r
- wr_ptr.cVal[1] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(2));\r
- wr_ptr.cVal[0] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(3));\r
-\r
- if (( READ_VALUE(OPT_PROTOCOL(s)) & 0x07) == SOCK_STREAM) // TCP\r
- {\r
- k = READ_VALUE(SHADOW_TXACK_PTR(s));\r
- WINDOW_RESTORE_BASE; // Needed whenever we touch a shadow ptr; different window.\r
- delay0(2);\r
- ack_ptr.cVal[3] = READ_VALUE(TX_ACK_PTR(s));\r
- ack_ptr.cVal[2] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(1));\r
- ack_ptr.cVal[1] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(2));\r
- ack_ptr.cVal[0] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(3));\r
- enable();\r
-\r
- if (wr_ptr.lVal >= ack_ptr.lVal)\r
- val = (u_int)(SSIZE[s] - (wr_ptr.lVal - ack_ptr.lVal));\r
- else\r
- val = (u_int)(SSIZE[s] - (0 - ack_ptr.lVal + wr_ptr.lVal));\r
- }\r
- else // UDP, IP RAW ... (except TCP)\r
- {\r
- k = READ_VALUE(SHADOW_TXRD_PTR(s));\r
- WINDOW_RESTORE_BASE; // Needed whenever we touch a shadow ptr; different window.\r
- delay0(2);\r
- rd_ptr.cVal[3] = READ_VALUE(TX_RD_PTR(s));\r
- rd_ptr.cVal[2] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(1));\r
- rd_ptr.cVal[1] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(2));\r
- rd_ptr.cVal[0] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(3));\r
- enable();\r
-\r
- if (wr_ptr.lVal >= rd_ptr.lVal)\r
- val = (u_int)(SSIZE[s] - (wr_ptr.lVal - rd_ptr.lVal));\r
- else\r
- val = (u_int)(SSIZE[s] - (0 - rd_ptr.lVal + wr_ptr.lVal));\r
- }\r
- break;\r
-\r
- // Calculate received data size\r
- case SEL_RECV :\r
- disable();\r
- k = READ_VALUE(SHADOW_RXWR_PTR(s));\r
- WINDOW_RESTORE_BASE; // Needed whenever we touch a shadow ptr; different window.\r
- delay0(2);\r
- wr_ptr.cVal[3] = READ_VALUE(RX_WR_PTR(s));\r
- wr_ptr.cVal[2] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(1));\r
- wr_ptr.cVal[1] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(2));\r
- wr_ptr.cVal[0] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(3));\r
-\r
- k = READ_VALUE(SHADOW_RXRD_PTR(s));\r
- WINDOW_RESTORE_BASE; // Needed whenever we touch a shadow ptr; different window.\r
- delay0(2);\r
- rd_ptr.cVal[3] = READ_VALUE(RX_RD_PTR(s));\r
- rd_ptr.cVal[2] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(1));\r
- rd_ptr.cVal[1] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(2));\r
- rd_ptr.cVal[0] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(3));\r
- enable();\r
-\r
- if (wr_ptr.lVal == rd_ptr.lVal)\r
- val = 0;\r
- else if (wr_ptr.lVal > rd_ptr.lVal)\r
- val = (u_int)(wr_ptr.lVal - rd_ptr.lVal);\r
- else\r
- val = (u_int)(0 - rd_ptr.lVal + wr_ptr.lVal);\r
- break;\r
-\r
- default :\r
- val = -1;\r
- break;\r
- }\r
-// Suppress compiler errors that k is not used\r
-k = k;\r
-return(val);\r
-}\r
-\r
-//\r
-// unsigned char dma_read_i2chip (unsigned int i2_segm, unsigned int i2_offs,\r
-// unsigned int cnt, unsigned int des_segm, unsigned int des_offs);\r
-// Using DMA0 to read data from i2chip buffer into destination SRAM.\r
-// where:\r
-// unsigned int cnt = number of sectors, 512-byte per sector\r
-// unsigned int des_segm = segment of destination SRAM data memory\r
-// unsigned int des_offs = offset of destination SRAM data memory\r
-// unsigned int i2_segm = segment of i2chip buffer mapped in memory\r
-// unsigned int i2_offs = offset of i2chip buffer mapped in memory\r
-// return DMA counter value\r
-//\r
-unsigned int dma_read_i2chip(u_char far* i2_src, u_char far* des, u_int cnt)\r
-{\r
- u_int des_segm, des_offs;\r
- u_int i2_segm, i2_offs;\r
- u_long temp;\r
-\r
- temp = ((long)FP_SEG(des) << 4) + ((long)FP_OFF(des));\r
- des_segm = (u_int)(temp >> 16);\r
- des_offs = (u_int)(temp & 0xffff);\r
-\r
- temp = ((long)FP_SEG(i2_src) << 4) + ((long)FP_OFF(i2_src));\r
- i2_segm = (u_int)(temp >> 16);\r
- i2_offs = (u_int)(temp & 0xffff);\r
-\r
- outport(0xffc6, des_segm); /* D0DSTH destination SRAM segment */\r
- outport(0xffc4, des_offs); /* D0DSTL destination SRAM offset */\r
- outport(0xffc2, i2_segm); /* D0SRCH=SP0RD */\r
- outport(0xffc0, i2_offs); /* D0SRCL=SP0RD */\r
- outport(0xffc8, cnt); // D0TC counter\r
- outport(0xfff8,0x0504); // PLLCON, 0203=10M,050f=40M, 051f=80MHz\r
-// DMA0 mem-mem, 16-bit, unsync, Start moving data line below\r
- outport(0xffca, 0xb60e); /* D0CON 1011 0110 0000 1111 */\r
-// outport(0xffca, 0xb42e); // 1011 0100 0010 1110\r
- while( inport(0xffc8) ); /* D0TC counter=0, DMA complete */\r
- outport(0xfff8,0x051f); // PLLCON, 0203=10M,050f=40M, 051f=80MHz\r
-return( inport(0xffc8) ); // counter\r
-}\r
-\r
-//\r
-// unsigned int dma_write_i2chip (unsigned int src_segm, unsigned int src_offs,\r
-// unsigned int cnt, unsigned int i2_segm, unsigned int i2_offs);\r
-// Using DMA0 to write data from memory into i2chip.\r
-// where:\r
-// unsigned int cnt = number of 16-bit DMA transfers\r
-// unsigned int src_segm = segment of the source SRAM data memory\r
-// unsigned int src_offs = offset of the source SRAM data memory\r
-// unsigned int i2_segm = segment of i2chip buffer mapped in memory\r
-// unsigned int i2_offs = offset of i2chip buffer mapped in memory\r
-// return DMA counter value\r
-//\r
-unsigned int dma_write_i2chip(u_char far* src, u_char far* i2_dest, u_int cnt)\r
-{\r
- u_int src_segm, src_offs;\r
- u_int i2_segm, i2_offs;\r
- u_long temp;\r
-\r
- temp = (FP_SEG(src) << 4) + (FP_OFF(src));\r
- src_segm = (u_int)(temp >> 4);\r
- src_offs = (u_int)(temp & 0xffff);\r
-\r
- temp = (FP_SEG(i2_dest) << 4) + (FP_OFF(i2_dest));\r
- i2_segm = (u_int)(temp >> 4);\r
- i2_offs = (u_int)(temp & 0xffff);\r
-\r
- outport(0xffc8, cnt); // D0TC counter\r
- outport(0xffc6, i2_segm); // D0DSTH=i2chip buffer segment\r
- outport(0xffc4, i2_offs); // D0DSTL=i2chip buffer offset\r
- outport(0xffc2, src_segm); /* D0SRCH=SP0RD */\r
- outport(0xffc0, src_offs); /* D0SRCL=SP0RD */\r
-// outport(0xfff8,0x050f); // PLLCON, 0203=10M,050f=40M, 051f=80MHz\r
-// DMA0 mem-mem, 16-bit, unsync, Start moving data line below\r
- outport(0xffca, 0xb60f); /* D0CON 1011 0110 0000 1111 */\r
- while( inport(0xffc8) ); /* D0TC counter=0, DMA complete */\r
-// outport(0xfff8,0x051f); // PLLCON, 0203=10M,050f=40M, 051f=80MHz\r
-\r
-return( inport(0xffc8) ); // counter\r
-}\r
-\r
-/*\r
-****************************************************************************************************\r
-* Copies the receive buffer data of the W3100A to the system buffer.\r
-*\r
-* Description : Copies the receive buffer data of the W3100A to the system buffer.\r
-* It is called from the recv()or recvfrom() function.\r
-* Arguments : s - channel number\r
-* src - receive buffer pointer of W3100A\r
-* dst - system buffer pointer\r
-* len - data size to copy\r
-* Returns : copied data size\r
-* Note : Internal Function\r
-****************************************************************************************************\r
-*/\r
-u_int read_data(SOCKET s, u_int offset, u_char far * dst, u_int len)\r
-{\r
- u_int i, size, size1;\r
- u_char far* src = (u_char far*)(MK_FP_WINDOW(RECV_DATA_BUF,\r
- RBUFBASEADDRESS[s] + offset));\r
-// src = (u_char far*)(MK_FP_WINDOW(RECV_DATA_BUF,\r
-// 0));\r
-\r
- if (len == 0)\r
- {\r
- WINDOW_RESTORE_BASE; // Needed whenever we do a call to MK_FP_WINDOW.\r
- return 0;\r
- }\r
-\r
- if ((offset + len) > RSIZE[s])\r
- {\r
- size = (u_int)(RSIZE[s] - offset);\r
-\r
- if (size > TERN_RDMA_THRES)\r
- {\r
- dma_read_i2chip(src, dst, size);\r
- }\r
- else\r
- {\r
- for (i = 0; i < size; i++)\r
- {\r
- *dst++ = READ_VALUE(src);\r
- WINDOW_PTR_INC(src);\r
-\r
- }\r
- }\r
-\r
- size1 = len - size;\r
- src = (u_char far *)(MK_FP_WINDOW(RECV_DATA_BUF, (RBUFBASEADDRESS[s])));\r
-\r
- if (size1 > TERN_RDMA_THRES)\r
- {\r
- dma_read_i2chip(src, dst, size);\r
- }\r
- else\r
- {\r
- for (i = 0; i < size1; i++)\r
- {\r
- *dst++ = READ_VALUE(src);\r
- WINDOW_PTR_INC(src);\r
- }\r
- }\r
- }\r
- else\r
- {\r
- if (len > TERN_RDMA_THRES)\r
- {\r
- dma_read_i2chip(src, dst, size);\r
- }\r
- else\r
- {\r
- for (i = 0; i < len; i++)\r
- {\r
- *dst++ = READ_VALUE(src);\r
- WINDOW_PTR_INC(src);\r
- }\r
- }\r
- }\r
- WINDOW_RESTORE_BASE; // Needed whenever we do a call to MK_FP_WINDOW.\r
- return len;\r
-}\r
-\r
-\r
-/*\r
-****************************************************************************************************\r
-* Copies the system buffer data to the transmit buffer of the W3100A.\r
-*\r
-* Description : Copies the system buffer data to the transmit buffer of the W3100A.\r
-* It is called from the send_in()or sendto_in() function.\r
-* Arguments : s - channel number\r
-* src - system buffer pointer\r
-* dst - send buffer pointer of W3100A\r
-* len - data size to copy\r
-* Returns : copied data size\r
-* Note : Internal Function\r
-****************************************************************************************************\r
-*/\r
-u_int write_data(SOCKET s, u_char far * src, u_int offset, u_int len)\r
-{\r
- u_int i, size, size1;\r
- u_char far* dst = (u_char far*)MK_FP_WINDOW(SEND_DATA_BUF,\r
- SBUFBASEADDRESS[s] + offset);\r
-\r
- if (len == 0)\r
- {\r
- WINDOW_RESTORE_BASE; // Needed whenever we do a call to MK_FP_WINDOW.\r
- return 0;\r
- }\r
-\r
- if ((offset + len) > SSIZE[s])\r
- {\r
- size = (u_int)(SSIZE[s] - offset);\r
-\r
- for (i = 0; i < size; i++)\r
- {\r
- WRITE_VALUE(dst, *src++);\r
- WINDOW_PTR_INC(dst);\r
- }\r
-\r
- size1 = len - size;\r
- dst = (u_char far *)(MK_FP_WINDOW(SEND_DATA_BUF, (SBUFBASEADDRESS[s])));\r
-\r
- for (i = 0; i < size1; i++)\r
- {\r
- WRITE_VALUE(dst, *src++);\r
- WINDOW_PTR_INC(dst);\r
- }\r
- }\r
- else\r
- {\r
- for (i = 0; i < len; i++)\r
- {\r
- WRITE_VALUE(dst, *src++);\r
- WINDOW_PTR_INC(dst);\r
- }\r
- }\r
- WINDOW_RESTORE_BASE; // Needed whenever we do a call to MK_FP_WINDOW.\r
- return len;\r
-}\r
-\r
-\r
-\r