using System; //using System.IO.Ports; //using System.Runtime.CompilerServices; using System.Threading; using Microsoft.SPOT; using Microsoft.SPOT.Hardware; using GHIElectronics.NETMF.Hardware; namespace GHIElectronics.NETMF.FEZ { public static partial class FEZ_Shields { static public class Ethernet { static public void Initialize(byte[] SourceIP, byte[] SubnetMask, byte[] Gateway, byte[] MAC) { W5100.Init(0x55, 0x55); W5100.SetMAC(MAC); W5100.SetGateway(Gateway); W5100.SetSourceIP(SourceIP); W5100.SetSubnetMask(SubnetMask); } public class uSocket : IDisposable { private enum IR_val { /* Sn_IR values */ Sn_IR_SEND_OK = 0x10, /**< complete sending */ Sn_IR_TIMEOUT = 0x08, /**< assert timeout */ Sn_IR_RECV = 0x04, /**< receiving data */ Sn_IR_DISCON = 0x02, /**< closed socket */ Sn_IR_CON = 0x01, /**< established connection */ } private enum SR_val { /* Sn_SR values */ SOCK_CLOSED = 0x00, /**< closed */ SOCK_INIT = 0x13, /**< init state */ SOCK_LISTEN = 0x14, /**< listen state */ SOCK_SYNSENT = 0x15, /**< connection state */ SOCK_SYNRECV = 0x16, /**< connection state */ SOCK_ESTABLISHED = 0x17, /**< success to connect */ SOCK_FIN_WAIT = 0x18, /**< closing state */ SOCK_CLOSING = 0x1A, /**< closing state */ SOCK_TIME_WAIT = 0x1B, /**< closing state */ SOCK_CLOSE_WAIT = 0x1C, /**< closing state */ SOCK_LAST_ACK = 0x1D, /**< closing state */ SOCK_UDP = 0x22, /**< udp socket */ SOCK_IPRAW = 0x32, /**< ip raw mode socket */ SOCK_MACRAW = 0x42, /**< mac raw mode socket */ SOCK_PPPOE = 0x5F, /**< pppoe socket */ } private enum CR_val { Sn_CR_OPEN = 0x01, /**< initialize or open socket */ Sn_CR_LISTEN = 0x02, /**< wait connection request in tcp mode(Server mode) */ Sn_CR_CONNECT = 0x04, /**< send connection request in tcp mode(Client mode) */ Sn_CR_DISCON = 0x08, /**< send closing reqeuset in tcp mode */ Sn_CR_CLOSE = 0x10, /**< close socket */ Sn_CR_SEND = 0x20, /**< updata txbuf pointer, send data */ Sn_CR_SEND_MAC = 0x21, /**< send data with MAC address, so without ARP process */ Sn_CR_SEND_KEEP = 0x22, /**< send keep alive message */ Sn_CR_RECV = 0x40, /**< update rxbuf pointer, recv data */ } public enum Protocol { //Sn_MR_CLOSE = 0x00, /**< unused socket */ TCP = 0x01, /**< TCP */ UDP = 0x02, /**< UDP */ IPRAW = 0x03, MACRAW = 0x04, /*Sn_MR_PPPOE = 0x05, Sn_MR_ND = 0x20, Sn_MR_MULTI = 0x80, */ } static private bool[] SocketIsUsed = new bool[4] { false, false, false, false }; private byte _scoket_number = 100; static int local_port = 50000; /// /// This Socket function initialize the channel in perticular mode, and set the port and wait for W5100 done it. /// /// for socket number /// for socket protocol /// the source port for the socket /// the option for the socket public uSocket(Protocol protocol, UInt16 port) { byte s; for (s = 0; s < 4; s++) { if (SocketIsUsed[s] == false) break; } if (s == 4) throw new Exception("No free sockets"); if ((protocol == Protocol.TCP) || (protocol == Protocol.UDP) || (protocol == Protocol.IPRAW) || (protocol == Protocol.MACRAW)) { _scoket_number = s; this.Close(); W5100.RegisterWrite(s, W5100.SocketRegisters.MR, (byte)protocol);//| flag)); if (port != 0) { W5100.RegisterWrite(s, W5100.SocketRegisters.PORT0, (byte)((port & 0xff00) >> 8)); W5100.RegisterWrite(s, W5100.SocketRegisters.PORT0 + 1, (byte)(port & 0x00ff)); } else { local_port++; // if don't set the source port, set local_port number. W5100.RegisterWrite(s, W5100.SocketRegisters.PORT0, (byte)((local_port & 0xff00) >> 8)); W5100.RegisterWrite(s, W5100.SocketRegisters.PORT0 + 1, (byte)(local_port & 0x00ff)); } W5100.RegisterWrite(s, W5100.SocketRegisters.CR, (byte)CR_val.Sn_CR_OPEN); // run sockinit Sn_CR while (W5100.RegisterRead(s, W5100.SocketRegisters.CR) != 0) ; _scoket_number = s; SocketIsUsed[s] = true; } else { throw new Exception("Unknown protocol"); } //Debug.Print("Sn_SR = " + W5100.RegisterRead(s, W5100.SocketRegisters.SR).ToString() + " Protocol = " + W5100.RegisterRead(s, W5100.SocketRegisters.MR).ToString()); } /// /// This function close the socket /// public void Dispose() { Close(); } public void Close() { byte s = _scoket_number; W5100.RegisterWrite(s, W5100.SocketRegisters.CR, (byte)CR_val.Sn_CR_CLOSE); while (W5100.RegisterRead(s, W5100.SocketRegisters.CR) != 0) Thread.Sleep(1); W5100.RegisterWrite(s, W5100.SocketRegisters.IR, 0xFF); SocketIsUsed[_scoket_number] = false; } /// /// This function established the connection for the channel in passive (server) mode. This function waits for the request from the peer. /// public bool Listen() { byte s = _scoket_number; if (W5100.RegisterRead(s, W5100.SocketRegisters.SR) == (byte)SR_val.SOCK_INIT) { W5100.RegisterWrite(s, W5100.SocketRegisters.CR, (byte)CR_val.Sn_CR_LISTEN); while (W5100.RegisterRead(s, W5100.SocketRegisters.CR) != 0) ; return true; } else { return false; //new Exception("Fail[invalid ip,port]\r\n"); } } /// /// This function established the connection for the channel in Active (client) mode. /// This function waits for the untill the connection is established. /// /// Destination IP address /// Destination Port public void Connect(byte[] addr, UInt16 port) { byte s = _scoket_number; if ( ((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) || ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) || (port == 0x00)) { throw new Exception("Fail[invalid ip,port]\r\n"); } else { // set destination IP W5100.RegisterWrite(s, W5100.SocketRegisters.DIPR0, addr[0]); W5100.RegisterWrite(s, (W5100.SocketRegisters.DIPR0 + 1), addr[1]); W5100.RegisterWrite(s, (W5100.SocketRegisters.DIPR0 + 2), addr[2]); W5100.RegisterWrite(s, (W5100.SocketRegisters.DIPR0 + 3), addr[3]); W5100.RegisterWrite(s, W5100.SocketRegisters.DPORT0, (byte)((port & 0xff00) >> 8)); W5100.RegisterWrite(s, (W5100.SocketRegisters.DPORT0 + 1), (byte)(port & 0x00ff)); W5100.RegisterWrite(s, W5100.SocketRegisters.CR, (byte)CR_val.Sn_CR_CONNECT); while (W5100.RegisterRead(s, W5100.SocketRegisters.CR) != 0) ; while (W5100.RegisterRead(s, W5100.SocketRegisters.SR) != (byte)SR_val.SOCK_ESTABLISHED) ; } } /// /// This function used for disconnect the socket /// public void Disconnect() { byte s = _scoket_number; W5100.RegisterWrite(s, W5100.SocketRegisters.CR, (byte)CR_val.Sn_CR_DISCON); while (W5100.RegisterRead(s, W5100.SocketRegisters.CR) != 0) ; } /// /// This function used to send the data in TCP mode /// /// a pointer to data /// the data size to be send /// returns 1 if succeeded public int Send(byte[] buf, int len) { byte s = _scoket_number; byte status = 0; int freesize = 0; int ret; if (len > W5100.GetTxMAX(s)) ret = W5100.GetTxMAX(s); // check size not to exceed MAX size. else ret = len; // if freebuf is available, start. do { freesize = W5100.Get_TX_FSR(s); status = W5100.RegisterRead(s, W5100.SocketRegisters.SR); if ((status != (byte)SR_val.SOCK_ESTABLISHED) && (status != (byte)SR_val.SOCK_CLOSE_WAIT)) { ret = 0; break; } Debug.Print("socket " + s.ToString() + " freesize(" + freesize.ToString() + " empty or error"); } while (freesize < ret); // copy data W5100.SendDataProc(s, buf, ret); W5100.RegisterWrite(s, W5100.SocketRegisters.CR, (byte)CR_val.Sn_CR_SEND); /* +20071122[chungs]:wait to process the command... */ while (W5100.RegisterRead(s, W5100.SocketRegisters.CR) != 0) ; while ((W5100.RegisterRead(s, W5100.SocketRegisters.IR) & (byte)IR_val.Sn_IR_SEND_OK) != (byte)IR_val.Sn_IR_SEND_OK) { /* m2008.01 [bj] : reduce code */ if (W5100.RegisterRead(s, W5100.SocketRegisters.SR) == (byte)SR_val.SOCK_CLOSED) { throw new Exception("Socket is closed"); //Debug.Print("SOCK_CLOSED.\r\n"); Close(); return 0; } } W5100.RegisterWrite(s, W5100.SocketRegisters.IR, (byte)IR_val.Sn_IR_SEND_OK); return ret; } public int AvilableBytes { get { return W5100.getSn_RX_RSR(_scoket_number); } } /// /// This function is an application I/F function which is used to receive the data in TCP mode. /// It continues to wait for data as much as the application wants to receive. /// /// a pointer to copy the data to be received /// the data size to be read /// received data size for success else -1. public int Receive(byte[] buf, int len) { byte s = _scoket_number; int ret = 0; if (len > 0) { W5100.RecvDataProc(s, buf, len); W5100.RegisterWrite(s, W5100.SocketRegisters.CR, (byte)CR_val.Sn_CR_RECV); /* +20071122[chungs]:wait to process the command... */ while (W5100.RegisterRead(s, W5100.SocketRegisters.CR) != 0) ; /* ------- */ ret = len; } return ret; } /// /// This function is an application I/F function which is used to send the data for other then TCP mode. /// Unlike TCP transmission, The peer's destination address and the port is needed. /// /// a pointer to the data /// the data size to send /// the peer's Destination IP address /// the peer's destination port number /// This function return send data size for success else -1 public int SendTo(byte[] buf, int len, byte[] addr, UInt16 port) { // uint8 status=0; // uint8 isr=0; byte s = _scoket_number; int ret = 0; if (len > W5100.GetTxMAX(s)) ret = W5100.GetTxMAX(s); // check size not to exceed MAX size. else ret = len; if (((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) || ((port == 0x00)) || (len == 0)) { /* +2008.01 [bj] : added return value */ //#ifdef __DEF_IINCHIP_DBG__ // printf("%d Fail[%.2x.%.2x.%.2x.%.2x, %.d, %d]\r\n",s, addr[0], addr[1], addr[2], addr[3] , port, len); throw new Exception("Invalid ip, port"); //#endif } else { W5100.RegisterWrite(s, W5100.SocketRegisters.DIPR0, addr[0]); W5100.RegisterWrite(s, (W5100.SocketRegisters.DIPR0 + 1), addr[1]); W5100.RegisterWrite(s, (W5100.SocketRegisters.DIPR0 + 2), addr[2]); W5100.RegisterWrite(s, (W5100.SocketRegisters.DIPR0 + 3), addr[3]); W5100.RegisterWrite(s, W5100.SocketRegisters.DPORT0, (byte)((port & 0xff00) >> 8)); W5100.RegisterWrite(s, (W5100.SocketRegisters.DPORT0 + 1), (byte)(port & 0x00ff)); // copy data W5100.SendDataProc(s, buf, ret); W5100.RegisterWrite(s, W5100.SocketRegisters.CR, (byte)CR_val.Sn_CR_SEND); while (W5100.RegisterRead(s, W5100.SocketRegisters.CR) != 0) ; while ((W5100.RegisterRead(s, W5100.SocketRegisters.IR) & (byte)IR_val.Sn_IR_SEND_OK) != (byte)IR_val.Sn_IR_SEND_OK) { if ((W5100.RegisterRead(s, W5100.SocketRegisters.IR) & (byte)IR_val.Sn_IR_TIMEOUT) != 0) { throw new Exception("Send fail"); W5100.RegisterWrite(s, W5100.SocketRegisters.IR, (byte)(IR_val.Sn_IR_SEND_OK | IR_val.Sn_IR_TIMEOUT)); /* clear SEND_OK & TIMEOUT */ return 0; } } W5100.RegisterWrite(s, W5100.SocketRegisters.IR, (byte)IR_val.Sn_IR_SEND_OK); } return ret; } private byte[] head = new byte[8]; /// /// This function is an application I/F function which is used to receive the data in other then /// TCP mode. This function is used to receive UDP, IP_RAW and MAC_RAW mode, and handle the header as well. /// /// a pointer to the copy data to be received /// the data size to read /// a pointer to store the peer's IP address /// a pointer to store the peer's port number. /// received data size for success else -1 public int RecvFrom(byte[] buf, int len, byte[] addr, ref UInt16 port) { byte s = _scoket_number; int data_len = 0; int ptr = 0; if (len > 0) { ptr = W5100.RegisterRead(s, W5100.SocketRegisters.RX_RD0); ptr = ((ptr & 0x00ff) << 8) + W5100.RegisterRead(s, W5100.SocketRegisters.RX_RD0 + 1); switch (W5100.RegisterRead(s, W5100.SocketRegisters.MR) & 0x07) { case (int)Protocol.UDP: W5100.ReadData(s, ptr, head, 0x08); ptr += 8; // read peer's IP address, port number. addr[0] = head[0]; addr[1] = head[1]; addr[2] = head[2]; addr[3] = head[3]; port = head[4]; port = (UInt16)((port << 8) | head[5]); data_len = head[6]; data_len = (data_len << 8) + head[7]; //Debug.Print("UDP msg arrived\r\n"); W5100.ReadData(s, ptr, buf, data_len); // data copy. ptr += data_len; W5100.RegisterWrite(s, W5100.SocketRegisters.RX_RD0, (byte)((ptr & 0xff00) >> 8)); W5100.RegisterWrite(s, (W5100.SocketRegisters.RX_RD0 + 1), (byte)(ptr & 0x00ff)); break; case (int)Protocol.IPRAW: W5100.ReadData(s, ptr, head, 0x06); ptr += 6; addr[0] = head[0]; addr[1] = head[1]; addr[2] = head[2]; addr[3] = head[3]; data_len = head[4]; data_len = (data_len << 8) + head[5]; //Debug.Print("IP RAW msg arrived\r\n"); W5100.ReadData(s, ptr, buf, data_len); // data copy. ptr += data_len; W5100.RegisterWrite(s, W5100.SocketRegisters.RX_RD0, (byte)((ptr & 0xff00) >> 8)); W5100.RegisterWrite(s, (W5100.SocketRegisters.RX_RD0 + 1), (byte)(ptr & 0x00ff)); break; case (int)Protocol.MACRAW: W5100.ReadData(s, ptr, head, 2); ptr += 2; data_len = head[0]; data_len = (data_len << 8) + head[1] - 2; W5100.ReadData(s, ptr, buf, data_len); ptr += data_len; W5100.RegisterWrite(s, W5100.SocketRegisters.RX_RD0, (byte)((ptr & 0xff00) >> 8)); W5100.RegisterWrite(s, (W5100.SocketRegisters.RX_RD0 + 1), (byte)(ptr & 0x00ff)); //Debug.Print("MAC RAW msg arrived\r\n"); break; default: break; } W5100.RegisterWrite(s, W5100.SocketRegisters.CR, (byte)CR_val.Sn_CR_RECV); while (W5100.RegisterRead(s, W5100.SocketRegisters.CR) != 0) ; } return data_len; } } } static private class W5100 { const int __DEF_IINCHIP_MAP_TXBUF__ = 0x4000; /* Internal Tx buffer address of the iinchip */ const int __DEF_IINCHIP_MAP_RXBUF__ = 0x6000; /* Internal Rx buffer address of the iinchip */ const int MAX_SOCK_NUM = 4; const int SOCKETS_BASE_ADDRESS = 0x400; const int SOCKET_REGISTER_MEMORY_SIZE = 0x100; static byte[] I_STATUS = new byte[MAX_SOCK_NUM]; static UInt16[] SMASK = new UInt16[MAX_SOCK_NUM]; /**< Variable for Tx buffer MASK in each channel */ static UInt16[] RMASK = new UInt16[MAX_SOCK_NUM]; /**< Variable for Rx buffer MASK in each channel */ static UInt16[] SSIZE = new UInt16[MAX_SOCK_NUM]; /**< Max Tx buffer size by each channel */ static UInt16[] RSIZE = new UInt16[MAX_SOCK_NUM]; /**< Max Rx buffer size by each channel */ static UInt16[] SBUFBASEADDRESS = new UInt16[MAX_SOCK_NUM]; /**< Tx buffer base address by each channel */ static UInt16[] RBUFBASEADDRESS = new UInt16[MAX_SOCK_NUM]; /**< Rx buffer base address by each channel */ private static SPI spi = null; //private static OutputPort CSpin = null; //private static OutputPort resetpin = null; //public const int TxMAX = (1024 * 2); public enum Registers { MR = 0x0000, GAR0 = 0x0001, SUBR0 = 0x0005, SHAR0 = 0x0009, SIPR0 = 0x000F, RMSR = 0x001a, TMSR = 0x001b, } public enum SocketRegisters { MR = 0x0000, CR = 0x0001, IR = 0x0002, SR = 0x0003, PORT0 = 0x0004, DIPR0 = 0x00C, DPORT0 = 0x0010, TX_FSR0 = 0x0020, TX_WR0 = 0x0024, RX_RSR0 = 0x0026, RX_RD0 = 0x0028, } static private byte[] ba = new byte[1]; static void SPIWriteByte(byte b) { ba[0] = b; spi.Write(ba); //return 1; } static private byte[] bo = new byte[1]; static private byte[] bi = new byte[1]; static byte SPIReadByte() { bo[0] = 0; spi.WriteRead(bo, bi); return bi[0]; } public static UInt16 GetTxMAX(byte s) { return SSIZE[s]; } public static UInt16 GetTxMASK(byte s) { return SMASK[s]; } public static UInt16 GetTxBASE(byte s) { return SBUFBASEADDRESS[s]; } public static UInt16 GetRxMAX(byte s) { return RSIZE[s]; } public static UInt16 GetRxMASK(byte s) { return RMASK[s]; } public static UInt16 GetRxBASE(byte s) { return RBUFBASEADDRESS[s]; } /// /// This function writes the data into W5100 registers. /// /// /// public static void RegisterWrite(Registers reg, byte data) { //tempbuf[0] = 0xF0; //tempbuf[1] = (byte)(((UInt16)reg & 0xFF00) >> 8); //tempbuf[2] = (byte)((UInt16)reg & 0x00FF); //tempbuf[3] = data; //spi.Write(tempbuf); SPIWriteByte(0xF0); SPIWriteByte((byte)(((UInt16)reg & 0xFF00) >> 8)); SPIWriteByte((byte)((UInt16)reg & 0x00FF)); SPIWriteByte(data); } /// /// This function writes the data into W5100 socket registers. /// /// socket number /// /// public static void RegisterWrite(byte socket, SocketRegisters reg, byte data) { int regaddr = SOCKETS_BASE_ADDRESS + socket * SOCKET_REGISTER_MEMORY_SIZE + (int)reg; RegisterWrite((Registers)regaddr, data); } /// /// This function reads the value from W5100 registers. /// /// /// public static byte RegisterRead(Registers reg) { byte data; SPIWriteByte(0x0F); SPIWriteByte((byte)(((UInt16)reg & 0xFF00) >> 8)); SPIWriteByte((byte)((UInt16)reg & 0x00FF)); data = SPIReadByte(); return data; } /// /// This function reads the value from W5100 Socket registers.. /// /// Socket Number /// /// public static byte RegisterRead(byte socket, SocketRegisters reg) { int regaddr = SOCKETS_BASE_ADDRESS + socket * SOCKET_REGISTER_MEMORY_SIZE + (int)reg; return RegisterRead((Registers)regaddr); } private static byte[] tempbuf = new byte[4]; public static int wizWriteBuf(UInt16 addr, byte[] buf, int len) { UInt16 idx = 0; //SPI MODE I/F for (idx = 0; idx < len; idx++) { tempbuf[0] = 0xF0; tempbuf[1] = (byte)(((addr + idx) & 0xFF00) >> 8); tempbuf[2] = (byte)((addr + idx) & 0x00FF); tempbuf[3] = buf[idx]; spi.Write(tempbuf); } return len; } private static byte[] rtempbuf = new byte[4]; public static int wiz_read_buf(UInt16 addr, byte[] buf, int len) { UInt16 idx = 0; //SPI MODE I/F for (idx = 0; idx < len; idx++) { SPIWriteByte(0x0F); SPIWriteByte((byte)(((UInt16)(addr + idx) & 0xFF00) >> 8)); SPIWriteByte((byte)((UInt16)(addr + idx) & 0x00FF)); buf[idx] = SPIReadByte(); //tempbuf[0] = 0xF0; //tempbuf[1] = (byte)(((UInt16)(addr + idx) & 0xFF00) >> 8); //tempbuf[2] = ((byte)((UInt16)(addr + idx) & 0x00FF)); //tempbuf[3] = 0; //spi.WriteRead(tempbuf, rtempbuf); ////spi.Write(rtempbuf); ////buf[idx] = rtempbuf[3]; //buf[idx] = SPIReadByte(); } return len; } /** @brief This function set the transmit & receive buffer size as per the channels is used Note for TMSR and RMSR bits are as follows\n bit 1-0 : memory size of channel #0 \n bit 3-2 : memory size of channel #1 \n bit 5-4 : memory size of channel #2 \n bit 7-6 : memory size of channel #3 \n\n Maximum memory size for Tx, Rx in the W5100 is 8K Bytes,\n In the range of 8KBytes, the memory size could be allocated dynamically by each channel.\n Be attentive to sum of memory size shouldn't exceed 8Kbytes\n and to data transmission and receiption from non-allocated channel may cause some problems.\n If the 8KBytes memory is already assigned to centain channel, \n other 3 channels couldn't be used, for there's no available memory.\n If two 4KBytes memory are assigned to two each channels, \n other 2 channels couldn't be used, for there's no available memory.\n */ /**< tx_size Tx memory size (00 - 1KByte, 01- 2KBtye, 10 - 4KByte, 11 - 8KByte) */ public static void Init( byte tx_size, byte rx_size) { UInt16 i; UInt16 ssum, rsum; SPI.Configuration config = new SPI.Configuration((Cpu.Pin)FEZ_Pin.Digital.Di10, false, 0, 0, false, true, 300, SPI.SPI_module.SPI1); spi = new SPI(config); //CSpin = new OutputPort((Cpu.Pin)43, true); //resetpin = new OutputPort((Cpu.Pin)37, true); //resetpin.Write(false); //Thread.Sleep(100); //resetpin.Write(true); //Thread.Sleep(100); //RegisterWrite(Registers.MR, 1);//soft reset ssum = 0; rsum = 0; RegisterWrite(Registers.TMSR, tx_size); /* Set Tx memory size for each channel */ byte b = RegisterRead(Registers.TMSR); RegisterWrite(Registers.RMSR, rx_size); /* Set Rx memory size for each channel */ SBUFBASEADDRESS[0] = (UInt16)(__DEF_IINCHIP_MAP_TXBUF__); /* Set base address of Tx memory for channel #0 */ RBUFBASEADDRESS[0] = (UInt16)(__DEF_IINCHIP_MAP_RXBUF__); /* Set base address of Rx memory for channel #0 */ for (i = 0; i < MAX_SOCK_NUM; i++) // Set the size, masking and base address of Tx & Rx memory by each channel { SSIZE[i] = 0; RSIZE[i] = 0; if (ssum < 8192) { switch ((tx_size >> i * 2) & 0x03) // Set Tx memory size { case 0: SSIZE[i] = 1024; SMASK[i] = 0x03FF; break; case 1: SSIZE[i] = 2048; SMASK[i] = 0x07FF; break; case 2: SSIZE[i] = 4096; SMASK[i] = 0x0FFF; break; case 3: SSIZE[i] = 8192; SMASK[i] = 0x1FFF; break; } } if (rsum < 8192) { switch ((rx_size >> i * 2) & 0x03) // Set Rx memory size { case 0: RSIZE[i] = 1024; RMASK[i] = 0x03FF; break; case 1: RSIZE[i] = 2048; RMASK[i] = 0x07FF; break; case 2: RSIZE[i] = 4096; RMASK[i] = 0x0FFF; break; case 3: RSIZE[i] = 8192; RMASK[i] = 0x1FFF; break; } } ssum += SSIZE[i]; rsum += RSIZE[i]; if (i != 0) // Sets base address of Tx and Rx memory for channel #1,#2,#3 { SBUFBASEADDRESS[i] = (UInt16)(SBUFBASEADDRESS[i - 1] + SSIZE[i - 1]); RBUFBASEADDRESS[i] = (UInt16)(RBUFBASEADDRESS[i - 1] + RSIZE[i - 1]); } // printf("%d : %.4x : %.4x : %.4x : %.4x\r\n", i, (uint16)SBUFBASEADDRESS[i], (uint16)RBUFBASEADDRESS[i], SSIZE[i], RSIZE[i]); } } public static void SetGateway(byte[] gw) { RegisterWrite((Registers.GAR0 + 0), gw[0]); RegisterWrite((Registers.GAR0 + 1), gw[1]); RegisterWrite((Registers.GAR0 + 2), gw[2]); RegisterWrite((Registers.GAR0 + 3), gw[3]); } public static void SetSubnetMask(byte[] sm) { RegisterWrite((Registers.SUBR0 + 0), sm[0]); RegisterWrite((Registers.SUBR0 + 1), sm[1]); RegisterWrite((Registers.SUBR0 + 2), sm[2]); RegisterWrite((Registers.SUBR0 + 3), sm[3]); } public static void SetMAC(byte [] mac) { RegisterWrite((Registers.SHAR0 + 0), mac[0]); RegisterWrite((Registers.SHAR0 + 1), mac[1]); RegisterWrite((Registers.SHAR0 + 2), mac[2]); RegisterWrite((Registers.SHAR0 + 3), mac[3]); RegisterWrite((Registers.SHAR0 + 4), mac[4]); RegisterWrite((Registers.SHAR0 + 5), mac[5]); } public static void SetSourceIP(byte [] ip) { RegisterWrite((Registers.SIPR0 + 0), ip[0]); RegisterWrite((Registers.SIPR0 + 1), ip[1]); RegisterWrite((Registers.SIPR0 + 2), ip[2]); RegisterWrite((Registers.SIPR0 + 3), ip[3]); } /// /// This gives free buffer size of transmit buffer. This is the data size that user can transmit. /// User shuold check this value first and control the size of transmitting data /// /// /// public static int Get_TX_FSR(Byte s) { int val = 0, val1 = 0; do { val1 = RegisterRead(s, SocketRegisters.TX_FSR0); val1 = (val1 << 8) + RegisterRead(s, SocketRegisters.TX_FSR0 + 1); if (val1 != 0) { val = RegisterRead(s, SocketRegisters.TX_FSR0); val = (val << 8) + RegisterRead(s, SocketRegisters.TX_FSR0 + 1); } } while (val != val1); return val; } /// /// This gives size of received data in receive buffer. /// /// /// public static int getSn_RX_RSR(Byte s) { int val = 0, val1 = 0; do { val1 = RegisterRead(s, SocketRegisters.RX_RSR0); val1 = (val1 << 8) + RegisterRead(s, SocketRegisters.RX_RSR0 + 1); if (val1 != 0) { val = RegisterRead(s, SocketRegisters.RX_RSR0); val = (val << 8) + RegisterRead(s, SocketRegisters.RX_RSR0 + 1); } } while (val != val1); return val; } /// /// This function is being called by send() and sendto() function also. /// This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer /// register. User should read upper byte first and lower byte later to get proper value. /// /// /// /// public static void SendDataProc(Byte s, byte[] data, int len) { int ptr; ptr = RegisterRead(s, SocketRegisters.TX_WR0); ptr = (UInt16)(((ptr & 0x00ff) << 8) + RegisterRead(s, SocketRegisters.TX_WR0 + 1)); WriteData(s, data, ptr, len); ptr += len; RegisterWrite(s, SocketRegisters.TX_WR0, (byte)((ptr & 0xff00) >> 8)); RegisterWrite(s, SocketRegisters.TX_WR0 + 1, (byte)(ptr & 0x00ff)); } public static int RecvDataProc(Byte s, byte[] data, int len) { int ptr; ptr = RegisterRead(s, SocketRegisters.RX_RD0); ptr = ((ptr & 0x00ff) << 8) + RegisterRead(s, SocketRegisters.RX_RD0 + 1); Debug.Print("ISR_RX: rd_ptr : " + ptr.ToString()); ReadData(s, ptr, data, len); // read data ptr += len; RegisterWrite(s, SocketRegisters.RX_RD0, (byte)((ptr & 0xff00) >> 8)); RegisterWrite(s, (SocketRegisters.RX_RD0 + 1), (byte)(ptr & 0x00ff)); return 0; } public static void WriteData(Byte s, byte[] src, int dst, int len) { UInt16 size; UInt16 dst_mask; UInt16 dst_ptr; byte[] src_temp = null; int index = 0; dst_mask = (UInt16)(dst & GetTxMASK(s)); dst_ptr = (UInt16)(GetTxBASE(s) + dst_mask); if (dst_mask + len > GetTxMAX(s)) { size = (UInt16)(((UInt16)GetTxMAX(s)) - dst_mask); wizWriteBuf((UInt16)dst_ptr, src, size); index = size; size = (UInt16)(len - size); dst_ptr = GetTxBASE(s); src_temp = new byte[size]; Array.Copy(src, index, src_temp, 0, size); wizWriteBuf((UInt16)dst_ptr, src_temp, size); } else { wizWriteBuf((UInt16)dst_ptr, src, len); } } public static void ReadData(byte s, int src, byte[] dst, int len) { UInt16 size; UInt16 src_mask; UInt16 src_ptr; byte[] dst_temp = null; int index = 0; src_mask = (UInt16)(src & GetRxMASK(s)); src_ptr = (UInt16)(GetRxBASE(s) + src_mask); if ((src_mask + len) > GetRxMAX(s)) { size = (UInt16)(GetRxMAX(s) - src_mask); wiz_read_buf((UInt16)src_ptr, dst, size); index = size; //dst += size; //while (true) ;//ofset pointer of array, use array copy? size = (UInt16)(len - size); dst_temp = new byte[size]; src_ptr = (GetRxBASE(s)); wiz_read_buf((UInt16)src_ptr, dst_temp, size); Array.Copy(dst_temp, 0, dst, index, size); } else { wiz_read_buf((UInt16)src_ptr, dst, len); } } } } }