⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socket.c

📁 W3100是WIZnet公司专门为以太网互联和嵌入式设备推出的硬件TCP/IP协议栈芯片
💻 C
📖 第 1 页 / 共 4 页
字号:
#endif
		rd_ptr.lVal += 6;								// Increment read pointer by 6, because already read as IP RAW header size
		recv_ptr = (u_char *)(RBUFBASEADDRESS[s] + (UINT)(rd_ptr.lVal & RMASK[s]));	// Calculate IP layer raw mode data pointer
		ret = read_data(s, recv_ptr, buf, UDPHeader.u.header.size);			// data copy.
		rd_ptr.lVal += (ret-4);
	} 
#endif	// end __IP_RAW__

	IndirectWriteBuf(RX_RD_PTR(s),(u_char*)&rd_ptr,4);					// Update rx_rd_ptr

#ifdef DEBUG
	EX0 = 0;
	k = IndirectReadByte(SHADOW_RXWR_PTR(s));
	wait_1us(2);
	IndirectReadBuf(RX_WR_PTR(s),(u_char*)&wr_ptr,4);

	k = IndirectReadByte(SHADOW_RXRD_PTR(s));
	wait_1us(2);
	IndirectReadBuf(RX_RD_PTR(s),(u_char*)&rd_ptr,4);
	EX0 = 1;

//	printf("%.8lx : %.8lx\r\n", wr_ptr.lVal, rd_ptr.lVal);
	PutLTOA(wr_ptr.lVal); PutString(" : ");PutLTOA(rd_ptr.lVal); PutStringLn("");
#endif


	IndirectWriteByte(COMMAND(s),CRECV);                                                                 // RECV
    return	(ret);	// Real received size return
}
#endif	// __UDP__

/*
********************************************************************************
*               Channel closing function.
*
* Description : Function for closing the connection of the designated channel.
* Arguments   : s - channel number
* Returns     : None
* Note        : API Function	       
********************************************************************************
*/
void close(SOCKET s)
{
	u_int len;

	if (select(s, SEL_CONTROL) == SOCK_CLOSED) return;	   // Already closed

	// When closing, if there's data which have not processed, Insert some source codes to handle this
	// Or before application call close(), handle those data first and call close() later.


	len = select(s, SEL_SEND);
	if (len == SSIZE[s])
	{
		I_STATUS[s] =0;
		IndirectWriteByte(COMMAND(s),CCLOSE);                               // CLOSE
		while(!(I_STATUS[s] & SCLOSED));
	}
}

/*
********************************************************************************
*               Function handling the channel socket information.
*
* Description : Return socket information of designated channel
* Arguments   : s    - channel number
*               func - SEL_CONTROL(0x00) -> return socket status 
*                      SEL_SEND(0x01)    -> return free transmit buffer size
*                      SEL_RECV(0x02)    -> return received data size
* Returns     : socket status or free transmit buffer size or received data size
* Note        : API Function
********************************************************************************
*/
u_int select(SOCKET s, u_char func)
{
	u_int val;
	un_l2cval rd_ptr, wr_ptr, ack_ptr;
	u_char k;

	EX0 = 0;
	switch (func) {
	case SEL_CONTROL :                                     // socket status information
		val = IndirectReadByte(SOCK_STATUS(s));
		break;

	case SEL_SEND :                                        // Calculate send free buffer size
		k = IndirectReadByte(SHADOW_TXWR_PTR(s));
		wait_1us(2);
		IndirectReadBuf(TX_WR_PTR(s),(u_char*)&wr_ptr,4);

		if( (IndirectReadByte(OPT_PROTOCOL(s)) & 0x07) != SOCK_STREAM)
		{
			k = IndirectReadByte(SHADOW_TXRD_PTR(s));
			wait_1us(2);
			IndirectReadBuf(TX_RD_PTR(s),(u_char*)&ack_ptr,4);
		}
		else
		{
			k = IndirectReadByte(SHADOW_TXACK_PTR(s));
			wait_1us(2);
			IndirectReadBuf(TX_ACK_PTR(s),(u_char*)&ack_ptr,4);
		}

		if (wr_ptr.lVal >= ack_ptr.lVal) val = SSIZE[s] - (wr_ptr.lVal - ack_ptr.lVal);
		else val = SSIZE[s] - (0 - ack_ptr.lVal + wr_ptr.lVal);
		break;
	case SEL_RECV :                                        // Calculate received data size	
		k = IndirectReadByte(SHADOW_RXWR_PTR(s));
		wait_1us(2);
		IndirectReadBuf(RX_WR_PTR(s),(u_char*)&wr_ptr,4);

		k = IndirectReadByte(SHADOW_RXRD_PTR(s));
		wait_1us(2);
		IndirectReadBuf(RX_RD_PTR(s),(u_char*)&rd_ptr,4);

		if (wr_ptr.lVal == rd_ptr.lVal){ val = 0;}
		else if (wr_ptr.lVal > rd_ptr.lVal) val = wr_ptr.lVal - rd_ptr.lVal;
		else val = 0 - rd_ptr.lVal + wr_ptr.lVal;
		
#ifdef DEBUG
		PutString("wr_ptr.lVal = ");PutLTOA(wr_ptr.lVal);PutString(" : rd_ptr.lVal = ");PutLTOA(rd_ptr.lVal);PutString(" : size = ");PutITOA(val);PutStringLn("");
#endif		
		break;
	default :
		val = -1;
		break;
	}
	EX0 = 1;
    return	( val );
}

/*
********************************************************************************
*               Copies the receive buffer data of the W3100A to the system buffer.
*
* Description : Copies the receive buffer data of the W3100A to the system buffer.
*    It is called from the recv()or recvfrom() function.
* Arguments   : s   - channel number
*               src - receive buffer pointer of W3100A
*               dst - system buffer pointer
*               len - data size to copy
* Returns     : copied data size
* Note        : Internal Function
********************************************************************************
*/
u_int read_data(SOCKET s, u_char xdata* src, u_char xdata* dst, u_int len)
{
	u_int size, size1;

	if (len == 0) return 0;

	if( (((u_int)src & RMASK[s]) + len)  > RSIZE[s] ) 
	{
		size = RSIZE[s] - ((u_int)src & RMASK[s]);
		IndirectReadBuf(src,dst,size);
		size1 = len - size;
		src =  RBUFBASEADDRESS[s];
		IndirectReadBuf(src,dst+size,size1);
	}
	else
		IndirectReadBuf(src,dst,len);
	return len;
}

/*
********************************************************************************
*               Copies the system buffer data to the transmit buffer of the W3100A.
*
* Description : Copies the system buffer data to the transmit buffer of the W3100A.
*               It is called from the send_in()or sendto_in() function.
* Arguments   : s   - channel number
*               src - system buffer pointer
*               dst - send buffer pointer of W3100A
*               len - data size to copy
* Returns     : copied data size
* Note        : Internal Function
********************************************************************************
*/
u_int write_data(SOCKET s, u_char xdata* src, u_char xdata* dst, u_int len)
{
	u_int size, size1;

	if (len == 0) return 0;

	if ( (((u_int)dst & SMASK[s]) + len) > SSIZE[s] ) 
	{
		size = SSIZE[s] - ((UINT)dst & SMASK[s]);
		IndirectWriteBuf(dst,src,size);
		size1 = len - size;
		dst = (SBUFBASEADDRESS[s]);
		IndirectWriteBuf(dst,src+size,size1);
	} 
	else
		IndirectWriteBuf(dst,src,len);

	return len;
}

/*
********************************************************************************
*               Designate the delay
*
* Description : Wait for 10 milliseconds
* Arguments   : cnt - time to wait
* Returns     : None
* Note        : Internal Function
********************************************************************************
*/

void wait_10ms(int cnt)
{
	u_int i;

	for (i = 0; i < cnt; i++) wait_1ms(10);
}


/*
********************************************************************************
*               Designate the delay
*
* Description : Wait for 1 millisecond
* Arguments   : cnt - time to wait
* Returns     : None
* Note        : Internal Function
********************************************************************************
*/
void wait_1ms(int cnt)
{
	u_int i;

	for (i = 0; i < cnt; i++) wait_1us(1000);
}

/*
********************************************************************************
*               Designate the delay
*
* Description : Wait for 1 microsecond
* Arguments   : cnt - time to wait
* Returns     : None
* Note        : Internal Function, System Dependant            
********************************************************************************
*/
void wait_1us(int cnt)
{
	u_int i;

	for (i = 0; i < cnt; i++) ;
}


/*
********************************************************************************
*               Write a byte via Indirect register of W3100A
*
* Description : Write one byte
* Arguments   : Addr - address
*		Data - Data to be written.
* Returns     : None
* Note        : Internal Fucntion
********************************************************************************
*/
void IndirectWriteByte(u_int Addr,char Data) reentrant
{
	char isr;
	isr = EX0;
	EX0 = 0;
	IDM_AR0 = (u_int)((Addr & 0xFF00) >> 8);
	IDM_AR1 = (u_char)(Addr & 0x00FF);
	IDM_DR  = Data;
	EX0 = isr;
}


/*
********************************************************************************
*               Read a byte via Indirect register of W3100A
*
* Description : Read one byte
* Arguments   : Addr - address
* Returns     : Data to have been read.
* Note        : Internal Fucntion
********************************************************************************
*/
char IndirectReadByte(u_int Addr) reentrant
{
	char isr;
	isr = EX0;
	EX0 = 0;
	IDM_AR0 = (u_char)((Addr & 0xFF00) >> 8);
	IDM_AR1 = (u_char)(Addr & 0x00FF);
	EX0 = isr;
	return IDM_DR;
}


/*
********************************************************************************
*               Write bytes stream via Indirect register of W3100A
*
* Description : Write bytes
* Arguments   : StartAddr - Base address
*		buf - pointer to data to be written.
*		size - size of buf
* Returns     : None
* Note        : Internal Fucntion
********************************************************************************
*/
void IndirectWriteBuf(u_int StartAddr,char * buf,u_int size) 
{
	u_int i;
	EX0 = 0;
	IDM_OR |= 0x01;
	IDM_AR0 = (u_char)((StartAddr & 0xFF00) >> 8);
	IDM_AR1 = (u_char)(StartAddr & 0x00FF);

	for(i = 0; i < size ; i++) IDM_DR = *buf++;
	IDM_OR &= 0xFE;
	EX0 = 1;
}

/*
********************************************************************************
*               Read bytes stream via Indirect register of W3100A
*
* Description : Read bytes
* Arguments   : StartAddr - Base address
*		buf - pointer to data to be saved.
*		size - size of buf
* Returns     : None
* Note        : Internal Fucntion
********************************************************************************
*/
void IndirectReadBuf(u_int StartAddr, char* buf,u_int size) 
{
	u_int i;
	EX0 = 0;
	IDM_OR |= 0x01;
	IDM_AR0 = (u_char)((StartAddr & 0xFF00) >> 8);
	IDM_AR1 = (u_char)(StartAddr & 0x00FF);
	for(i = 0; i < size ; i++) *buf++ = IDM_DR;
	IDM_OR &= 0xFE;
	EX0 = 1;
}

⌨️ 快捷键说明

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