📄 ethernet_mini_driver.c
字号:
if(EIR & EIR_TXERIF == 1)
{
TXERIF = 0;
TXRTS = 1;
TXRTS = 0;
}
//TXIF = 0;
TXRTS = 1;
//do{
// temp = ECON1);
// }while((temp & ECON1_TXRTS) == 1);
//++tx_end;
////banksel(ERDPTL);
//ERDPTL= LOW_BYTE(tx_end);
//ERDPTH= HIGH_BYTE(tx_end);
//for(i=0;i<7;++i)
//tx_status[i]= rd_sram();
//temp = ESTAT);
//if((temp & ESTAT_TXABRT) == 1)
//printf("\r\nARP Request Transmission Aborted..");
//else
//printf("\r\nARP Request Sent..");
}
//******************************************************************
//* Perform ARP Response
//* This routine supplies a requesting computer with the
//* Ethernet modules's MAC (hardware) address.
//******************************************************************
void arp_reply(void)
{
unsigned int tx_end,i;
char temp;
tx_end = TXSTART;
//load beginning page for transmit buffer
//banksel(EWRPTL);
EWRPTL = LOW_BYTE(TXSTART);
EWRPTH = HIGH_BYTE(TXSTART);
//write control byte
wr_sram(tx_control_byte);
++tx_end;
//write destination MAC address
for(i=0;i<6;++i)
{
wr_sram(packet[enetpacketSrc0+i]);
++tx_end;
}
//write source MAC address
for(i=0;i<6;++i)
{
wr_sram(macaddrc[i]);
++tx_end;
}
//write typelen hwtype prtype hwlen prlen op:
addr = &packet[enetpacketType0];
packet[arp_op+1] = 0x02;
for(i=0;i<10;++i)
{
wr_sram(*addr++);
++tx_end;
}
//write ethernet module MAC address
for(i=0;i<6;++i)
{
wr_sram(macaddrc[i]);
++tx_end;
}
//write ethernet module IP address
for(i=0;i<4;++i)
{
wr_sram(ipaddrc[i]);
++tx_end;
}
//write remote MAC address
for(i=0;i<6;++i)
{
wr_sram(packet[enetpacketSrc0+i]);
++tx_end;
}
//write remote IP address
for(i=0;i<4;++i)
{
wr_sram(packet[arp_sipaddr+i]);
++tx_end;
}
//banksel(ETXNDL);
ETXNDL = LOW_BYTE(tx_end);
ETXNDH = HIGH_BYTE(tx_end);
//send the contents of the transmit buffer onto the network
//temp = EIR;
//if((temp & EIR_TXERIF) == 1)
if(TXERIF)
{
TXERIF = 0;
TXRST = 1;
TXRST = 0;
}
TXIF = 0;
TXRTS = 1;
//do{
//temp = ECON1);
//}while((temp & ECON1_TXRTS) == 1);
// while(1 == (ECON1 & ECON1_TXRTS));
while(TXRTS);
++tx_end;
//banksel(ERDPTL);
ERDPTL= LOW_BYTE(tx_end);
ERDPTH= HIGH_BYTE(tx_end);
//banksel(ERDPTL);
//ERDPTL= 0x00;
//ERDPTH= 0x00;
for(i=0;i<7;++i)
tx_status[i]= rd_sram();
//temp = ESTAT;
//if((temp & ESTAT_TXABRT) == 1)
if(TXABRT)
printf("\r\nARP Reply Transmission Aborted..");
//else
//printf("\r\nARP Reply Sent..");
}
//******************************************************************
//* Application Code
//* Your application code goes here.
//******************************************************************
void application_code()
{
char i,j;
if (aux_data[0] == 0x0D)
{
j = sizeof(telnet_banner);
for(i=0;i<j;++i)
packet[TCP_data+i] = telnet_banner[i];
tcpdatalen_out = j;
}
else
tcpdatalen_out = tcpdatalen_in;
}
//******************************************************************
//* TCP Function
//* This function uses TCP protocol to act as a Telnet server on
//* port 8088 decimal. The application function is called with
//* every incoming character.
//******************************************************************
void tcp()
{
char *bufferptr,temp,i,j;
unsigned int buffer_addr,tx_end,tx_cnt;
//assemble the destination port address from the incoming packet
portaddr = make16(packet[TCP_destport],packet[TCP_destport+1]);
//calculate the length of the data coming in with the packet
//tcpdatalen_in = incoming packet length - incoming ip header length - incoming tcp header length
tcpdatalen_in = (make16(packet[ip_pktlen],packet[ip_pktlen+1])) - ((packet[ip_vers_len] & 0x0F) * 4) - (((packet[TCP_hdrflags] & 0xF0) >> 4) * 4);
//If an ACK is recieved and the destination port address is valid and no data is in the packet
if(ACK_IN && portaddr == MY_PORT_ADDRESS && tcpdatalen_in == 0x00)
{
//assemble the acknowledgment number from the incoming packet
incoming_ack = make32(packet[TCP_acknum],packet[TCP_acknum+1],packet[TCP_acknum+2],packet[TCP_acknum+3]);
//if the incoming packet is a result of session establishment
if(bsynflag)
{
//clear the SYN flag
//the incoming acknowledgment is my new sequence number
clr_synflag;
my_seqnum = incoming_ack;
//send the Telnet server banner
//limit the character count to 40 decimal
j = sizeof(telnet_banner);
for(i=0;i<j;++i)
packet[TCP_data+i] = telnet_banner[i];
//length of the banner message
tcpdatalen_out = j;
//expect to get an acknowledgment of the banner message
expected_ack = my_seqnum +tcpdatalen_out;
//send the TCP/IP packet
send_tcp_packet();
}
}
//if an ack is received and the port address is valid and there is data in the incoming packet
if(ACK_IN && portaddr == MY_PORT_ADDRESS && tcpdatalen_in)
{
for(i=0;i<tcpdatalen_in;++i)
{
//receive the data and put it into the incoming data buffer
aux_data[i] = packet[TCP_data+i];
//run the TCP application
application_code();
}
//assemble the acknowledgment number from the incoming packet
incoming_ack =make32(packet[TCP_acknum],packet[TCP_acknum+1],packet[TCP_acknum+2],packet[TCP_acknum+3]);
//check for the number of bytes acknowledged
//determine how many bytes are outstanding and adjust the outgoing sequence number accordingly
if(incoming_ack <= expected_ack)
my_seqnum = expected_ack - (expected_ack - incoming_ack);
//my expected acknowledgement number
expected_ack = my_seqnum +tcpdatalen_out;
send_tcp_packet();
}
//this code segment processes the incoming SYN from the Telnet client
//and sends back the initial sequence number (ISN) and acknowledges
//the incoming SYN packet
if(SYN_IN && portaddr == MY_PORT_ADDRESS)
{
tcpdatalen_in = 0x01;
set_synflag;
setipaddrs();
temp = packet[TCP_srcport];
packet[TCP_srcport] = packet[TCP_destport];
packet[TCP_destport] = temp;
temp = packet[TCP_srcport+1];
packet[TCP_srcport+1] = packet[TCP_destport+1];
packet[TCP_destport+1] = temp;
assemble_ack();
if(++ISN == 0x0000 || ++ISN == 0xFFFF)
ISN = 0x1234;
my_seqnum = make32i(ISN,0xFFFF);
set_packet32(TCP_seqnum,my_seqnum);
packet[TCP_hdrflags+1] = 0x00;
SYN_OUT;
ACK_OUT;
packet[TCP_cksum] = 0x00;
packet[TCP_cksum+1] = 0x00;
hdr_chksum =0;
hdrlen = 0x08;
addr = &packet[ip_srcaddr];
cksum();
hdr_chksum = hdr_chksum + packet[ip_proto];
tcplen = make16(packet[ip_pktlen],packet[ip_pktlen+1]) - ((packet[ip_vers_len] & 0x0F) * 4);
hdr_chksum = hdr_chksum + tcplen;
hdrlen = tcplen;
addr = &packet[TCP_srcport];
cksum();
chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
packet[TCP_cksum] = make8(chksum16,1);
packet[TCP_cksum+1] = make8(chksum16,0);
tx_end = TXSTART;
//load beginning page for transmit buffer
//banksel(EWRPTL);
EWRPTL = LOW_BYTE(TXSTART);
EWRPTH = HIGH_BYTE(TXSTART);
//write control byte
wr_sram(tx_control_byte);
++tx_end;
tx_end = tx_end + rxlen;
//banksel(ETXNDL);
ETXNDL = LOW_BYTE(tx_end);
ETXNDH = HIGH_BYTE(tx_end);
tx_cnt = tx_end - TXSTART;
//for(buffer_addr=0;buffer_addr<tx_cnt;++buffer_addr)
//wr_sram(packet[enetpacketDest0 + buffer_addr]);
bufferptr = packet;
while(tx_cnt)
{
EDATA = *bufferptr;
bufferptr++;
tx_cnt--;
};
//send the contents of the transmit buffer onto the network
//temp = EIR;
if(1 == (EIR & EIR_TXERIF))
{
TXERIF = 0;
TXRTS = 1;
TXRTS = 0;
}
TXIF = 0;
TXRTS = 1;
//do{
// temp = ECON1);
// }while((temp & ECON1_TXRTS) == 1);
while(1 ==(ECON1 & ECON1_TXRTS));
//++tx_end;
////banksel(ERDPTL);
//ERDPTL= LOW_BYTE(tx_end);
//ERDPTH= HIGH_BYTE(tx_end);
//for(i=0;i<7;++i)
//tx_status[i]= rd_sram();
//temp = ESTAT);
//if(1 ==( ESTAT) & ESTAT_TXABRT))
printf("\r\nTCP Transmission Aborted..");
//else
//printf("\r\nTCP Message Sent..");
}
//this code segment processes a FIN from the Telnet client
//and acknowledges the FIN and any incoming data.
if(FIN_IN && portaddr == MY_PORT_ADDRESS)
{
if(tcpdatalen_in)
{
for(i=0;i<tcpdatalen_in;++i)
{
aux_data[i] = packet[TCP_data+i];
application_code();
}
}
set_finflag;
++tcpdatalen_in;
incoming_ack =make32(packet[TCP_acknum],packet[TCP_acknum+1],packet[TCP_acknum+2],packet[TCP_acknum+3]);
if(incoming_ack <= expected_ack)
my_seqnum = expected_ack - (expected_ack - incoming_ack);
expected_ack = my_seqnum +tcpdatalen_out;
send_tcp_packet();
}
}
//******************************************************************
//* Assemble the Acknowledgment
//* This function assembles the acknowledgment to send to
//* to the client by adding the received data count to the
//* client's incoming sequence number.
//******************************************************************
void assemble_ack()
{
client_seqnum=make32(packet[TCP_seqnum],packet[TCP_seqnum+1],packet[TCP_seqnum+2],packet[TCP_seqnum+3]);
client_seqnum = client_seqnum + tcpdatalen_in;
set_packet32(TCP_acknum,client_seqnum);
}
//******************************************************************
//* Send TCP Packet
//* This routine assembles and sends a complete TCP/IP packet.
//* 40 bytes of IP and TCP header data is assumed.
//******************************************************************
void send_tcp_packet()
{
char temp,i,*bufferptr;
unsigned int buffer_addr,tx_end,tx_cnt;
//count IP and TCP header bytes.. Total = 40 bytes
ip_packet_len = 40 + tcpdatalen_out;
packet[ip_pktlen] = make8(ip_packet_len,1);
packet[ip_pktlen+1] = make8(ip_packet_len,0);
setipaddrs();
temp = packet[TCP_srcport];
packet[TCP_srcport] = packet[TCP_destport];
packet[TCP_destport] = temp;
temp = packet[TCP_srcport+1];
packet[TCP_srcport+1] = packet[TCP_destport+1];
packet[TCP_destport+1] = temp;
assemble_ack();
set_packet32(TCP_seqnum,my_seqnum);
packet[TCP_hdrflags+1] = 0x00;
ACK_OUT;
if(bfinflag)
{
FIN_OUT;
clr_finflag;
}
packet[TCP_cksum] = 0x00;
packet[TCP_cksum+1] = 0x00;
hdr_chksum =0;
hdrlen = 0x08;
addr = &packet[ip_srcaddr];
cksum();
hdr_chksum = hdr_chksum + packet[ip_proto];
tcplen = ip_packet_len - ((packet[ip_vers_len] & 0x0F) * 4);
hdr_chksum = hdr_chksum + tcplen;
hdrlen = tcplen;
addr = &packet[TCP_srcport];
cksum();
chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
packet[TCP_cksum] = make8(chksum16,1);
packet[TCP_cksum+1] = make8(chksum16,0);
txlen = ip_packet_len + 14;
if(txlen < 60)
txlen = 60;
tx_end = TXSTART;
//load beginning page for transmit buffer
//banksel(EWRPTL);
EWRPTL = LOW_BYTE(TXSTART);
EWRPTH = HIGH_BYTE(TXSTART);
//write control byte
wr_sram(tx_control_byte);
++tx_end;
tx_end = tx_end + txlen;
//banksel(ETXNDL);
ETXNDL = LOW_BYTE(tx_end);
ETXNDH = HIGH_BYTE(tx_end);
tx_cnt = tx_end - TXSTART;
//for(buffer_addr=0;buffer_addr<tx_cnt;++buffer_addr)
//wr_sram(packet[enetpacketDest0 + buffer_addr]);
bufferptr = packet;
while(tx_cnt)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -