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

📄 ethernet_mini_driver.c

📁 利用 pic18f67j60 单片机来实现10M IP网络的连接
💻 C
📖 第 1 页 / 共 5 页
字号:

	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 + -