socket.c

来自「W3100A网络调试程序,可进行数据传输」· C语言 代码 · 共 876 行 · 第 1/2 页

C
876
字号
/*
###############################################################################
File Include Section
###############################################################################
*/
#include "socket_inc.h"
/*
###############################################################################
Define Part
###############################################################################
*/
//#ifndef _LITTLE_ENDIAN_
//#define DEBUG                        // Add debugging code
/*
###############################################################################
Local Variable Declaration Section
###############################################################################
*/
unsigned int xdata Local_Port;                // Designate Local Port
unsigned int xdata SMASK[MAX_SOCK_NUM];      // Variable to store MASK of Tx in each channel, on setting dynamic memory size.
unsigned int xdata RMASK[MAX_SOCK_NUM];      // Variable to store MASK of Rx in each channel, on setting dynamic memory size.
unsigned int xdata SSIZE[MAX_SOCK_NUM];         // Maximun Tx memory size by each channel
unsigned int xdata RSIZE[MAX_SOCK_NUM];         // Maximun Rx memory size by each channel
unsigned char xdata* SBUFBASEADDRESS[MAX_SOCK_NUM];     // Maximun Tx memory base address by each channel
unsigned char xdata* RBUFBASEADDRESS[MAX_SOCK_NUM];     // Maximun Rx memory base address by each channel

/*
###############################################################################
Function Implementation Section
###############################################################################
*/

void Int0(void) interrupt 0
{
	EX0 = 0;                      	  // INT0 DISABLE
	EX0 = 1;
}

void iinchip_init(void)
{
    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
	*((volatile unsigned char xdata*)(TMODE)) = TMODE_SWRESET;
}

void sysinit(unsigned char sbufsize, unsigned char rbufsize)
{
	unsigned char i;
	unsigned int ssum,rsum;

	IINCHIP_WRITE(TX_DMEM_SIZE, sbufsize); // Set Tx memory size for each channel
	IINCHIP_WRITE(RX_DMEM_SIZE, rbufsize); // Set Rx memory size for each channel

	ssum = 0;
	rsum = 0;
	SBUFBASEADDRESS[0] = SEND_DATA_BUF;      // Set Base Address of Tx memory for channel #0
	RBUFBASEADDRESS[0] = RECV_DATA_BUF;      // Set Base Address of Rx memory for channel #0

	for(i = 0 ; i < MAX_SOCK_NUM; i++)               // Set maximum memory size for Tx and Rx, mask, base address of memory by each channel
	{
		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] = 0x03FF;
				break;
			case 1:
				SSIZE[i] = 2048;
				SMASK[i] = 0x07FF;
				break;
			case 2:
				SSIZE[i] = 4096;
				SMASK[i] = 0x0FFF;
				break;
			default:
				SSIZE[i] = 8192;
				SMASK[i] = 0x1FFF;
				break;
			}
		}
		if(rsum < 8192)
		{
			switch((rbufsize>> i*2) & 0x03)  // Set maximum 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;
			default:
				RSIZE[i] = 8192;
				RMASK[i] = 0x1FFF;
				break;
			}
		}
		ssum += SSIZE[i];
		rsum += RSIZE[i];
		if(i != 0) // Set base address of Tx and Rx memory for channel #1,#2,#3
		{
			SBUFBASEADDRESS[i] = SBUFBASEADDRESS[i-1] + SSIZE[i-1];
			RBUFBASEADDRESS[i] = RBUFBASEADDRESS[i-1] + RSIZE[i-1];
		}
#ifdef DEBUG
		printf("%bd : %d %d", i, SSIZE[i], RSIZE[i]);
#endif
	}
	wait_1us(1);
}

void setgateway(unsigned char * addr)
{
	unsigned char i;

	for (i = 0; i < 4; i++) {
		IINCHIP_WRITE((GATEWAY_PTR + i), addr[i]);
	}
}

void setsubmask(unsigned char * addr)
{
	unsigned char i;

	for (i = 0; i < 4; i++) {
		IINCHIP_WRITE((SUBNET_MASK_PTR + i), addr[i]);
	}
}

void setMACAddr(unsigned char * addr)
{
	unsigned char i;

	for (i = 0; i < 6; i++) {
		IINCHIP_WRITE((SRC_HA_PTR + i), addr[i]);
	}
}

void setIP(unsigned char * addr)
{
	unsigned char i;

	for (i = 0; i < 4; i++) {
		IINCHIP_WRITE((SRC_IP_PTR + i), addr[i]);
	}
}

/*---------------*/
#ifdef __IP_RAW__
void setIPprotocol(unsigned char s, unsigned char ipprotocol)
{
	IINCHIP_WRITE(IP_PROTOCOL(s), ipprotocol);
}
#endif

/*---------------*/
#ifdef	__OPT__
void setINTMask(unsigned char mask)
{
	IINCHIP_WRITE(INTMASK, mask);
}

void settimeout(unsigned char * val)
{
	unsigned char i;
	for (i = 0; i < 3; i++) {
		IINCHIP_WRITE((TIMEOUT_PTR + i), val[i]);
	}
}

void getDestAddr(unsigned char ch, unsigned char * addr)
{
	addr[0] = IINCHIP_READ(DST_IP_PTR(ch));
	addr[1] = IINCHIP_READ(DST_IP_PTR(ch)+1);
	addr[2] = IINCHIP_READ(DST_IP_PTR(ch)+2);
	addr[3] = IINCHIP_READ(DST_IP_PTR(ch)+3);
}

void Send_KeepalivePacket(unsigned char s)
{
	IINCHIP_WRITE(COMMAND(s),CSENDKEEPALIVE);			/* SEND command */	
}

#endif

/*---------------*/
#ifdef _DEF_IINCHIP_PPP
void getLocalAddr(unsigned char * addr)
{
	addr[0] = IINCHIP_READ(SRC_IP_PTR);
	addr[1] = IINCHIP_READ(SRC_IP_PTR+1);
	addr[2] = IINCHIP_READ(SRC_IP_PTR+2);
	addr[3] = IINCHIP_READ(SRC_IP_PTR+3);
}
void getDestMAC(unsigned char ch, unsigned char * addr)
{
	addr[0] = IINCHIP_READ(DST_HA_PTR(ch));
	addr[1] = IINCHIP_READ(DST_HA_PTR(ch)+1);
	addr[2] = IINCHIP_READ(DST_HA_PTR(ch)+2);
	addr[3] = IINCHIP_READ(DST_HA_PTR(ch)+3);
	addr[4] = IINCHIP_READ(DST_HA_PTR(ch)+4);
	addr[5] = IINCHIP_READ(DST_HA_PTR(ch)+5);
}
unsigned int getDestPort(unsigned char ch)
{
	unsigned int ret;
#ifndef _LITTLE_ENDIAN_
	ret = IINCHIP_READ(DST_PORT_PTR(ch));
	ret = (ret << 8) + IINCHIP_READ(DST_PORT_PTR(ch) + 1);
#else
	ret = IINCHIP_READ(DST_PORT_PTR(ch)+1);
	ret = (ret << 8) + IINCHIP_READ(DST_PORT_PTR(ch));
#endif
	return ret;
}
#endif
/*---------------*/

unsigned int select(unsigned char s, unsigned char func)
{
	unsigned int val;

	switch (func)
	{
	case SEL_CONTROL :
		val = (unsigned int)IINCHIP_READ(SOCK_STATUS(s));
		break;
	case SEL_SEND :
#ifndef _LITTLE_ENDIAN_
		val = IINCHIP_READ(TX_FREE_SIZE_PTR(s));
		val = (val << 8) + IINCHIP_READ(TX_FREE_SIZE_PTR(s) + 1);
#else
		val = IINCHIP_READ(TX_FREE_SIZE_PTR(s)+1);
		val = (val << 8) + IINCHIP_READ(TX_FREE_SIZE_PTR(s));
#endif
		break;
	case SEL_RECV :
#ifndef _LITTLE_ENDIAN_
		val = IINCHIP_READ(RX_RECV_SIZE_PTR(s));
		val = (val << 8) + IINCHIP_READ(RX_RECV_SIZE_PTR(s) + 1);
#else
		val = IINCHIP_READ(RX_RECV_SIZE_PTR(s)+1);
		val = (val << 8) + IINCHIP_READ(RX_RECV_SIZE_PTR(s));
#endif
		break;
	default :
		val = 0;
		break;
	}
	return val;
}

/**
* return : 
*		1 => success
*		0 => fail
*/
unsigned char socket(unsigned char s, unsigned char protocol, unsigned int port, unsigned char flag)
{
	unsigned char ret;
	if ((protocol == SOCK_STREAM) || (protocol == SOCK_DGRAM) || (protocol == SOCK_ICMPM) || (protocol == SOCK_IPL_RAWM) || (protocol == SOCK_MACL_RAWM) || (protocol == SOCK_PPPOEM))
	{
		// 1. first, CLOSE
		IINCHIP_WRITE(COMMAND(s),CCLOSE);
		// 2. write protocol
		IINCHIP_WRITE(OPT_PROTOCOL(s),protocol | flag);
		// 3. write Port number
		if (port != 0) {
#ifndef _LITTLE_ENDIAN_
			IINCHIP_WRITE(SRC_PORT_PTR(s),(unsigned char)((port & 0xff00) >> 8));
			IINCHIP_WRITE((SRC_PORT_PTR(s) + 1),(unsigned char)(port & 0x00ff));
#else
			IINCHIP_WRITE((SRC_PORT_PTR(s)+1),(unsigned char)((port & 0xff00) >> 8));
			IINCHIP_WRITE(SRC_PORT_PTR(s),(unsigned char)(port & 0x00ff));
#endif
		} else {
			Local_Port++; // if don't set the source port, set Local_Port number.
#ifndef _LITTLE_ENDIAN_
			IINCHIP_WRITE(SRC_PORT_PTR(s),(unsigned char)((Local_Port & 0xff00) >> 8));
			IINCHIP_WRITE((SRC_PORT_PTR(s) + 1),(unsigned char)(Local_Port & 0x00ff));
#else
			IINCHIP_WRITE((SRC_PORT_PTR(s)+1),(unsigned char)((Local_Port & 0xff00) >> 8));
			IINCHIP_WRITE(SRC_PORT_PTR(s),(unsigned char)(Local_Port & 0x00ff));
#endif
		}
		// 4. write SOCK_INIT commnad
		IINCHIP_WRITE(COMMAND(s),CSOCKINIT);
		ret = 1;
	}
	else
	{
		ret = 0;
	}
	return ret;
}

void close(unsigned char s)
{
	IINCHIP_WRITE(COMMAND(s),CCLOSE);
}

/*---------------*/
#ifdef	__TCP_SERVER__
void NBlisten(unsigned char s)
{
	IINCHIP_WRITE(COMMAND(s),CLISTEN);
}
#endif


/*---------------*/
#ifdef	__TCP_CLIENT__
/**
* return : 
*		1 => success
*		0 => fail
*/
unsigned char connect(unsigned char s, unsigned char * addr, unsigned int port)
{
	unsigned char ret;
	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) 
		) 
 	{
 		ret = 0;
	}
	else
	{
		// 1. write destination IP
		IINCHIP_WRITE(DST_IP_PTR(s),addr[0]);
		IINCHIP_WRITE((DST_IP_PTR(s) + 1),addr[1]);
		IINCHIP_WRITE((DST_IP_PTR(s) + 2),addr[2]);
		IINCHIP_WRITE((DST_IP_PTR(s) + 3),addr[3]);
		// 2. write destination Port number
#ifndef _LITTLE_ENDIAN_
		IINCHIP_WRITE(DST_PORT_PTR(s),(unsigned char)((port & 0xff00) >> 8));
		IINCHIP_WRITE((DST_PORT_PTR(s) + 1),(unsigned char)(port & 0x00ff));
#else
		IINCHIP_WRITE((DST_PORT_PTR(s)+1),(unsigned char)((port & 0xff00) >> 8));
		IINCHIP_WRITE(DST_PORT_PTR(s),(unsigned char)(port & 0x00ff));
#endif
		// 3. write CONNECT command
		IINCHIP_WRITE(COMMAND(s),CCONNECT);
		ret = 1;
	}

	// blocking mode, if you want to change non-blocking mode, comment these section.
	/*----*/
	while (1)
	{
		switch (IINCHIP_READ(SOCK_STATUS(s)))
		{
			case SOCK_ESTABLISHED : return 1;
			case SOCK_CLOSED : return -1;
			default :
				break;
		}
		wait_1us(1);
	}
	/*----*/
}
#endif

/*---------------*/
#ifdef	__TCP__
void disconnect(unsigned char s)
{
	IINCHIP_WRITE(COMMAND(s),CDISCONNECT);
}


/**
* return
*		n => count of sending data
*		0 => fail to send
*/
unsigned int send(unsigned char s, const unsigned char *buf, unsigned int len)
{
	unsigned int ret, size;
	ret = 0;
	while (len > 0)
	{
		size = send_in(s, buf + ret, len, 0x00);
		if (size == 0) return 0;
		len -= size;
		ret += size;
	}
	return ret;
}

/**
* return
*		n => count of receving data
* attention
* 		len => 捞固 捞窃荐 龋免傈俊 罐篮 荤捞令甫 备秦 弊蔼 捞窍狼 蔼阑 持绢林绢具 茄促.
*				捞犯霸 窍瘤 臼扁 困秦辑绰, 窃荐救俊辑 促矫 荐脚荤捞令甫 眉农窍绰 内靛啊 眠啊登绢具 茄促.
*/
unsigned int recv(unsigned char s, const unsigned char * buf, unsigned int len)
{
	unsigned int rd_ptr;
	unsigned int ret;
	if ( len > 0 )
	{
		// 1. get current rd_prt
#ifndef _LITTLE_ENDIAN_
		rd_ptr = IINCHIP_READ(RX_RD_PTR(s));
		rd_ptr = ((rd_ptr & 0x00ff) << 8) + IINCHIP_READ(RX_RD_PTR(s) + 1);
#else
		rd_ptr = IINCHIP_READ(RX_RD_PTR(s)+1);
		rd_ptr = ((rd_ptr & 0x00ff) << 8) + IINCHIP_READ(RX_RD_PTR(s));
#endif
		// 2. copy data as len
		ret = read_data(s, (unsigned char *)rd_ptr, buf, len);
		// 3. update rd_ptr
		rd_ptr = rd_ptr + len;
#ifndef _LITTLE_ENDIAN_
		IINCHIP_WRITE(RX_RD_PTR(s),(unsigned char)((rd_ptr & 0xff00) >> 8));
		IINCHIP_WRITE((RX_RD_PTR(s) + 1),(unsigned char)(rd_ptr & 0x00ff));
#else
		IINCHIP_WRITE((RX_RD_PTR(s)+1),(unsigned char)((rd_ptr & 0xff00) >> 8));
		IINCHIP_WRITE(RX_RD_PTR(s),(unsigned char)(rd_ptr & 0x00ff));
#endif
		// 4. write RECV command
		IINCHIP_WRITE(COMMAND(s),CRECV);
	}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?