📄 socket.c
字号:
}
/*
*********************************************************************************************************
* If the socket called SEND_DELAY send command,
* finish the sending packet process
*********************************************************************************************************
*/
#define RECOVER_TX_WR
void SOCK_send_enable(SOCKET s)
{
lan_enable();
while (idmr(COMMAND(s)) & CSEND) { // Confirm previous send command
if (select(s, SEL_CONTROL) != SOCK_ESTABLISHED)
{
dv03_enable();
return;
}
#ifdef DEBUG_SOCK
printf("\n\rsend_in: ch=%d : still sending", (int)s);
#endif
}
#ifdef RECOVER_TX_WR
{
union un_l2cval tmp;
read_4reg( SHADOW_TXWR_PTR(s), tmp.cVal, TX_WR_PTR(s,0) );
if((tmp.lVal+0x800)!= tx_wr_ptr_save.lVal)
{
#ifdef DEBUG_SOCK_WPTR
printf("\n\rTX_WR: (cur_reg=%08lx) +0x800 = (saved=%08lx)", tmp.lVal, tx_wr_ptr_save.lVal);
#endif
if(tmp.lVal!=0)
{
read_4reg( SHADOW_TXACK_PTR(s), tmp.cVal, TX_ACK_PTR(s,0) );
tx_wr_ptr_save.lVal = tmp.lVal + 0x800;
#ifdef DEBUG_SOCK_WPTR
printf(" Recalculated(usingACK)=%08lx",tx_wr_ptr_save.lVal);
#endif
}
}
}
#endif
write_4reg(tx_wr_ptr_save.cVal, TX_WR_PTR(s,0));
wait_1us(1);
idmw(COMMAND(s), CSEND); // SEND
dv03_enable();
}
/*
*********************************************************************************************************
* TCP data receiving function.
*
* Description : This function is for receiving TCP data.
* The SOCK_recv function is an application I/F function. It continues to wait for as much data as the application wants to receive.
* Arguments : s - channel number
* buf - Pointer where the data to be received is copied
* len - Size of the data to be received
* Returns : Succeeded: received data size, Failed: -1
* Note : API Fcuntion
*********************************************************************************************************
*/
int SOCK_recv(SOCKET s, u8 * buf, u16 len)
{
xdata u16 size;
xdata u8 * recv_ptr;
xdata union un_l2cval wr_ptr, rd_ptr;
xdata int ret=0;
lan_enable();
R_START:
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) );
// calculate received data size
if ( len <= 0 ){ ret=0; goto ErrReturn; }
else if (wr_ptr.lVal >= rd_ptr.lVal) size = wr_ptr.lVal - rd_ptr.lVal;
else size = 0 - rd_ptr.lVal + wr_ptr.lVal;
#ifdef DEBUG_SOCK
printf("\n\rSOCK_recv: ch=%d wr_ptr=0x%08lx rd_ptr=0x%08lx RxSz=0x%04x", (int)s, wr_ptr.lVal, rd_ptr.lVal, size);
#endif
// Wait until receiving is done when received data size is less then len
if (size < len) {
if (select(s, SEL_CONTROL) != SOCK_ESTABLISHED){ ret=-1; goto ErrReturn; }
wait_1ms(1);
goto R_START;
}
// Calculate pointer to be copied received data
recv_ptr = (u8 *)(RBUFBASEADDRESS[s] + (u16)(rd_ptr.lVal & RMASK[s]));
read_data(s, recv_ptr, buf, len); // Copy receibed data
// Update rx_rd_ptr
rd_ptr.lVal += len;
write_4reg(rd_ptr.cVal, RX_RD_PTR(s,0));
idmw(COMMAND(s), CRECV); // RECV
ret = len;
ErrReturn:
dv03_enable();
return (ret);
}
/*
*********************************************************************************************************
* Channel closing function.
*
* Description : Function for closing the connection of the designated channel.
* Arguments : s - channel number
* Returns : None
* Note : API Function
*********************************************************************************************************
*/
void SOCK_close(SOCKET s)
{
xdata u16 len;
xdata u8 wait_count = 30;
lan_enable();
I_STATUS[s] = 0;
if (select(s, SEL_CONTROL) == SOCK_CLOSED) goto ENDOFMODULE; // Already closed
while(wait_count--)
{
len = select(s, SEL_SEND); // Get free buffer size
if (len == SSIZE[s]) // If the buffer is empty, we can close socket
{
idmw(COMMAND(s), CCLOSE); // CLOSE
//while(!(I_STATUS[s] & SCLOSED))printf("close:Wait");
goto ENDOFMODULE;
}
}
#ifdef DEBUG_SOCK
printf("\n\rSOCK_close: sock=%d still data in tx buffer", (int)s);
#endif
idmw(COMMAND(s), CCLOSE); // STEVE : ADD
ENDOFMODULE:;
dv03_enable();
}
/*
*********************************************************************************************************
* 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
*********************************************************************************************************
*/
u16 SOCK_select(SOCKET s, u8 func)
{
u16 ret;
lan_enable();
ret = select(s, func);
dv03_enable();
return ret;
}
#ifdef DEBUG_LANRPT
/*
//==============================================================================
//
//==============================================================================
void SOCK_dump_config(void)
{
lan_enable();
printf("\n\rW3100 Configuration Registers");
// IR (0x08) Interrupt Register
// IMR (0x09) Interrupt Mask Register
printf("\n\rIR=0x%02x IMR=0x%02x", (u16)idmr(INT_REG), (u16)idmr(INTMASK));
// GAR (0x80-0x83) Gateway Addr Register
printf("\n\rGAR=%u.%u.%u.%u",
(u16)idmr(GATEWAY_PTR(0)),
(u16)idmr(GATEWAY_PTR(1)),
(u16)idmr(GATEWAY_PTR(2)),
(u16)idmr(GATEWAY_PTR(3)));
// SMR (0x84-0x87) Subnet Mask Register
printf("\n\rSMR=%u.%u.%u.%u",
(u16)idmr(SUBNET_MASK_PTR(0)),
(u16)idmr(SUBNET_MASK_PTR(1)),
(u16)idmr(SUBNET_MASK_PTR(2)),
(u16)idmr(SUBNET_MASK_PTR(3)));
// SHAR (0x88-0x8D) Source Hardware Address Register
printf("\n\rSHAR=%02x:%02x:%02x:%02x:%02x:%02x",
(u16)idmr(SRC_HA_PTR(0)),
(u16)idmr(SRC_HA_PTR(1)),
(u16)idmr(SRC_HA_PTR(2)),
(u16)idmr(SRC_HA_PTR(3)),
(u16)idmr(SRC_HA_PTR(4)),
(u16)idmr(SRC_HA_PTR(5)));
// SIPR (0x8E-0x91) Source IP address Register
printf("\n\rSIPR=%u.%u.%u.%u",
(u16)idmr(SRC_IP_PTR(0)),
(u16)idmr(SRC_IP_PTR(1)),
(u16)idmr(SRC_IP_PTR(2)),
(u16)idmr(SRC_IP_PTR(3)));
// IRTR (0x92-0x93) Initial Retry Time-value Register
// RCR (0x94) Retry Counter Register
printf("\n\rIRTR=0x%02x%02x (07D0) RCR=0x%02x (6)",
(u16)idmr(TIMEOUT_PTR(0)),
(u16)idmr(TIMEOUT_PTR(1)),
(u16)idmr(RETRYCNT_PTR));
// RMSR (0x95) Rx Memory Size Register
// TMSR (0x96) Tx Memory Size Register
printf("\n\rRMSR=0x%02x TMSR=0x%02x (ch3:ch2:ch1:ch0)", (u16)idmr(RX_DMEM_SIZE), (u16)idmr(TX_DMEM_SIZE));
dv03_enable();
}
*/
void SOCK_dump_channel(u8 i)
{
u8 k;
union un_l2cval wr_ptr, ack_ptr, rd_ptr;
lan_enable();
printf("\n\rW3100 CHANNEL - %d", (int)i);
// CR : Command Register
// ISR : Interrupt Status Register
printf("\n\rCmdR=0x%02x ISR=0x%02x(.:Rx:Tx:To:Co:Es:Op:.)",
(u16)idmr(COMMAND(i)),
(u16)idmr(INT_STATUS(i)));
// SSR : Socket Status Register
// SOPR : Socket Option Protocol Register
printf("\n\rSSR=0x%02x SOPR=0x%02x",
(u16)idmr(SOCK_STATUS(i)),
(u16)idmr(OPT_PROTOCOL(i)));
// DIR : Destination IP address Register
// DPR : Destination Port Register
printf("\n\rDestIP=%u.%u.%u.%u DestPort=0x%02x%02x",
(u16)idmr(DST_IP_PTR(i,0)),
(u16)idmr(DST_IP_PTR(i,1)),
(u16)idmr(DST_IP_PTR(i,2)),
(u16)idmr(DST_IP_PTR(i,3)),
(u16)idmr(DST_PORT_PTR(i,0)),
(u16)idmr(DST_PORT_PTR(i,1)));
// SPR : Source Port Register
// IPR : IP Protocol Register
printf("\n\rSrcPort=0x%02x%02x IPprotocolField(IPrawMode)=0x%02x",
(u16)idmr(SRC_PORT_PTR(i,0)),
(u16)idmr(SRC_PORT_PTR(i,1)),
(u16)idmr(IP_PROTOCOL(i)));
// TOSR : Type Of Service Register
// MSSR : Max Segment Size Register
// printf("\n\rTOS=0x%02x (0), MaxSegSize=0x%04x", (u16)idmr(TOS(i)), (u16)idmr(MSS(i)));
// RW_PR : Rx Write Pointer Register
disable();
k = idmr(SHADOW_RXWR_PTR(i));
wait_1us(2);
wr_ptr.cVal[0] = idmr(RX_WR_PTR(i,0));
wr_ptr.cVal[1] = idmr(RX_WR_PTR(i,1));
wr_ptr.cVal[2] = idmr(RX_WR_PTR(i,2));
wr_ptr.cVal[3] = idmr(RX_WR_PTR(i,3));
enable();
printf("\n\rRx WP=%08lx",wr_ptr.lVal);
// RR_PR : Rx Read Pointer Register
disable();
k = idmr(SHADOW_RXRD_PTR(i));
wait_1us(2);
rd_ptr.cVal[0] = idmr(RX_RD_PTR(i,0));
rd_ptr.cVal[1] = idmr(RX_RD_PTR(i,1));
rd_ptr.cVal[2] = idmr(RX_RD_PTR(i,2));
rd_ptr.cVal[3] = idmr(RX_RD_PTR(i,3));
enable();
printf("\n\rRx RP=%08lx",rd_ptr.lVal);
// TA_PR : Tx Ack Pointer Register
disable();
k = idmr(SHADOW_TXACK_PTR(i));
wait_1us(2);
ack_ptr.cVal[0] = idmr(TX_ACK_PTR(i,0));
ack_ptr.cVal[1] = idmr(TX_ACK_PTR(i,1));
ack_ptr.cVal[2] = idmr(TX_ACK_PTR(i,2));
ack_ptr.cVal[3] = idmr(TX_ACK_PTR(i,3));
enable();
printf("\n\rTx AK=%08lx",ack_ptr.lVal);
// TW_PR : Tx Write Pointer Register
disable();
k = idmr(SHADOW_TXWR_PTR(i));
wait_1us(2);
wr_ptr.cVal[0] = idmr(TX_WR_PTR(i,0));
wr_ptr.cVal[1] = idmr(TX_WR_PTR(i,1));
wr_ptr.cVal[2] = idmr(TX_WR_PTR(i,2));
wr_ptr.cVal[3] = idmr(TX_WR_PTR(i,3));
enable();
printf("\n\rTx WP=%08lx",wr_ptr.lVal);
// TR_PR : Tx Read Pointer Register
disable();
k = idmr(SHADOW_TXRD_PTR(i));
wait_1us(2);
rd_ptr.cVal[0] = idmr(TX_RD_PTR(i,0));
rd_ptr.cVal[1] = idmr(TX_RD_PTR(i,1));
rd_ptr.cVal[2] = idmr(TX_RD_PTR(i,2));
rd_ptr.cVal[3] = idmr(TX_RD_PTR(i,3));
enable();
printf("\n\rTx RP=%08lx",rd_ptr.lVal);
dv03_enable();
}
#endif
#ifdef DEBUG_DUMPWIZBUF
void wiznet_mem_test(void)
{
u16 ptr,i;
static u8 tbuf[20];
u8 ch;
ptr = (u16)bufaddr_h;
ptr = (ptr<<8)|bufaddr_l;
lan_enable();
disable();
// set memory as test mode.
idmw(0x0001, 0x80);
// read buffer
for(i=0;i<20;i++) tbuf[i] = idmr(ptr+i);
// set memory as mornal mode.
idmw(0x0001, 0x80);
enable();
dv03_enable();
if(
(tbuf[0]!=0xf7)||
(tbuf[12]==0x00)||
(tbuf[13]==0x00)||
(tbuf[19]!=0x0f)
)
{
printf("\n\r%04x: ", ptr);
for(i=0;i<20;i++) printf("%02x ", (u16)tbuf[i]);
}
}
#endif
//######################################################################################################
//
// S T A T I C P R O C E D U R E S
//
//######################################################################################################
/*
*********************************************************************************************************
* 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
*********************************************************************************************************
*/
u16 select(SOCKET s, u8 func)
{
xdata union un_l2cval rd_ptr, wr_ptr;
xdata union un_l2cval ack_ptr;
xdata u16 val;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -