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

📄 ethmod.c

📁 pic单片机实现的TCP/IP协议
💻 C
📖 第 1 页 / 共 3 页
字号:
   printf("\r\n");
   data_L = 0x00;
   for(i=0;i<80;++i)
   {
      bin2hex(aux_data[i]);
      printf(" %c%c",high_char,low_char);
      if(++data_L == 0x10)
         {
            data_L = 0x00;
            printf("\r\n");
         }
   }
}

/******************************************************************
//*	Write to NIC Control Register
//******************************************************************/
void write_creg(int regaddr, int regdata)
{
    cregaddr = regaddr;
    cregdata = regdata;
    tocreg;
    iow_pin=0;/*bit_clear(iow_pin);*/
    delay_cycles(1);
    iow_pin=1;/*bit_set(iow_pin);*/
    fromcreg;
}
/******************************************************************
//*	Read From NIC Control Register
//******************************************************************/
char read_creg(int regaddr)
{
   fromcreg;
   cregaddr = regaddr;
   ior_pin=0;/*bit_clear(ior_pin);*/
   byte_read = input_d();
   ior_pin=1;/*bit_set(ior_pin);*/
   return(byte_read);
}
/******************************************************************
//*	Detect EEPROM Clock from RTL8019AS
//******************************************************************/
void clock_9346()
{
#asm
chk_is_lo:
   btfss EESK
   goto  chk_is_lo
chk_is_hi:
   btfsc EESK
   goto  chk_is_hi
#endasm
}
/******************************************************************
//*	Emulate the presence of a 9346 EEPROM
//******************************************************************/
void fakeout_9346()
{
char reps,clocks,datum;

#asm
movlw 0x02
movwf reps
reload:
bcf   EEDO
movlw 0x03     /*0x03=half duplex 0x07=full duplex*/
movwf datum
#endasm

start_bit:
clock_9346();
#asm
btfss EEDI
goto  start_bit
#endasm
clock_9346();
#asm
btfss EEDI
goto  start_bit
#endasm
clock_9346();
#asm
btfsc EEDI
goto  start_bit
movlw 0x06
movwf clocks
#endasm
addr:
clock_9346();
#asm
decfsz clocks,1
goto  addr
movlw 0x10
movwf clocks
bcf   C
#endasm
send:
clock_9346();
#asm
movf  datum,0
movwf PORTA
rrf   datum,1
decfsz clocks,1
goto  send
decfsz reps,1
goto  reload
bcf   EEDO
#endasm
}
/******************************************************************
//*	Handle Receive Ring Buffer Overrun
//*   No packets are recovered
//******************************************************************/
void overrun()
{
   read_creg(CR);
   data_L = byte_read;
   write_creg(CR,0x21);
   delay_ms(2);
   write_creg(RBCR0,0x00);
   write_creg(RBCR1,0x00);
   if(!bit_test(data_L,2))
      resend = 0;
   else if(bit_test(data_L,2))
      {
         read_creg(ISR);
         data_L = byte_read;
         if(bit_test(data_L,1) || bit_test(data_L,3))
            resend = 0;
         else
            resend = 1;
      }

   write_creg(TCR,0x02);
   write_creg(CR,0x22);
   write_creg(BNRY,rxstart);
   write_creg(CR,0x62);
   write_creg(CURR,rxstart);
   write_creg(CR,0x22);
   write_creg(ISR,0x10);
   write_creg(TCR,tcrval);
}
/******************************************************************
//*	Echo Packet Function
//*   This routine does not modify the incoming packet size and
//*   thus echoes the original packet structure.
//******************************************************************/
void echo_packet()
{
   write_creg(CR,0x22);
   write_creg(TPSR,txstart);
   write_creg(RSAR0,0x00);
   write_creg(RSAR1,0x40);
   write_creg(ISR,0xFF);
   write_creg(RBCR0,pageheader[enetpacketLenL] - 4 );
   write_creg(RBCR1,pageheader[enetpacketLenH]);
   write_creg(CR,0x12);

   txlen = make16(pageheader[enetpacketLenH],pageheader[enetpacketLenL]) - 4;
   for(i=0;i<txlen;++i)
      write_creg(RDMAPORT,packet[enetpacketDest0+i]);

   byte_read = 0;
   while(!bit_test(byte_read,RDC))
      read_creg(ISR);

   write_creg(TBCR0,pageheader[enetpacketLenL] - 4);
   write_creg(TBCR1,pageheader[enetpacketLenH]);
   write_creg(CR,0x24);
}
/******************************************************************
//*	Get A Packet From the Ring
//*   This routine removes a data packet from the receive buffer
//*   ring.
//******************************************************************/
void get_packet()
{
   /*execute Send Packet command to retrieve the packet*/
   write_creg(CR,0x1A);
   for(i=0;i<4;++i)
      {
         read_creg(RDMAPORT);
         pageheader[i] = byte_read;
      }
         rxlen = make16(pageheader[enetpacketLenH],pageheader[enetpacketLenL]);
         for(i=0;i<rxlen;++i)
            {
               read_creg(RDMAPORT);
               /*dump any bytes that will overrun the receive buffer*/
               if(i < 96)
                  packet[i] = byte_read;
            }
   while(!bit_test(byte_read,RDC))
      read_creg(ISR);

   write_creg(ISR,0xFF);

   /*process an ARP packet*/
   if(packet[enetpacketType0] == 0x08 && packet[enetpacketType1] == 0x06)
   {
      if(packet[arp_hwtype+1] == 0x01 &&
      packet[arp_prtype] == 0x08 && packet[arp_prtype+1] == 0x00 &&
      packet[arp_hwlen] == 0x06 && packet[arp_prlen] == 0x04 &&
      packet[arp_op+1] == 0x01 &&
      MYIP[0] == packet[arp_tipaddr] &&
      MYIP[1] == packet[arp_tipaddr+1] &&
      MYIP[2] == packet[arp_tipaddr+2] &&
      MYIP[3] == packet[arp_tipaddr+3] )
         arp();
   }
   /*process an IP packet*/
   else if(packet[enetpacketType0] == 0x08 && packet[enetpacketType1] == 0x00
          && packet[ip_destaddr] == MYIP[0]
          && packet[ip_destaddr+1] == MYIP[1]
          && packet[ip_destaddr+2] == MYIP[2]
          && packet[ip_destaddr+3] == MYIP[3])
   {
      if(packet[ip_proto] == PROT_ICMP)
         icmp();
      else if(packet[ip_proto] == PROT_UDP)
         udp();
      else if(packet[ip_proto] == PROT_TCP)
         tcp();
   }

}
/******************************************************************
//*	SETIPADDRS
//*   This function builds the IP header.
//******************************************************************/
void setipaddrs()
{
   /*move IP source address to destination address*/
   packet[ip_destaddr]=packet[ip_srcaddr];
   packet[ip_destaddr+1]=packet[ip_srcaddr+1];
   packet[ip_destaddr+2]=packet[ip_srcaddr+2];
   packet[ip_destaddr+3]=packet[ip_srcaddr+3];
   /*make ethernet module IP address source address*/
   packet[ip_srcaddr]=MYIP[0];
   packet[ip_srcaddr+1]=MYIP[1];
   packet[ip_srcaddr+2]=MYIP[2];
   packet[ip_srcaddr+3]=MYIP[3];
   /*move hardware source address to destinatin address*/
   packet[enetpacketDest0]=packet[enetpacketSrc0];
   packet[enetpacketDest1]=packet[enetpacketSrc1];
   packet[enetpacketDest2]=packet[enetpacketSrc2];
   packet[enetpacketDest3]=packet[enetpacketSrc3];
   packet[enetpacketDest4]=packet[enetpacketSrc4];
   packet[enetpacketDest5]=packet[enetpacketSrc5];
   /*make ethernet module mac address the source address*/
   packet[enetpacketSrc0]=MYMAC[0];
   packet[enetpacketSrc1]=MYMAC[1];
   packet[enetpacketSrc2]=MYMAC[2];
   packet[enetpacketSrc3]=MYMAC[3];
   packet[enetpacketSrc4]=MYMAC[4];
   packet[enetpacketSrc5]=MYMAC[5];

   /*calculate the IP header checksum*/
   packet[ip_hdr_cksum]=0x00;
   packet[ip_hdr_cksum+1]=0x00;

   hdr_chksum =0;
   hdrlen = (packet[ip_vers_len] & 0x0F) * 4;
   addr = &packet[ip_vers_len];
   cksum();
   chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
   packet[ip_hdr_cksum] = make8(chksum16,1);
   packet[ip_hdr_cksum+1] = make8(chksum16,0);
 }
/******************************************************************
//*	CHECKSUM CALCULATION ROUTINE
//******************************************************************/
void cksum()
{
      while(hdrlen > 1)
      {
         data_H=*addr++;
         data_L=*addr++;
         chksum16=make16(data_H,data_L);
         hdr_chksum = hdr_chksum + chksum16;
         hdrlen -=2;
      }
      if(hdrlen > 0)
      {
         data_H=*addr;
         data_L=0x00;
         chksum16=make16(data_H,data_L);
         hdr_chksum = hdr_chksum + chksum16;
      }
}
/******************************************************************
//*	Initialize the RTL8019AS
//******************************************************************/
void init_RTL8019AS()
{
  	ADCON1 = 0x06;		                  /*00000110	all digital to start*/
	ADCON0 = 0;
   set_tris_C(0x85);
   set_tris_A(0x00);
   bit_clear(EEDO);
   set_tris_B(0xE0);                   /* setup address lines*/
   cregaddr = 0x00;                    /* clear address lines*/
   fromcreg;                           /* address lines = input*/
   set_tris_E(0x00);                   /* setup IOW, IOR, RESET*/

   iow_pin=1;/*bit_set(iow_pin);                    disable IOW*/
   ior_pin=1;/*bit_set(ior_pin);                    disable IOR*/
   rst_pinb=1;/*it_set(rst_pin);                    put NIC in reset*/
   delay_ms(2);                        /* delay at least 1.6ms*/
   rst_pinb=0;/*bit_clear(rst_pin);                 /* disable reset line*/
   read_creg(RSTPORT);                 /* read contents of reset port*/
   write_creg(RSTPORT,byte_read);      /* do soft reset*/
   delay_ms(10);                       /* give it time*/
   read_creg(ISR);                     /* check for good soft reset*/
   if(!bit_test(byte_read,RST)){
      while(1){
      printf("INIT FAILED\n\r");
      }
   }

   write_creg(CR,0x21);       /*stop the NIC, abort DMA, page 0*/
   delay_ms(2);               /*make sure nothing is coming in or going out*/
   write_creg(DCR,dcrval);    /*0x58*/
   write_creg(RBCR0,0x00);    /*clear the DMA byte counters*/
   write_creg(RBCR1,0x00);
   write_creg(RCR,0x04);      /*accept broadcast packets  */
   write_creg(TPSR,txstart);  /*set transmit buffer start page */ 
   write_creg(TCR,0x02);
   write_creg(PSTART,rxstart);//set receive buffer start page*/
   write_creg(BNRY,rxstart);  /*initialize the boundary  */
   write_creg(PSTOP,rxstop);  /*set receive buffer stop page  */
   write_creg(CR,0x61);       /*stop NIC and change control register page */
   delay_ms(2);
   write_creg(CURR,rxstart);  /*write NIC MAC (hardware) address  */
   for(i=0;i<6;++i)
      write_creg(PAR0+i, MYMAC[i]);

   write_creg(CR,0xC1);      /*prepare to emulate 9346 EEPROM*/
   write_creg(CR9346,0xC0);
   write_creg(CR9346,0x40);

   fakeout_9346();           /*emulate the 9348 */
   delay_ms(10);

   write_creg(CR,0x21);      /*stop the NIC and go to home page */
   write_creg(DCR,dcrval);   /*set FIFO threshold, enable Send Packet Command, */
   write_creg(CR,0x22);      /*start NIC  */
   write_creg(ISR,0xFF);     /*clear interrupts*/
   write_creg(IMR,imrval);   /*unmask interrupts */
   write_creg(TCR,tcrval);   /*normal operation and enable CRC */
}
/******************************************************************
//*	MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN
//******************************************************************/
void main()
{
   init_RTL8019AS();
   synflag = 0;
   finflag = 0;
/******************************************************************
//*	Look for a packet in the receive buffer ring
//******************************************************************/
   while(1)
   {
      /*start the NIC*/
      write_creg(CR,0x22);

      /*wait for a good packet*/
      while(!bit_test(INT0));

      /*read the interrupt status register*/
      read_creg(ISR);

      /*if the receive buffer has been overrun*/
      if(bit_test(byte_read,OVW))
         overrun();

      /*if the receive buffer holds a good packet*/
      if(bit_test(byte_read,PRX))
         get_packet();

      /*make sure the receive buffer ring is empty*/
      /*if BNRY = CURR, the buffer is empty*/
         read_creg(BNRY);
         data_L = byte_read;
         write_creg(CR,0x62);
         read_creg(CURR);
         data_H = byte_read;
         write_creg(CR,0x22);
      /*buffer is not empty.. get next packet*/
         if(data_L != data_H)
            get_packet();

      /*reset the interrupt bits*/
      write_creg(ISR,0xFF);
   }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -