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

📄 socket.c

📁 dvr
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
********************************************************************************
*
*  Copyright 2002, Vineyard Technologies, Inc.
*
* Filename   : socket.c
* Programmer : Steve KyeongHyeon Lee
* Created    : 2003/02/17
* Modified   :
*
* Description : Driver API program of W3100A (Little Endian)
********************************************************************************
*/

#include "types.h"
#ifdef LANIF
/*
###############################################################################
File Include Section
###############################################################################
*/
#include <stdio.h>
#include <absacc.h>
#include "gio.h"
#include "socket.h"

#define FIX_PTR_CHANGE	1
/*
###############################################################################
Externs
###############################################################################
*/


/*
###############################################################################
Define Part
###############################################################################
*/


// Indirect Access Mode Register
#define FREG_IDM_OR			0xC000
#define FREG_IDM_AR0		0xC001
#define FREG_IDM_AR1		0xC002
#define FREG_IDM_DR			0xC003
// IDM_OR bits
#define IND_EN		0x80	// (1)Enable indirect bus I/F 
#define LB			0x02	// Little(1) or Big Endian (0)
#define AUTO_INC	0x01	// Address Auto Increment(1)


void read_4reg(u16 shadow, u8* val, u16 addr);
void write_4reg(u8* val, u16 addr);


/*
###############################################################################
Indirect Mode Access API
###############################################################################
*/
void idminit(void)
{
	XBYTE[FREG_IDM_OR] = IND_EN | AUTO_INC;
}
/*
###############################################################################
Indirect Mode Access API
###############################################################################
*/
void idmw(u16 addr, u8 val)
{   
	//XBYTE[FREG_IDM_OR] = IND_EN;
	XBYTE[FREG_IDM_AR0] = (u8)(addr>>8);
	XBYTE[FREG_IDM_AR1] = (u8)addr;
	XBYTE[FREG_IDM_DR] = val;	                       
}                          
                           
/*
###############################################################################
Indirect Mode Access API
###############################################################################
*/
u8 idmr(u16 addr)          
{   
	idata u8 val;
//	xdata u8 val;

	//XBYTE[FREG_IDM_OR] = IND_EN;
	XBYTE[FREG_IDM_AR0] = (u8)(addr>>8);
	XBYTE[FREG_IDM_AR1] = (u8)addr;
	val = XBYTE[FREG_IDM_DR];
	return val;
}   
/*
###############################################################################
Indirect Mode Access API
###############################################################################
*/
xdata u8 idm_addr0;
xdata u8 idm_addr1;                       
void idm_save(void)
{
	idm_addr0 = XBYTE[FREG_IDM_AR0];
	idm_addr1 = XBYTE[FREG_IDM_AR1];
}
	
/*
###############################################################################
Indirect Mode Access API
###############################################################################
*/
void idm_restore(void)
{
	//XBYTE[FREG_IDM_OR] = IND_EN;
	XBYTE[FREG_IDM_AR0] = idm_addr0;
	XBYTE[FREG_IDM_AR1] = idm_addr1;
}
/*
###############################################################################
Indirect Mode Access API
###############################################################################
*/
#ifdef DEBUG_IDM_AUTO
void idm_auto_inc_test(void)
{
	xdata u16 addr;
	lan_enable();
	// set memory as test mode.
	XBYTE[FREG_IDM_OR] = IND_EN; // | AUTO_INC;
	XBYTE[FREG_IDM_AR0] = 0x00;
	XBYTE[FREG_IDM_AR1] = 0x01;
	XBYTE[FREG_IDM_DR] = 0x80;

	// clear area 0x4000 to 0x5000 (offset)
	addr=0x4000;
	XBYTE[FREG_IDM_OR] = IND_EN; // | AUTO_INC;
	for(addr=0x4000;addr<0x5000;addr++)
	{
		XBYTE[FREG_IDM_AR0] = (u8)(addr>>8);
		XBYTE[FREG_IDM_AR1] = (u8) addr;
		XBYTE[FREG_IDM_DR] = 0x00;
	}
	// set auto increment mode
	addr = 0x4000;
	XBYTE[FREG_IDM_AR0] = (u8)(addr>>8);
	XBYTE[FREG_IDM_AR1] = (u8) addr;
	XBYTE[FREG_IDM_OR] = IND_EN | AUTO_INC;
	
	// write 0xaa into 0x4000 -- 0x400f
	for(;addr<0x4010;addr++)
	{
		XBYTE[FREG_IDM_DR] = 0xaa;
	}
	// skip writing 0x4010 -- 0x401f
	addr = 0x4020;
	XBYTE[FREG_IDM_AR0] = (u8)(addr>>8);
	XBYTE[FREG_IDM_AR1] = (u8) addr;
	
	// write 0xaa into 0x4020 -- 0x402f
	for(;addr<0x4030;addr++)
	{
		XBYTE[FREG_IDM_DR] = 0xaa;
	}
	
	dv03_enable();
}
#endif
/*******************************************************************/
#define WAIT1US_40MHZ		10			// Wait loop factor value	
#define WAIT1MS_40MHZ		10000 		//100 //10000
#define	MAX_SOCK_NUM		4			// Concurrent maxmium number of socket

#define	I2CHIP_BASE			0x0000		//0x8000		// Address of W3100A
#define	SEND_DATA_BUF		0x4000		//0xC000		// Internal Tx buffer address of W3100A
#define	RECV_DATA_BUF		0x6000		//0xE000		// Internal Rx buffer address of W3100A

#define MAX_SEGMENT_SIZE	1460		// Maximum TCP transmission packet size


// Internal register set of W3100A

#define COMMAND(i)			(I2CHIP_BASE + i)
#define	INT_STATUS(i)		(I2CHIP_BASE + 0x04 + i)
#define	INT_REG				(I2CHIP_BASE + 0x08)
#define	INTMASK				(I2CHIP_BASE + 0x09)
#define	RESETSOCK			(I2CHIP_BASE + 0x0A)

#define RX_PTR_BASE			0x10
#define RX_PTR_SIZE			0x0C
#define TX_PTR_BASE			0x40
#define TX_PTR_SIZE			0x0C

#define	RX_WR_PTR(i,n)		((I2CHIP_BASE + RX_PTR_BASE + RX_PTR_SIZE * i)+n)
#define	RX_RD_PTR(i,n)		((I2CHIP_BASE + RX_PTR_BASE + RX_PTR_SIZE * i + 0x04)+n)
#define	RX_ACK_PTR(i,n)		((I2CHIP_BASE + TX_PTR_BASE + TX_PTR_SIZE * i + 0x08)+n)
#define	TX_WR_PTR(i,n)		((I2CHIP_BASE + TX_PTR_BASE + TX_PTR_SIZE * i)+n)
#define	TX_RD_PTR(i,n)		((I2CHIP_BASE + TX_PTR_BASE + TX_PTR_SIZE * i + 0x04)+n)
#define	TX_ACK_PTR(i,n)		((I2CHIP_BASE + RX_PTR_BASE + RX_PTR_SIZE * i + 0x08)+n)

// Shadow Register Pointer Define 
#define SHADOW_RXWR_PTR(i)	(I2CHIP_BASE + 0x1E0 + 3 *i)
#define	SHADOW_RXRD_PTR(i)	(I2CHIP_BASE + 0x1E1 + 3 *i)
#define	SHADOW_TXACK_PTR(i)	(I2CHIP_BASE + 0x1E2 + 3 *i)
#define	SHADOW_TXWR_PTR(i)	(I2CHIP_BASE + 0x1F0 + 3 *i)
#define SHADOW_TXRD_PTR(i)	(I2CHIP_BASE + 0x1F1 + 3 *i)

#define SOCK_BASE			0xA0
#define SOCK_SIZE			0x18

#define SOCK_STATUS(i)		(I2CHIP_BASE + SOCK_BASE + SOCK_SIZE * i)
#define OPT_PROTOCOL(i)		(I2CHIP_BASE + SOCK_BASE + SOCK_SIZE * i + 0x01)
#define DST_HA_PTR(i)		(I2CHIP_BASE + SOCK_BASE + SOCK_SIZE * i + 0x02)
#define DST_IP_PTR(i,n)		((I2CHIP_BASE + SOCK_BASE + SOCK_SIZE * i + 0x08)+n)
#define DST_PORT_PTR(i,n)	((I2CHIP_BASE + SOCK_BASE + SOCK_SIZE * i + 0x0C)+n)
#define SRC_PORT_PTR(i,n)	((I2CHIP_BASE + SOCK_BASE + SOCK_SIZE * i + 0x0E)+n)
#define IP_PROTOCOL(i)		(I2CHIP_BASE + SOCK_BASE + SOCK_SIZE * i + 0x10)
#define TOS(i)				(I2CHIP_BASE + SOCK_BASE + SOCK_SIZE * i + 0x11)		// Type of Service register

#define GATEWAY_PTR(n)		(I2CHIP_BASE + 0x80 + n)
#define SUBNET_MASK_PTR(n)	(I2CHIP_BASE + 0x84 + n)
#define SRC_HA_PTR(n)		(I2CHIP_BASE + 0x88 + n)
#define SRC_IP_PTR(n)		(I2CHIP_BASE + 0x8E + n)
#define TIMEOUT_PTR(n)		(I2CHIP_BASE + 0x92 + n)
#define RETRYCNT_PTR		(I2CHIP_BASE + 0x94)

#define RX_DMEM_SIZE		(I2CHIP_BASE + 0x95)
#define TX_DMEM_SIZE		(I2CHIP_BASE + 0x96)


/* SOCKET OPTION(Settting OPT_PROTOCOL REG.) */
#define SOCKOPT_BROADCAST	0x80		// Transmission, Reception of broadcasting data
#define SOCKOPT_NDTIMEOUT	0x40		// Setting timeout
#define SOCKOPT_NDACK		0x20		// Setting No Delayed Ack(TCP)
#define SOCKOPT_SWS			0x10		// Setting Silly Window Syndrome(TCP)

/* OPTION(Setting OPT_PROTOCOL REG.) for MAC LAYER RAW MODE */
#define MACLOPT_RXERR		0x80		// Setting reception of error packet
#define MACLOPT_BROADCAST	0x40		// Setting reception of broadcast packet
#define MACLOPT_PROMISC		0x20		// Setting reception of promiscuous packet

/* Command variables */
#define CSYS_INIT			0x01	   	// To set up network information(mac address, gateway address, subnet mask, source ip)
#define CSOCK_INIT			0x02		// To initialize socket
#define CCONNECT			0x04		// To establish connection as tcp client mode
#define CLISTEN				0x08		// To wait for connection request as tcp server mode
#define CCLOSE				0x10		// To terminate connection
#define CSEND				0x20		// To send data
#define CRECV				0x40		// To receive data
#define CSW_RESET			0x80		// To do software reset


/*
###############################################################################
Static function prototypes
###############################################################################
*/

			void	initseqnum(SOCKET s);
			char	listen(SOCKET s, u8 * addr, u16 * port);
			u16		select(SOCKET s, u8 func);
			char	connect(SOCKET s, u8 * addr, u16 port);
			u16		sendto_in(SOCKET , const u8 *, u16, u8 flag);
			int		send_in(SOCKET s, u8 * buf, u16 len, u8 flag, u8 isTcp);
			u16		read_data(SOCKET s, u8 * src, u8 * dst, u16 len);
			u16		write_data(SOCKET s, u8 * src, u8 * dst, u16 len);
			char	reset_sock(SOCKET s);
volatile	void	wait_1us(int i);
volatile	void	wait_1ms(int i);
			void	enable(void);
			void	disable(void);

/*
###############################################################################
Local Variable Declaration Section
###############################################################################
*/
		u8				I_STATUS[4]={0,0,0,0};			// Store Interrupt Status according to channels
		u16				Local_Port;						// Source port number if a specific source port is not decided
		union un_l2cval	SEQ_NUM;						// Set initial sequence number
		u32				SMASK[MAX_SOCK_NUM];			// Variable to store MASK of Tx in each channel, on setting dynamic memory size.
		u32				RMASK[MAX_SOCK_NUM];			// Variable to store MASK of Rx in each channel, on setting dynamic memory size.
		int				SSIZE[MAX_SOCK_NUM];			// Maximun Tx memory size by each channel
		int				RSIZE[MAX_SOCK_NUM];			// Maximun Rx memory size by each channel
		u16				SBUFBASEADDRESS[MAX_SOCK_NUM];	// Maximun Tx memory base address by each channel
		u16				RBUFBASEADDRESS[MAX_SOCK_NUM];	// Maximun Rx memory base address by each channel
		u8				w3100a_intrrupt_mask = 0;
		u8				bufaddr_h = 0x00;
		u8				bufaddr_l = 0x00;
		union un_l2cval	tx_wr_ptr_save;
		u8				in_w3100a_intr = 0;

/*
###############################################################################
Function Implementation Section
###############################################################################
*/
void SOCK_access_mode(void)
{
	lan_enable();
	idminit();
	dv03_enable();
}
/*
********************************************************************************
*               Interrupt handling function of the W3100A
*
* Description :
*   Stores the status information that each function waits for in the global 
*   variable I_STATUS for transfer.
*   I_STATUS stores the interrupt status value for each channel.
* Arguments   : None
* Returns     : interrupt status register value
* Note        : Internal Function
********************************************************************************
*/
#ifdef DEBUG_CTRL_RX_CNT
xdata u16 gv_socket_ctrl_rx_cnt = 0;
#endif
void SOCK_ISR_W3100A(u8* status)// using 3
{
	u8 Tstatus;
	
	lan_enable();			// To access W3100A
	
	*status = Tstatus = idmr(INT_REG);
	
	// Control Channel Status Change
	if (Tstatus & 0x01) {	// channel 0 interrupt(sysinit, sockinit, established, closed, timeout, send_ok, recv_ok)

		I_STATUS[0] = idmr(INT_STATUS(0));	// & ~(SSEND_OK|SRECV_OK);	// No checking tx rx ok interrupt

		//if(I_STATUS[0]==0x00) // if tx or rx interrupt
		//	*status &= 0xFE;	// clear channel 0 interrupt status bits

		idmw(INT_REG, 0x01);	// clear interrupt status
	}

	// Video Channel Status Change
	if (Tstatus & 0x02) {	// channel 1 interrupt(sysinit, sockinit, established, closed, timeout, send_ok, recv_ok)

		I_STATUS[1] = idmr(INT_STATUS(1)) & ~(SSEND_OK|SRECV_OK);	// No checking tx rx ok interrupt
		
		if(I_STATUS[1]==0x00)	// if tx or rx interrupt
			*status &= 0xFD;	// clear channel 1 interrupt status bits 
			
		idmw(INT_REG, 0x02);	// clear interrupt status
	}

	// Control Channel Rx packets
	if (Tstatus & 0x10) {	// channel 0 receive interrupt
#ifdef DEBUG_CTRL_RX_CNT
		gv_socket_ctrl_rx_cnt++;
#endif
		idmw(INT_REG, 0x10);
	}

	// Video Channel Rx packets -- never happen
	if (Tstatus & 0x20) {	// channel 1 receive interrupt
		idmw(INT_REG, 0x20);
	}

}


/*
*********************************************************************************************************
*              W3100A Initialization Function
*
* Description:  Reset of W3100A S/W and Registeration of i386 interrupt
* Arguments  : None.
* Returns    : None.
* Note       :
*********************************************************************************************************
*/
void SOCK_softreset_W3100A(u32 seqnum)
{
/*
	xdata u16 addr;
	xdata u16 size;
*/
	lan_enable();
	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
	SEQ_NUM.lVal = seqnum;		//4294967293;// Sets the initial SEQ# to be used for TCP communication. (It should be ramdom 
								// value)
	idmw(COMMAND(0), CSW_RESET);		// Software RESET

	dv03_enable();
}

/*
********************************************************************************
*               W3100A initialization function
*
* Description : 
*   Sets the Tx, Rx memory size by each channel, source MAC, source IP, gateway, and subnet mask
*   to be used by the W3100A to the designated values.
*   May be called when reflecting modified network information or Tx, Rx memory size on the W3100A
*   Include Ping Request for ARP update (In case that a device embedding W3100A is directly connected to Router)
* Arguments   : sbufsize - Tx memory size (00 - 1KByte, 01- 2KBtye, 10 - 4KByte, 11 - 8KByte)
*                          bit 1-0 : Tx memory size of channel #0 
*                          bit 3-2 : Tx memory size of channel #1 
*                          bit 5-4 : Tx memory size of channel #2
*                          bit 7-6 : Tx memory size of channel #3 
*               rbufsize - Rx memory size (00 - 1KByte, 01- 2KBtye, 10 - 4KByte, 11 - 8KByte)
*                          bit 1-0 : Rx memory size of channel #0 
*                          bit 3-2 : Rx memory size of channel #1 
*                          bit 5-4 : Rx memory size of channel #2
*                          bit 7-6 : Rx memory size of channel #3 
* Returns     : None
* Note        : API Function
*               Maximum memory size for Tx, Rx in W3100A is 8KBytes,
*               In the range of 8KBytes, the memory size could be allocated dynamically by each channel 
*               Be attentive to sum of memory size shouldn't exceed 8Kbytes
*               and to data transmission and receiption from non-allocated channel may cause some problems.
*               If 8KBytes memory already is assigned to centain channel, other 3 channels couldn't be used, for there's no available memory.
*               If two 4KBytes memory are assigned to two each channels, other 2 channels couldn't be used, for there's no available memory.
*               [Example of memory assignment]
*                sbufsize => 00000011, rbufsize => 00000011 : Assign 8KBytes for Tx and Rx to channel #0, Cannot use channel #1,#2,#3
*                sbufsize => 00001010, rbufsize => 00001010 : Assign 4KBytes for Tx and Rx to each channel #0,#1 respectively. Cannot use channel #2,#3
*                sbufsize => 01010101, rbufsize => 01010101 : Assign 2KBytes for Tx and Rx to each all channels respectively.

⌨️ 快捷键说明

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