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

📄 socket.c

📁 Wiznet iRadio Source
💻 C
字号:
/*
*
@file		socket.c
@brief	setting chip register for socket
*
*/

#include "w5100.h"
#include "socket.h"
#include "vs1033.h"
#include "util.h"


void _delay_us(u16 val)
{
  u16 i, j;
  
  for(j=0; j < val; j++) {
	  for(i=0; i<2; i++);
  }
}


/**
@brief	This Socket function initialize the channel in perticular mode, and set the port and wait for W5100 done it.
@return 	1 for sucess else 0.
*/  
u8 socket(
	u8 s, 		/**< for socket number */
	u8 protocol, 	/**< for socket protocol */
	u16 port, 		/**< the source port for the socket */
	u8 flag		/**< the option for the socket */
	)
{
	u8 ret;
#ifdef __DEF_IINCHIP_DBG__
	printf("socket()\r\n");
#endif
	if ((protocol == Sn_MR_TCP) || (protocol == Sn_MR_UDP) || (protocol == Sn_MR_IPRAW) || (protocol == Sn_MR_MACRAW) || (protocol == Sn_MR_PPPOE))
	{
		close(s);
		IINCHIP_WRITE(Sn_MR(s),protocol | flag);
		if (port != 0) {
			IINCHIP_WRITE(Sn_PORT0(s),(u8)((port & 0xff00) >> 8));
			IINCHIP_WRITE((Sn_PORT0(s) + 1),(u8)(port & 0x00ff));
		} 
		IINCHIP_WRITE(Sn_CR(s),Sn_CR_OPEN); // run sockinit Sn_CR
		ret = 1;
	}
	else
	{
		ret = 0;
	}
#ifdef __DEF_IINCHIP_DBG__
	printf("Sn_SR = %.2x , Protocol = %.2x\r\n", IINCHIP_READ(Sn_SR(s)), IINCHIP_READ(Sn_MR(s)));
#endif
	return ret;
}


/**
@brief	This function close the socket and parameter is "s" which represent the socket number
*/ 
void close(u8 s)
{
#ifdef __DEF_IINCHIP_DBG__
	printf("close()\r\n");
#endif
	IINCHIP_WRITE(Sn_CR(s),Sn_CR_CLOSE);
}


/**
@brief	This function established  the connection for the channel in passive (server) mode. This function waits for the request from the peer.
@return	1 for success else 0.
*/ 
/*
u8 listen(u8 s)
{
	u8 ret;
#ifdef __DEF_IINCHIP_DBG__
	printf("listen()\r\n");
#endif
	if (IINCHIP_READ(Sn_SR(s)) == SOCK_INIT)
	{
		IINCHIP_WRITE(Sn_CR(s),Sn_CR_LISTEN);
		ret = 1;
	}
	else
	{
		ret = 0;
#ifdef __DEF_IINCHIP_DBG__
	printf("Fail[invalid ip,port]\r\n");
#endif
	}
	return ret;
}
*/

/**
@brief	This function established  the connection for the channel in Active (client) mode. 
		This function waits for the untill the connection is established.
		
@return	1 for success else 0.
*/ 
u8 connect(u8 s, u8 * addr, u16 port)
{
	u8 ret;
	
	
#ifdef __DEF_IINCHIP_DBG__
	printf("connect()\r\n");
#endif
	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;
#ifdef __DEF_IINCHIP_DBG__
	printf("Fail[invalid ip,port]\r\n");
#endif
	}
	else
	{

		ret = 1;
		// set destination IP
		IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
		IINCHIP_WRITE((Sn_DIPR0(s) + 1),addr[1]);
		IINCHIP_WRITE((Sn_DIPR0(s) + 2),addr[2]);
		IINCHIP_WRITE((Sn_DIPR0(s) + 3),addr[3]);
		IINCHIP_WRITE(Sn_DPORT0(s),(u8)((port & 0xff00) >> 8));
		IINCHIP_WRITE((Sn_DPORT0(s) + 1),(u8)(port & 0x00ff));
		
		IINCHIP_WRITE(Sn_CR(s),Sn_CR_CONNECT);
		// wait for completion

		while (IINCHIP_READ(Sn_CR(s)))
		{
			if (IINCHIP_READ(Sn_SR(s)) == SOCK_CLOSED)
			{
#ifdef __DEF_IINCHIP_DBG__
			printf("SOCK_CLOSED.\r\n");
#endif
				ret = 0; break;
			}
		}
		
		
	}

	return ret;
}



/**
@brief	This function used for disconnect the socket and parameter is "s" which represent the socket number
@return	1 for success else 0.
*/ 
void disconnect(u8 s)
{
#ifdef __DEF_IINCHIP_DBG__
	printf("disconnect()\r\n");
#endif
	IINCHIP_WRITE(Sn_CR(s),Sn_CR_DISCON);
}


/**
@brief	This function used to send the data in TCP mode
@return	1 for success else 0.
*/ 
u16 send(
	u8 s, 		/**< the socket index */
	const u8 * buf, 	/**< a pointer to data */
	u16 len		/**< the data size to be send */
	)
{
	u8 status=0;
	u16 ret=0;
	u16 freesize=0;
#ifdef __DEF_IINCHIP_DBG__
	printf("send()\r\n");
#endif

   if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
   else ret = len;

   // if freebuf is available, start.
	do 
	{
		freesize = getSn_TX_FSR(s);
		status = IINCHIP_READ(Sn_SR(s));
		if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT))
		{
			ret = 0; 
			break;
		}
#ifdef __DEF_IINCHIP_DBG__
		printf("socket %d freesize(%d) empty or error\r\n", s, freesize);
#endif
	} while (freesize < ret);

      // copy data
	send_data_processing(s, (u8 *)buf, ret);
	IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);

	_delay_us(5);

	// wait for completion
	while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
	{
		status = IINCHIP_READ(Sn_SR(s));
		if (status == SOCK_CLOSED)
		{
#ifdef __DEF_IINCHIP_DBG__
			printf("SOCK_CLOSED.\r\n");
#endif
			putISR(s, getISR(s) & (Sn_IR_RECV | Sn_IR_DISCON | Sn_IR_CON));
			IINCHIP_WRITE(Sn_IR(s), (Sn_IR_SEND_OK | Sn_IR_TIMEOUT));
			return 0;
		}
     	}
     	putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
	IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
  	return ret;
}


/**
@brief	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.
		
@return	received data size for success else -1.
*/ 
u16 recv(
	u8 s, 	/**< socket index */
	u8 * buf, 	/**< a pointer to copy the data to be received */
	u16 len	/**< the data size to be read */
	)
{
	u16 ret=0;
#ifdef __DEF_IINCHIP_DBG__
	printf("recv()\r\n");
#endif


	if ( len > 0 )
	{
		recv_data_processing(s, buf, len);
		IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
		ret = len;
	}
	return ret;
}


/**
@brief	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.
		
@return	This function return send data size for success else -1.
*/ 
u16 sendto(u8 s, const u8 * buf, u16 len, u8 * addr, u16 port	)
{
	u8 status=0;
	u8 isr=0;
	u16 ret=0;

#ifdef __DEF_IINCHIP_DBG__
	printf("sendto()\r\n");
#endif
   if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(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)) ||(ret == 0)  ) 
 	{
 	   ;
#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);
	printf("Fail[invalid ip,port]\r\n");
#endif
	}
	else
	{
		IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
		IINCHIP_WRITE((Sn_DIPR0(s) + 1),addr[1]);
		IINCHIP_WRITE((Sn_DIPR0(s) + 2),addr[2]);
		IINCHIP_WRITE((Sn_DIPR0(s) + 3),addr[3]);
		IINCHIP_WRITE(Sn_DPORT0(s),(u8)((port & 0xff00) >> 8));
		IINCHIP_WRITE((Sn_DPORT0(s) + 1),(u8)(port & 0x00ff));

      		// copy data
      		send_data_processing(s, (u8 *)buf, ret);
		IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);

		/*
		while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
		{
			status = IINCHIP_READ(Sn_SR(s));
			
#ifndef __DEF_IINCHIP_INT__
			isr = IINCHIP_READ(Sn_IR(s));
#endif


			MyPrintf("\r\nSn_SR[%x], Sn_IR[%x] ",status, isr);

			if ((isr & Sn_IR_TIMEOUT) || (getISR(s) & Sn_IR_TIMEOUT))
			{
#ifdef __DEF_IINCHIP_DBG__
				printf("send fail.\r\n");
#endif
				MyPrintf("\r\nSend fail");

				putISR(s, getISR(s) & (Sn_IR_RECV | Sn_IR_DISCON | Sn_IR_CON));  //clear SEND_OK & TIMEOUT in I_STATUS[s]
				IINCHIP_WRITE(Sn_IR(s), (Sn_IR_SEND_OK | Sn_IR_TIMEOUT));						// clear SEND_OK & TIMEOUT in Sn_IR(s)
	   			return 0;
			}
		}
		*/

		while (1)
		{

			status = IINCHIP_READ(IR);
			
#ifndef __DEF_IINCHIP_INT__
			isr = IINCHIP_READ(Sn_IR(s));
#endif

			//MyPrintf("\r\nIR[%x], Sn_IR[%x] ",status, isr);
			if ((isr & Sn_IR_SEND_OK) == Sn_IR_SEND_OK) {
				if ((status &  IR_CONFLICT) && (status & IR_UNREACH)) {
					IINCHIP_WRITE(IR, status);
					return 0;
				}
				break;
			}

			if ((isr & Sn_IR_TIMEOUT) || (getISR(s) & Sn_IR_TIMEOUT))
			{
				//MyPrintf("\r\nSend fail");

				putISR(s, getISR(s) & isr);  	//clear SEND_OK & TIMEOUT in I_STATUS[s]
				IINCHIP_WRITE(Sn_IR(s), isr);	// clear SEND_OK & TIMEOUT in Sn_IR(s)
	   			return 0;
			}
		}
		
		putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
	   	IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);

	}
	return ret;
}


/**
@brief	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. 
	
@return	This function return received data size for success else -1.
*/ 
u16 recvfrom(
	u8 s, 	/**< the socket number */
	u8 * buf, 	/**< a pointer to copy the data to be received */
	u16 len, 	/**< the data size to read */
	u8 * addr, 	/**< a pointer to store the peer's IP address */
	u16 *port	/**< a pointer to store the peer's port number. */
	)
{
	u8 head[8];
	u16 data_len=0;
	u16 ptr=0;
#ifdef __DEF_IINCHIP_DBG__
	printf("recvfrom()\r\n");
#endif

	if ( len > 0 )
	{
   	ptr = IINCHIP_READ(Sn_RX_RD0(s));
   	ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_RX_RD0(s) + 1);
#ifdef __DEF_IINCHIP_DBG__
   	printf("ISR_RX: rd_ptr : %.4x\r\n", ptr);
#endif
   	switch (IINCHIP_READ(Sn_MR(s)) & 0x07)
   	{
   	case Sn_MR_UDP :
   			read_data(s, (u8 *)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 = (*port << 8) + head[5];
   			data_len = head[6];
   			data_len = (data_len << 8) + head[7];
   			
#ifdef __DEF_IINCHIP_DBG__
   			printf("UDP msg arrived\r\n");
   			printf("source Port : %d\r\n", *port);
   			printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
#endif

			read_data(s, (u8 *)ptr, buf, data_len); // data copy.
			ptr += data_len;

			IINCHIP_WRITE(Sn_RX_RD0(s),(u8)((ptr & 0xff00) >> 8));
			IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(u8)(ptr & 0x00ff));
   			break;
   
   	case Sn_MR_IPRAW :
   			read_data(s, (u8 *)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];
   	
#ifdef __DEF_IINCHIP_DBG__
   			printf("IP RAW msg arrived\r\n");
   			printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
#endif
			read_data(s, (u8 *)ptr, buf, data_len); // data copy.
			ptr += data_len;

			IINCHIP_WRITE(Sn_RX_RD0(s),(u8)((ptr & 0xff00) >> 8));
			IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(u8)(ptr & 0x00ff));
   			break;
   	case Sn_MR_MACRAW :
   			read_data(s,(u8*)ptr,head,2);
   			ptr+=2;
   			data_len = head[0];
   			data_len = (data_len<<8) + head[1] - 2;

   			read_data(s,(u8*) ptr,buf,data_len);
   			ptr += data_len;
   			IINCHIP_WRITE(Sn_RX_RD0(s),(u8)((ptr & 0xff00) >> 8));
   			IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(u8)(ptr & 0x00ff));
   			
#ifdef __DEF_IINCHIP_DGB__
			printf("MAC RAW msg arrived\r\n");
			printf("dest mac=%.2X.%.2X.%.2X.%.2X.%.2X.%.2X\r\n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]);
			printf("src  mac=%.2X.%.2X.%.2X.%.2X.%.2X.%.2X\r\n",buf[6],buf[7],buf[8],buf[9],buf[10],buf[11]);
			printf("type    =%.2X%.2X\r\n",buf[12],buf[13]); 
#endif			
			break;

   	default :
   			break;
   	}
		IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
	}
#ifdef __DEF_IINCHIP_DBG__
	printf("recvfrom() end ..\r\n");
#endif
 	return data_len;
}

/*
u16 igmpsend(u8 s, const u8 * buf, u16 len)
{
	//u8 status=0;
	u8 isr=0;
	u16 ret=0;
	
#ifdef __DEF_IINCHIP_DBG__
	printf("igmpsend()\r\n");
#endif
   if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
   else ret = len;

	if	(ret == 0) 
 	{
 	   
#ifdef __DEF_IINCHIP_DBG__
	printf("%d Fail[%d]\r\n",len);
#endif
	}
	else
	{
		// copy data
		send_data_processing(s, (u8 *)buf, ret);
		IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
      
      		while (IINCHIP_READ(Sn_CR(s)))
		{
			// status = IINCHIP_READ(Sn_SR(s));
#ifndef __DEF_IINCHIP_INT__			
			isr = IINCHIP_READ(Sn_IR(s));
#endif
			if ((getISR(s) & Sn_IR_TIMEOUT) || (isr & Sn_IR_TIMEOUT))
			{
#ifdef __DEF_IINCHIP_DBG__
				printf("igmpsend fail.\r\n");
#endif
				putISR(s, getISR(s) & (Sn_IR_RECV | Sn_IR_DISCON | Sn_IR_CON));
				IINCHIP_WRITE(Sn_IR(s), (Sn_IR_SEND_OK | Sn_IR_TIMEOUT));
				return 0;
			}
		}
		putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
	   	IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
	}
	return ret;
}
*/

⌨️ 快捷键说明

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