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

📄 socket.c

📁 dvr
💻 C
📖 第 1 页 / 共 4 页
字号:
	switch (func) {
		case SEL_CONTROL :						// socket status information
			val = idmr(SOCK_STATUS(s));
			break;
			
		case SEL_SEND :							// Calculate send free buffer size
			read_4reg( SHADOW_TXWR_PTR(s), wr_ptr.cVal, TX_WR_PTR(s,0) );
			read_4reg( SHADOW_TXACK_PTR(s), ack_ptr.cVal, TX_ACK_PTR(s,0) );
			
			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);
#ifdef DEBUG_SOCK
			printf("\n\r[%d] WR=0x%08lx AK=0x%08lx", (int)s, (u32)wr_ptr.lVal, (u32)ack_ptr.lVal);
#endif		
			break;

		case SEL_RECV :							//  Calculate received data size
			read_4reg( SHADOW_RXWR_PTR(s), wr_ptr.cVal, RX_WR_PTR(s,0) );
			read_4reg( SHADOW_RXRD_PTR(s), rd_ptr.cVal, RX_RD_PTR(s,0) );

			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_SOCK
			printf("\n\r[%d] WR=0x%08lx RD=0x%08lx (len=%04x)", (int)s, (u32)wr_ptr.lVal, (u32)rd_ptr.lVal, (u16)val);
#endif		
			break;
			
		default :
			val = -1;
			break;
	}

    return(val);
}



/*
*********************************************************************************************************
*              Internal function for sending TCP data.
*
* Description : Called by the SOCK_send() function for TCP transmission.
*    It first calculates the free transmit buffer size
*    and compares it with the size of the data to be transmitted to determine the transmission size.
*    After calculating the data size, it copies data from TX_WR_PTR.
*    It waits if there is a previous send command in process.
*    When the send command is cleared, it updates the TX_WR_PTR up to the size to be transmitted and performs the send command.
* Arguments   : s   - channel number
*               buf - Pointer pointing data to send
*               len - data size to send
* Returns     : Succeeded: sent data size, Failed: -1
* Note        : Internal Function
*********************************************************************************************************
*/
int send_in(SOCKET s, u8 * buf, u16 len, u8 flag, u8 isTcp)
{
	xdata u16 size;
	xdata u8 * send_ptr;
	xdata union un_l2cval wr_ptr, rd_ptr;
#ifdef DEBUG_SOCK	
	xdata u16 free_check_retry=0;
	xdata u16 retry=0;
#endif	
	xdata u16 bufaddr;

S_START:

	read_4reg( SHADOW_TXWR_PTR(s), wr_ptr.cVal, TX_WR_PTR(s,0) );

	if(isTcp)
	{
		read_4reg( SHADOW_TXACK_PTR(s), rd_ptr.cVal, TX_ACK_PTR(s,0) );
	}
	else
	{
		read_4reg( SHADOW_TXRD_PTR(s), rd_ptr.cVal, TX_RD_PTR(s,0) );
	}

	//  Calculate send free buffer size
	if (wr_ptr.lVal >= rd_ptr.lVal) 
		size = SSIZE[s] - (wr_ptr.lVal - rd_ptr.lVal);
	else 
		size = SSIZE[s] - (0 - rd_ptr.lVal + wr_ptr.lVal);

	// Recalulate after some delay because of error in pointer calculation
	if (size > SSIZE[s]) {
		if (isTcp)
		{
			if (select(s, SEL_CONTROL) != SOCK_ESTABLISHED) return -1;
		}
#ifdef DEBUG_SOCK		
		printf("\n\rsend_in: ch=%d : err in ptr wr=0x%08lx rd=0x%08lx", (int)s, wr_ptr.lVal, rd_ptr.lVal);
#endif
		
		wait_1ms(1);
#ifdef DEBUG_SOCK
		retry++;
#endif
		goto S_START;
	}
#ifdef DEBUG_SOCK
	if(retry){
		printf("\n\rsend_in: pointer err cnt = %u", retry);
	}
#endif
	// Wait when previous sending has not finished yet and there's no free buffer
	if (size == 0) {
		if (isTcp)
		{
			if (select(s, SEL_CONTROL) != SOCK_ESTABLISHED) return -1;
		}
		wait_1ms(1);
#ifdef DEBUG_SOCK
		free_check_retry++;
#endif		
		goto S_START;

	} else if (size < len) { 
		len = size;
	}

#ifdef DEBUG_SOCK
	if(free_check_retry){
		printf("\n\rsend_in: buf free check cnt = %u", free_check_retry);
	}
#endif

	//  Calculate pointer to data copy
	send_ptr = (u8 *)(SBUFBASEADDRESS[s] + (u16)(wr_ptr.lVal & SMASK[s]));

	if (flag == SEND_NODELAY) {
		write_data(s, buf, send_ptr, len);		// copy data

		while (idmr(COMMAND(s)) & CSEND)  {			// Confirm previous send command 
			if (isTcp) {
				if (select(s, SEL_CONTROL) != SOCK_ESTABLISHED) return -1;
			}
			else {
				if (select(s, SEL_CONTROL) == SOCK_CLOSED) return -1;
			}
		}

		wr_ptr.lVal = wr_ptr.lVal + len;		//  update tx_wr_ptr

		write_4reg(wr_ptr.cVal, TX_WR_PTR(s,0));
		wait_1us(1);

		idmw(COMMAND(s), CSEND);						// SEND

    }
    else { 		// SEND_DELAY
    	// save network target buffer address
    	bufaddr = (u16)send_ptr;
    	bufaddr_h = (u8)(bufaddr >> 8);
    	bufaddr_l = (u8) bufaddr;
    	// save network write pointer
    	tx_wr_ptr_save.lVal = wr_ptr.lVal + len;
	}
   	return(len);
}


/*
*********************************************************************************************************
*              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 SOCK_recv()or SOCK_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
*********************************************************************************************************
*/
u16 read_data(SOCKET s, u8 * src, u8 * dst, u16 len)
{
	u16 xsrc;
	xdata u16 i, size, size1;

	if (len == 0) return 0;

	xsrc = (u16)src;
	if ((((u32)src & RMASK[s]) + len) > RSIZE[s]) {
		size = RSIZE[s] - ((u32)src & RMASK[s]);

		for (i = 0; i < size; i++) {
			//*dst++ = XBYTE[xsrc++];
			*dst++ = idmr(xsrc++);
		}

		size1 = len - size;
		xsrc = (u16)RBUFBASEADDRESS[s];
		for (i = 0; i < size1; i++) {
			//*dst++ = XBYTE[xsrc++];	
			*dst++ = idmr(xsrc++);
		}
	}
	else {
		for (i = 0; i < len; i++) {
			//*dst++ = XBYTE[xsrc++];	
			*dst++ = idmr(xsrc++);
		}
	}

	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
*********************************************************************************************************
*/
u16 write_data(SOCKET s, u8 * src, u8 * dst, u16 len)
{
	xdata u16 i, size, size1;
	u16 xdst;

	if (len == 0) return 0;

#ifdef DEBUG_SOCK
	printf("\n\rwrite_data: src=0x%04x dst=0x%04x len=%d\n\r", (u16)src, (u16)dst, len);
#endif
	xdst = (u16)dst;
	if ((((u32)xdst & SMASK[s]) + len) > SSIZE[s]) {

		size = SSIZE[s] - ((u32)xdst & SMASK[s]);

		for (i = 0; i < size; i++) {
			//XBYTE[xdst++] = *src++;
			idmw( xdst++, *src++ );
		}

		size1 = len - size;
		xdst = (u16)SBUFBASEADDRESS[s];
		for (i = 0; i < size1; i++) {
			//XBYTE[xdst++] = *src++;
			idmw( xdst++, *src++ );
		}
	}
	else {
		for (i = 0; i < len; i++) {
			//XBYTE[xdst++] = *src++;
			idmw( xdst++, *src++ );
		}
	}
	return len;
}

/*
*********************************************************************************************************
*               Create random value for initial Seq# when establishing TCP connection
*
* Description : In this function, you can add some source codes to create random number for initial Seq#
*     In real, TCP initial SEQ# should be random value. 
*               (Currently, we're using static value in EVB/DK.)
* Arguments   : s - channel number
* Returns     : None
* Note        : API Function
*********************************************************************************************************
*/
void initseqnum(SOCKET s)
{
	SEQ_NUM.lVal++;				// Designate initial seq#
    							// If you have random number generation function, 
    							// assign random number instead of SEQ_NUM.lVal++.
	//SEQ_NUM.lVal=0xffffffff;    							

	write_4reg(SEQ_NUM.cVal, TX_WR_PTR(s,0));
	wait_1us(2);

	write_4reg(SEQ_NUM.cVal, TX_RD_PTR(s,0));
	wait_1us(2);

	write_4reg(SEQ_NUM.cVal, TX_ACK_PTR(s,0));
	wait_1us(2);

}


/*
*********************************************************************************************************
wait_1us is working for 4us when input, i, is 2
*********************************************************************************************************
*/
volatile void wait_1us(int i)
{
//	xdata u16 j;
//	for(j=0;j<i;j++);
	
	i++;
	return;
}

/*
*********************************************************************************************************
*********************************************************************************************************
*/
volatile void wait_1ms(int i)
{

	u16 n = WAIT1MS_40MHZ;
	u16 x;

    while(i-- > 0)
    {
        n = WAIT1MS_40MHZ;
		for(x=0;x<WAIT1MS_40MHZ;x++)
			n--;
    }
}

/*
*********************************************************************************************************
*********************************************************************************************************
*/
void enable(void)
{
	EX1 = 1;
}
/*
*********************************************************************************************************
*********************************************************************************************************
*/
void disable(void)
{
	EX1 = 0;
}


void lan_int_enable(void)
{
	lan_enable();
	enable();
	dv03_enable();
}

void lan_int_disable(void)
{
	lan_enable();
	disable();
	dv03_enable();
}

//=========================================================
//
//=========================================================
void read_4reg(u16 shadow, u8* val, u16 addr)
{
	u8 k;

	disable();
	k = idmr(shadow);
	wait_1us(2);
	val[0] = idmr(addr+0);
	val[1] = idmr(addr+1);
	val[2] = idmr(addr+2);
	val[3] = idmr(addr+3);
	enable();

#ifdef DEBUG_GPIO
	if((val[0]+val[1]+val[2]+val[3])==0)
	{
		P16_WZREG0 = HIGH;
		delay_time(10, 1);
		//printf("\n\rWZNET REG OFF=%04x VAL=0x00000000", addr);
		P16_WZREG0 = LOW;
	}
#endif

}

//=========================================================
//
//=========================================================
void write_4reg(u8* val, u16 addr)
{	
	disable();
	idmw(addr+0, val[0]);
	idmw(addr+1, val[1]);
	idmw(addr+2, val[2]);
	idmw(addr+3, val[3]);
	enable();
}












#endif // LANIF



⌨️ 快捷键说明

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