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 + -
显示快捷键?