?? w3100a.c
字號:
* Note : API Function
********************************************************************************
*/
static int select(SOCKET s, unsigned char func)
{
unsigned int val;
un_l2cval rd_ptr,wr_ptr,ack_ptr;
unsigned char k;
switch(func){
case SEL_CONTROL:
val = SOCK_STATUS(s);
break;
case SEL_SEND:
//sci0_print("case SEL_SEND\r\n");
set_imask_ccr(1);
k = *SHADOW_TXWR_PTR(s);
wait_1us(2);
wr_ptr.cVal[0] = *TX_WR_PTR(s);
wr_ptr.cVal[1] = *(TX_WR_PTR(s) + 1);
wr_ptr.cVal[2] = *(TX_WR_PTR(s) + 2);
wr_ptr.cVal[3] = *(TX_WR_PTR(s) + 3);
if( (OPT_PROTOCOL(s)& 0x07) != SOCK_STREAM)
{
k = *SHADOW_TXRD_PTR(s);
wait_1us(2);
ack_ptr.cVal[0] = *TX_RD_PTR(s);
ack_ptr.cVal[1] = *(TX_RD_PTR(s) + 1);
ack_ptr.cVal[2] = *(TX_RD_PTR(s) + 2);
ack_ptr.cVal[3] = *(TX_RD_PTR(s) + 3);
}
else
{
k = *SHADOW_TXACK_PTR(s);
wait_1us(2);
ack_ptr.cVal[0] = *TX_ACK_PTR(s);
ack_ptr.cVal[1] = *(TX_ACK_PTR(s) + 1);
ack_ptr.cVal[2] = *(TX_ACK_PTR(s) + 2);
ack_ptr.cVal[3] = *(TX_ACK_PTR(s) + 3);
}
set_imask_ccr(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);
break;
case SEL_RECV:
//sci0_print("case SEL_RECV\r\n");
set_imask_ccr(1);
k = *SHADOW_RXWR_PTR(s);
wait_1us(2);
wr_ptr.cVal[0] = *RX_WR_PTR(s);
wr_ptr.cVal[1] = *(RX_WR_PTR(s) + 1);
wr_ptr.cVal[2] = *(RX_WR_PTR(s) + 2);
wr_ptr.cVal[3] = *(RX_WR_PTR(s) + 3);
k = *SHADOW_RXRD_PTR(s);
wait_1us(2);
rd_ptr.cVal[0] = *RX_RD_PTR(s);
rd_ptr.cVal[1] = *(RX_RD_PTR(s) + 1);
rd_ptr.cVal[2] = *(RX_RD_PTR(s) + 2);
rd_ptr.cVal[3] = *(RX_RD_PTR(s) + 3);
set_imask_ccr(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;
break;
default:
val = -1;
break;
}
return (val);
}
/*
********************************************************************************
* Channel closing function.
*
* Description : Function for closing the connection of the designated channel.
* Arguments : s - channel number
* Returns : None
* Note : API Function
********************************************************************************
*/
void close(SOCKET s)
{
unsigned int len;
if (select(s, SEL_CONTROL) == SOCK_CLOSED) return; // Already closed
// When closing, if there's data which have not processed, Insert some source codes to handle this
// Or before application call close(), handle those data first and call close() later.
len = select(s, SEL_SEND);
if (len == SSIZE[s])
{
//I_STATUS[s] =0; //killed by brucelyang
COMMAND(s) = CCLOSE; // CLOSE
//while(!(I_STATUS[s] & SCLOSED)); //killed by brucelyang for interrupt
}
}
/*
********************************************************************************
* Function for sending TCP data.
*
* Description : Function for sending TCP data and Composed of the send() and send_in() functions.
* The send() function is an application I/F function.
* It continues to call the send_in() function to complete the sending of the data up to the size of the data to be sent
* when the application is called.
* The send_in() function receives the return value (the size of the data sent), calculates the size of the data to be sent,
* and calls the send_in() function again if there is any data left to be sent.
* Arguments : s - channel number
* buf - Pointer pointing data to send
* len - data size to send
* Returns : Succeed: sent data size, Failed: -1;
* Note : API Function
********************************************************************************
*/
int tcp_write(SOCKET s,unsigned char* buf,int len)
{
int ptr, size;
if (len <= 0) return 0;
else
{
ptr = 0;
do {
size = send_in(s, buf + ptr, len);
if (size == -1)
{
sci0_print("tcp_write error\r\n");
return -1;
} // Error
len = len - size;
ptr += size;
} while ( len > 0);
}
return 0;
}
/*
********************************************************************************
* Internal function for sending TCP data.
*
* Description : Called by the 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
********************************************************************************
*/
static int send_in(SOCKET s, unsigned char *buf, int len)
{
unsigned char k;
int size,size1,i;
un_l2cval wr_ptr, ack_ptr;
unsigned char *send_ptr;
S_START:
set_imask_ccr(1);
k = *SHADOW_TXWR_PTR(s); // Must read the shadow register for reading 4byte pointer registers
wait_1us(2); // wait for reading 4byte pointer registers safely
wr_ptr.cVal[0] = *TX_WR_PTR(s);
wr_ptr.cVal[1] = *(TX_WR_PTR(s) + 1);
wr_ptr.cVal[2] = *(TX_WR_PTR(s) + 2);
wr_ptr.cVal[3] = *(TX_WR_PTR(s) + 3);
k = *SHADOW_TXACK_PTR(s); // Must read the shadow register for reading 4byte pointer registers
wait_1us(2); // wait for reading 4byte pointer registers safely
ack_ptr.cVal[0] = *TX_ACK_PTR(s);
ack_ptr.cVal[1] = *(TX_ACK_PTR(s) + 1);
ack_ptr.cVal[2] = *(TX_ACK_PTR(s) + 2);
ack_ptr.cVal[3] = *(TX_ACK_PTR(s) + 3);
set_imask_ccr(0);
// Calculate send free buffer size
if (wr_ptr.lVal >= ack_ptr.lVal) size = SSIZE[s] - (wr_ptr.lVal - ack_ptr.lVal);
else size = SSIZE[s] - (0 - ack_ptr.lVal + wr_ptr.lVal);
if (size > SSIZE[s]) // Recalulate after some delay because of error in pointer caluation
{
if (select(s, SEL_CONTROL) != SOCK_ESTABLISHED) return -1; // Error
wait_1us(1000);
WATCH_DOG;
goto S_START;
}
if (size == 0) // Wait when previous sending has not finished yet and there's no free buffer
{
if (select(s, SEL_CONTROL) != SOCK_ESTABLISHED) return -1; // Error
wait_1us(1000);
WATCH_DOG;
goto S_START;
}
else if (size < len) len = size;
send_ptr = (unsigned char *)( SBUFBASEADDRESS[s] + (unsigned int)(wr_ptr.lVal & SMASK[s])); // Calculate pointer to data copy
//write_data(s, buf, send_ptr, len); // data copy
////////////////////added by brucelyang 2005.12.21///////////////////////////
if ( (((unsigned int)send_ptr & SMASK[s]) + len) > SSIZE[s] )
{
size = SSIZE[s] - ((unsigned int)send_ptr & SMASK[s]);
for (i = 0; i < size; i++) *send_ptr++ = *buf++;
size1 = len - size;
send_ptr = (SBUFBASEADDRESS[s]);
for (i = 0; i < size1; i++) *send_ptr++ = *buf++;
}
else
for (i = 0; i < len; i++) *send_ptr++ = *buf++;
/////////////////////end of brucelyang 2005.12.21////////////////////////////
while (COMMAND(s) & CSEND) // Confirm send command
{
if (select(s, SEL_CONTROL) != SOCK_ESTABLISHED) return -1; // Error
WATCH_DOG;
}
wr_ptr.lVal = wr_ptr.lVal + len; // tx_wr_ptr update
*TX_WR_PTR(s) = wr_ptr.cVal[0];
*(TX_WR_PTR(s) + 1) = wr_ptr.cVal[1];
*(TX_WR_PTR(s) + 2) = wr_ptr.cVal[2];
*(TX_WR_PTR(s) + 3) = wr_ptr.cVal[3];
COMMAND(s) = CSEND; // SEND
//點亮RJ-45 LED add by wqf 2005.06.14
PF.DR.BIT.B2 = 0x00;
//初始化100ms計數器,開始計時
rj45led_flag = 1;
//清除計數個數
rj45led_time = 0;
//I have just sent a data,donn't close me -add by wqf 2005.05.31
wtm_time =0 ;//清除通信空閑時間計數
return (len);
}
/*
********************************************************************************
* UDP data sending function.
*
* Description : An internal function that is the same as the send_in() function of the TCP.
* Arguments : s - Channel number
* buf - Pointer indicating the data to send
* len - data size to send
* Returns : Sent data size
* Note : Internal Function
********************************************************************************
*/
int udp_write(SOCKET s,unsigned char *buf, int len)
{
unsigned char k;
unsigned int size;
un_l2cval wr_ptr, rd_ptr;
unsigned char * send_ptr;
S2_START:
if(select(s,SEL_CONTROL)==SOCK_CLOSED) return -1; // Error
set_imask_ccr(1);
k = *SHADOW_TXWR_PTR(s);
wait_1us(2);
wr_ptr.cVal[0] = *TX_WR_PTR(s);
wr_ptr.cVal[1] = *(TX_WR_PTR(s) + 1);
wr_ptr.cVal[2] = *(TX_WR_PTR(s) + 2);
wr_ptr.cVal[3] = *(TX_WR_PTR(s) + 3);
k = *SHADOW_TXRD_PTR(s);
wait_1us(2);
rd_ptr.cVal[0] = *TX_RD_PTR(s);
rd_ptr.cVal[1] = *(TX_RD_PTR(s) + 1);
rd_ptr.cVal[2] = *(TX_RD_PTR(s) + 2);
rd_ptr.cVal[3] = *(TX_RD_PTR(s) + 3);
set_imask_ccr(0);
// Calculate free buffer size to send
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);
if (size > SSIZE[s]) // Recalulate after some delay because of error in pointer caluation
{
wait_1us(1000);
goto S2_START;
}
if (size == 0) // Wait when previous sending has not finished yet and there's no free buffer
{
wait_1us(1000);
goto S2_START;
}
else if (size < len) len = size;
send_ptr = (unsigned char *)(SBUFBASEADDRESS[s] + (unsigned int)(wr_ptr.lVal & SMASK[s])); // Calculate pointer to copy data pointer
write_data(s, buf, send_ptr, len); // Copy data
// while (COMMAND(s) & CSEND) // Confirm previous send command
// if(select(s,SEL_CONTROL)==SOCK_CLOSED) return -1; // Error
wr_ptr.lVal = wr_ptr.lVal + len; // Update tx_wr_ptr
*TX_WR_PTR(s) = wr_ptr.cVal[0];
*(TX_WR_PTR(s) + 1) = wr_ptr.cVal[1];
*(TX_WR_PTR(s) + 2) = wr_ptr.cVal[2];
*(TX_WR_PTR(s) + 3) = wr_ptr.cVal[3];
COMMAND(s) = CSEND; // SEND
//點亮RJ-45 LED add by wqf 2005.06.14
PF.DR.BIT.B2 = 0x00;
//初始化100ms計數器,開始計時
rj45led_flag = 1;
//清除計數個數
rj45led_time = 0;
return (len);
}
//設為上下跳變都觸發
void irq6_DSR_init(void)
{
INTC.ISCR.BYTE.H = 0x30; /*IRQ6 interrupt request at both level low and high*/
INTC.ISR.BYTE = 0x00; /*clear interrupt flag*/
INTC.IER.BIT.IRQ6E = 0x01;
}
//先讀一下dsr狀態,以判斷上、下跳變?
void irq6_DSR(void)
{
INTC.ISR.BYTE = INTC.ISR.BYTE & ~0x40;
INTC.IER.BIT.IRQ6E = 0x00;
//if dtr==mm,and the mm is connect,then cut the connect
//sci0_print("irq6 \r\n");
///////////////////for virtual comm//////////////////////////
///////////////////add by brucelyang 2005.7.12///////////////
if(virtual_com == 1)
{
//DSR狀態線變化
if(PG.PORT.BIT.B0 == 0)
{
VtulCom_PreComConfig.THIRDBYTE.BIT.DSR = 0x01; //DSR有效
}
else
{
VtulCom_PreComConfig.THIRDBYTE.BIT.DSR = 0x00; //DSR無效
}
tcp_write(VTL_TCP_CONTROL_CHANNEL,(unsigned char *)&VtulCom_PreComConfig,5);
INTC.IER.BIT.IRQ6E = 0x01;
//set_imask_ccr(0);
return;
}
if(((tt_page1.Tdtr == 'H') || (tt_page1.Tdtr == 'h'))&&(PG.PORT.BIT.B0 == 1)&&(ethernet_status & TCP_SERVER_CHANNEL_ON))
{
//sci0_print("DTR=H and DSR is busy,close TCP\r\n");
close(TCP_SERVER_CHANNEL);
ethernet_status &= ~TCP_SERVER_CHANNEL_ON;
Ch_connect = ETH_OFF;
//打印提示信息, add by wqf 2005.6.6
Sel_prtmsg(0,"CLOSE COMPLETED\r\n");
//下一次允許連接計時開始
//wait_flag = 1;
//wait_connect_flag = 1;
//清除wtm的計時標志以及計數器
wtm_flag =0;
wtm_time = 0;
//熄滅LED,add by wqf 2005.06.03
PF.DR.BIT.B0 = 0x01;
PF.DR.BIT.B1 = 0x01;
}
if(((tt_page1.Tdtr > 0) && (tt_page1.Tdtr < 11))&&(PG.PORT.BIT.B0 == 1)&&(ethernet_status & TCP_CLIENT_CHANNEL_ON))
{
//sci0_print("DTR=nn and DSR is busy,close TCP\r\n");
close(TCP_CLIENT_CHANNEL);
ethernet_status &= ~TCP_CLIENT_CHANNEL_ON;
Ch_connect =ETH_OFF;
//add by wqf 2005.6.8
Sel_prtmsg(0,"TIME WAIT\r\n");
//下一次允許連接計時開始 add by wqf 2005.05.30
wait_flag = 1;
wait_connect_flag = 1;
//清除wtm的計時標志以及計數器 add by wqf 2005.05.31
wtm_flag =0;
wtm_time = 0;
//end of add by wqf
//熄滅LED,add by wqf 2005.06.03
PF.DR.BIT.B0 = 0x01;
PF.DR.BIT.B1 = 0x01;
}
//DSR輸入為有效時,與指定的IP建立TCP連接,add by wqf 2005.6.7
if((tt_page1.Tdtr > 0) && (tt_page1.Tdtr < 11) && (PG.PORT.BIT.B0 == 0) && (Ch_connect == ETH_OFF) && (Prog_Mode == 0))
{
//sci0_print("DSR is ready,TCP handle\r\n");
if(dtr_ready_flag == 0)
{
//sci0_print("1st time DTR is ready\r\n");
dtr_ready_flag = 1;
//return;
}
else
{
dtr_connect_flag = 1;
}
}
INTC.IER.BIT.IRQ6E = 0x01;
}
//設為上下跳變都觸發
void irq7_DCD_init(void)
{
INTC.ISCR.BYTE.H = INTC.ISCR.BYTE.H | 0xC0; /*IRQ7 interrupt request at both level low and high*/
INTC.ISR.BYTE = 0x00; /*clear interrupt flag*/
INTC.IER.BIT.IRQ7E = 0x01;
}
void irq1_CTS_init(void)
{
//INTC.IPRA.BYTE = 0x77; // IRQ0-CTS: 7, IRQ1-DSR: 7 //設置中斷優先級為最高,但是有疑問。IPRA~IPRO,IPRL分別對應哪幾個中斷呢??
// Sense Control, 11: Interrupt request generated at both falling and rising edges
INTC.ISCR.BIT.IRQ1SC = 0x03;//
INTC.ISR.BIT.IRQ1F=0; //clear 狀態位
INTC.IER.BIT.IRQ1E = 0x01; // Eable Interrupt IRQ1
}
void irq1_CTS(void)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -