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

📄 etherdev.c

📁 c8051f020_uip1.0.rar
💻 C
字号:
#include "c8051f020.h"
#include "uip.h"
#include "uip_arp.h"
#include "cp2200.h"


/******************************************************************************
**复位CP2200
******************************************************************************/		    
void CP220x_RST_Low(void)				
{
   P4 &= ~0x20;                       // Set P4.5 Low	    
}

void CP220x_RST_High(void)
{
   P4 |= 0x20;     
                                      // Set P4.5 High	    
}
/******************************************************************************
**物理层PHY 初始化
******************************************************************************/		    
unsigned char PHY_Init()			    
{
   unsigned char temp_char;
   unsigned char retval =LINK_ERROR;
		    		 
   //--------------------------------------------------------------------------
   // Auto-Negotiation Synchronization (Section 15.2 of CP220x Datasheet)			  
   //--------------------------------------------------------------------------

   // Step 1: Disable the PHY	
   	 
      PHYCN = 0x00;  
   
   // Step 2: Enable the PHY with link integrity test and auto-negotiation 
   // turned off	   
      
      // A. Disable the Transmitter Power Save Option and Configure Options			   
      TXPWR = 0x80;
      PHYCF = ( SMSQ | JABBER | ADPAUSE | AUTOPOL );
      // B. Enable the Physical Layer	    
      PHYCN = PHYEN;
      Delay1ms(50);		//200--50
      Delay1ms(200);

      // C. Wait for the physical layer to power up		    
      // wait_ms(10);
      // D. Enable the Transmitter and Receiver		    
      PHYCN = ( PHYEN | TXEN | RXEN );
   
      //Step 3: Poll the Wake-on-Lan Interrupt	   
      Delay1ms(50);		//200--50
      Delay1ms(200);


      // A. Clear Interrupt Flags	   
      temp_char = INT1;

      // B. Start a new timeout for 1.5 seconds		   
      //reset_timeout(ONE_SECOND+ONE_SECOND/2);		    
      // C. Check for a signal		   
     
      // If no signal is deteced, wait 1.5s, then continue
	  /*		  
      if(timeout_expired())
	  {		 
         break;
      }		 
	  */
     			   
   //--------------------------------------------------------------------------
   // Physical Layer Initialization (Section 15.7 of CP220x Datasheet)			 
   //--------------------------------------------------------------------------
   
   // Step 1: Synchronization procedure implemented above		   
																  
   // Step 2: Disable the physical layer		    
   PHYCN = 0x00; 
  
   // Step 3: Configure the desired physical layer options including 
   // auto-negotiation and link integrity	    
   PHYCF = ( SMSQ | LINKINTG | JABBER | AUTONEG | ADPAUSE | AUTOPOL );
  
   // Step 4: Enable the physcial layer		 
      
   // A. Enable the Physical Layer		 
   PHYCN = PHYEN;
   Delay1ms(50);		//200--50
   Delay1ms(200);
// Delay1ms(200);
// B. Wait for the physical layer to power up		    
// wait_ms(10);

// C. Enable the Transmitter and Receiver		    
// Auto-negotiation begins now	   
   PHYCN = ( PHYEN | TXEN | RXEN );
  

   // Step 5: Wait for auto-negotiation to complete		    
   // Clear INT1 Interrupt Flags		 
   temp_char = INT1;
   Delay1ms(50);	 //200--50
   Delay1ms(200);

   //RXFILT=0;
   //Start a six second timeout		    
   //reset_timeout(6*ONE_SECOND);	   
   // Check for autonegotiation fail or complete flag		 
    while(1){
   // If Auto-Negotiation Completes/Fails, break		  
    if(INT1RD & (ANCINT | ANFINT)){					  
            break;            
    }
      }


      // Mask out all bits except for auto negotiation bits 
      temp_char = INT1RD;
      temp_char &= (ANCINT | ANFINT);

      // Check if Auto-Negotiation has FAILED 
      if(temp_char & ANFINT){
      
         // Auto-Negotiation has failed		  
         retval = LINK_ERROR;
		 
        
         } else 
   
        //Check if Auto-Negotiation has PASSED   
	        if(temp_char == ANCINT){
      
         // Auto-Negotiation has passed		 
         retval = 0;

         // Enable Link LED and Activity LED                         
         IOPWR = 0x0C;   
         
                           

      } else 
   
      // Timeout Occured.   
      { 
          // Timeout    
         retval = LINK_ERROR;
      }

   return retval;
     
}
/******************************************************************************			  
**		                    MAC初始化设置  										
******************************************************************************/			  
void MAC_Init(void)
{  

   // Check the duplex mode and perform duplex-mode specific initializations		   
   if(PHYCN & 0x10){
      
      // The device is in full-duplex mode, configure MAC registers			  
      // Padding is turned on.	   
      MAC_Write(MACCF, 0x40B3);	  
      MAC_Write(IPGT, 0x0015);
      
   } else {

      // The device is in half-duplex mode, configure MAC registers			  
      // Padding is turned off.	    
      MAC_Write(MACCF, 0x4012);
      MAC_Write(IPGT, 0x0012);

   }

   // Configure the IPGR register	   
   MAC_Write(IPGR, 0x0C12);

   // Configure the MAXLEN register to 1518 bytes		 
   MAC_Write(MAXLEN, 0x05EE);

   // Copy MAC Address Stored in Flash to MYMAC		   
   FLASHADDRH = 0x1F;
   FLASHADDRL = 0xFA;

   MYMAC.Char[0] = FLASHAUTORD;
   MYMAC.Char[1] = FLASHAUTORD;
   MYMAC.Char[2] = FLASHAUTORD;
   MYMAC.Char[3] = FLASHAUTORD;
   MYMAC.Char[4] = FLASHAUTORD;
   MYMAC.Char[5] = FLASHAUTORD;      
   my_hwaddr[0]=MYMAC.Char[0];	  //6字节MAC
   my_hwaddr[1]=MYMAC.Char[1];
   my_hwaddr[2]=MYMAC.Char[2];
   my_hwaddr[3]=MYMAC.Char[3];
   my_hwaddr[4]=MYMAC.Char[4];
   my_hwaddr[5]=MYMAC.Char[5];
   // Program the MAC address	   
   MAC_SetAddress(&MYMAC); 

   // Enable Reception and configure Loopback mode		   
   MAC_Write(MACCN, 0x0001);       // Enable Reception without loopback		 
																				 
}
/******************************************************************************			  
**MAC写入  										
******************************************************************************/
void MAC_Write(unsigned char mac_reg_offset, unsigned int mac_reg_data)
{

   // Step 1: Write the address of the indirect register to MACADDR.		  
   MACADDR = mac_reg_offset;              

   // Step 2: Copy the contents of <mac_reg_data> to MACDATAH:MACDATAL		    
   MACDATAH = (mac_reg_data >> 8);    // Copy High Byte	   
   MACDATAL = (mac_reg_data & 0xFF);  // Copy Low Byte	 

   // Step 3: Perform a write on MACRW to transfer the contents of MACDATAH:MACDATAL			 
   // to the indirect MAC register.		 
   MACRW = 0;
   
   return;
}


/*****************************************************************************
 MAC_SetAddress	   	

 Return Value : None	  
 Parameters   : 
   1)  MACADDRESS* pMAC - pointer to a 6-byte MAC address structure.			 
 
 Sets the current MAC address to the MAC address pointed to by <pMAC>.		   
*****************************************************************************/
void MAC_SetAddress(MACADDRESS* pMAC)
{
   UINT1 temp_int;

   temp_int.Char[0] = pMAC->Char[5];
   temp_int.Char[1] = pMAC->Char[4];
   MAC_Write(MACAD0, temp_int.Int);
   
   temp_int.Char[0] = pMAC->Char[3];
   temp_int.Char[1] = pMAC->Char[2];
   MAC_Write(MACAD1, temp_int.Int);
   
   temp_int.Char[0] = pMAC->Char[1];
   temp_int.Char[1] = pMAC->Char[0];
   MAC_Write(MACAD2, temp_int.Int);
   
   return;
}


/*******************************************************************************			  
**以太网数据发送		   
*******************************************************************************/			  

void CP220x_Send( UCHAR xdata *outbuf, UINT len)
{

   int i; 
   unsigned int ramaddr;

   // Define Macro to increment the RAM address Pointer		   
   #define INC_RAMADDR {ramaddr++; \
                        RAMADDRH = (ramaddr >> 8);\
                        RAMADDRL = (ramaddr & 0x00FF);}


   // Step 1: Poll TXBUSY until it becomes 0x00		   
   while(TXBUSY);

   // Step 2: Set the TXSTARTH:TXSTARTL address to 0x0000		  
   TXSTARTH = 0x00;
   TXSTARTL = 0x00;


   // Step 3: Load data into transmit buffer	   
   // When the random access method is used, we do not need to check for		   
   // aborted packets. This method will be slightly slower than the Autowrite			 
   // method, however, it reduces code space requirements.		   
  
      // Setup RAM Address Pointer To 0x0000	
      RAMADDRH = 0x00;
      RAMADDRL = 0x00;
      ramaddr = 0x0000;

      // Step 3d: Load the packet payload	    
      for(i = 0; i < len; i++){
	     
         RAMTXDATA = outbuf[i];
		 
         INC_RAMADDR
      }
      
      // Step 3e: Pad short packets	    
      while(ramaddr < 64){		   //将短包填充到至少64个字节     
         RAMTXDATA = 0;
         INC_RAMADDR
      }
      
      // Set the TXENDH:TXENDL address to <ramaddr - 1>		    
      ramaddr--;
      TXENDH = (ramaddr >> 8);
      TXENDL = (ramaddr & 0x00FF);

	 

   // Step 4: Set the TXSTARTH:TXSTARTL address back to 0x0000		    
   TXSTARTH = 0x00;
   TXSTARTL = 0x00;
   
   // Step 5: Write '1' to TXGO to begin transmission		  
   TXCN = 0x01;			  //:通过向TXGO位(TXCN.0)写1来启动发送。     
//   free(outbuf);	   

}
/**************************************************************************
从CP2200读出数据 
**************************************************************************/  
UCHAR xdata * rcve_frame(void)

{
   bit rx_ok;		                     //接收正确标记位 
   bit skip = 0;	                     //跳过包标记位
   UINT1 cplen;   	                     //包程度
   unsigned int i;
   UCHAR xdata * buf;	                 //指向XDATA外部存储器中的UCHAR型变量指针  

   unsigned char interrupt_read;         //中断读 
   unsigned char valid_bits;	         //有效位 
   unsigned char num_packets;	         //包数量 

   // Clear interrupt flags.	 
   interrupt_read = INT1;		         //清中断标记 
   interrupt_read = INT0;
   
   // Check for packet received interrupt	    
   if( interrupt_read & RXINT)
   {   
      // Count the number of packets in the receive buffer         
      // This is equal to the number of bits set to 1 in TLBVALID		   
      valid_bits = TLBVALID;                                      //TLB有效标记     
	    for(num_packets = 0; valid_bits; num_packets++)      
      {                                 
         valid_bits &= valid_bits - 1; 			                 //从第1个包开始 
      }
   
      // If the receive buffer has 7 packets, then disable reception.		   
      if( num_packets >= 7) 			                       //如果大于等于7个包 
      {
         RXCN = RXINH;           // Inhibit New Packet Reception	  
      }									       //就禁止接收 
   }								  

   // Step 1: Check the RXOK bit to see if packet was received correctly		   
   rx_ok = (CPINFOL & RXOK) && (CPINFOH & RXVALID);	  //检查是否接收了正确的包 

   // Step 2: If packet received correctly, read the length, otherwise, skip packet.			 
   if(rx_ok){
   
      // Read the packet length	               //是正确的包就读它的长度 	 
      cplen.Char[0] = CPLENH;
      cplen.Char[1] = CPLENL;
	  buf=inbuf1;			  //buf 局部变量 inbuf1 全局的 
	  
	  	
	 // buf = (UCHAR xdata *)malloc(cplen.Int);	    
                  
		 	
		 
   } else {
     
      // Set packet length to zero	     //如果不正确 就设置包长度0
      cplen.Int = 0;
      
      // Skip packet	 
      skip = 1;      
	  buf = NULL;						  //跳过包
	  return(buf); 
   }   

   // Step 3: Read the entire packet from the buffer 
   										//从BUFFER中读出完整的包 
   // If packet will fit in the buffer		 
   if(1)
      {
      
      // Copy entire packet		  		   //复制完整的包 
      for(i = 0; i < cplen.Int; i++)
	      {	   
         buf[i] = RXAUTORD;				  //RXfifo自动读 W/增量 
		
		
          }
	  		rcve_buf_allocated = TRUE;		
		    skip=0;

       }
else
   {

      // Set packet length to zero	    
      cplen.Int = 0;
      
      // Skip packet	  
      skip = 1; 
   }
      
   // Step 4: Skip the packet, or clear the valid bit if the entire packet			   
   // has been unloaded from the buffer.	   
   
   if(skip)
   {
      RXCN |= 0x02;                   // Skip the packet    RXSKIP	 
   } 								  //向该位写1将丢弃当前包,  
                                      //实际上是清除其有效位并将自动读缓冲 
									  //区指针前进到下一个包的开始位置。 

   else 
   {
      RXCN |= 0x04;                   // Clear the valid bit only		 
   }								  //向该位写1将清除当前包的有效位,  
                                      //释放缓冲区以接收新包。只有在当前包的 
									  //所有字节都被读取后(CPEND = 1)才 
									  //能执行该操作。如果当前包没有被读完, 
									  //则应使用RXSKIP来丢弃剩余字节。  

   // If there are no more packets in the receive buffer, enable reception			   
   if(TLBVALID == 0x00)
   {
      RXCN = 0x00;                    //如果没有包再接收就使能接收 
	                                  //RXCN复位值 00000000
   }
   
   // Return the number of bytes added to the buffer
    		 
   return(buf);	                      //返回加在BUFFER中的字节数量 											 
}

⌨️ 快捷键说明

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