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

📄 cp2200.c

📁 c8051f020_uip1.0.rar
💻 C
字号:
#include "main.h"
#include "cp220x_reg.h"



u8_t xdata my_hwaddr[6] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};  
MACADDRESS xdata MYMAC;
#define LINK_ERROR  0x20
/*******************************************************************************/
		    
void CP220x_RST_Low(void)			 
{
   P4 &= ~0x20;                        // Set P4.5 Low	    
}

void CP220x_RST_High(void)
{
   P4 |= 0x20;     
                                      // Set P4.5 High	    
}
/******************************************************************************
**物理层
******************************************************************************/		    
u8_t PHY_Init()			    
{
   u8_t temp_char;
   u8_t 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);	

   
      // 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
 
      // 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);	
  
      // 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
 

      //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  if(temp_char == ANCINT)
	  {
         // Check if Auto-Negotiation has PASSED   

         // Auto-Negotiation has passed		 
         retval = 0;
         // Enable Link LED and Activity LED                         
         IOPWR = 0x0C;   
      } 
	  
	  else 
      // Timeout Occured.   
      { 
          // Timeout    
         retval = LINK_ERROR; 
      }

      return retval;
     
}
/*---------------------------------------------------------------------------*/			  
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];	  
   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		 
																				 
}

void MAC_Write(u8_t mac_reg_offset, u16_t 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;
}


/*---------------------------------------------------------------------------*/
/*CP2200接收*/ 
void CP220x_Send(void)
{

   u16_t i; 
   u16_t ramaddr;
   u8_t *ptr;

   ptr = uip_buf;

    // 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 < uip_len; i++)
	  {
	     if(i==40+UIP_LLH_LEN)
		 {
		   ptr=(u8_t *)uip_appdata;	  //appdata
		 }
         RAMTXDATA = *ptr++;
         INC_RAMADDR
      }
      
      // Step 3e: Pad short packets	    
      while(ramaddr < 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;			   
	   

}
/*---------------------------------------------------------------------------*/
/*CP2200发送*/  
u16_t rcve_frame(void)

{
   bit rx_ok;		                    
   bit skip = 0;	                   
   UINT1 cplen;   	                    
   u16_t i;
  

   u8_t interrupt_read;        
   u8_t valid_bits;	         
   u8_t 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;                                      
	    for(num_packets = 0; valid_bits; num_packets++)      
        {                                 
              valid_bits &= valid_bits - 1; 			             
        }
   
        // If the receive buffer has 7 packets, then disable reception.		   
        if( num_packets >= 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;
	  	 
       } 
	   else 
	   {
           // Set packet length to zero	    
           cplen.Int = 0;
           // Skip packet	 
           skip = 1;      						 
	       return(cplen.Int); 
       }   

       // Step 3: Read the entire packet from the buffer 							
       // If packet will fit in the buffer		 
       if(1)
       {
      
          // Copy entire packet		  	
          for(i = 0; i < cplen.Int; i++)
	      {	   
            *(uip_buf + i)= RXAUTORD;	  
          }	
		  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	 
       } 								
       else 
       {
          RXCN |= 0x04;                   // Clear the valid bit only		 
       }								  

       // If there are no more packets in the receive buffer, enable reception			   
       if(TLBVALID == 0x00)
       {
          RXCN = 0x00;                   
       }
       // Return the number of bytes added to the buffer
    		 
       return(cplen.Int);	                									 
}
/*---------------------------------------------------------------------------*/
/*发送*/
void  etherdev_send(void)
{
    CP220x_Send();
}
/*---------------------------------------------------------------------------*/
/*接收*/
u16_t etherdev_read(void)
{

  return(rcve_frame());
}
/*---------------------------------------------------------------------------*/
/*初始化CP2200*/
void etherdev_init(void)
{
	 u8_t err_val;

     CP220x_RST_Low();
     Delay1ms(200);
     Delay1ms(200);
     CP220x_RST_High();
     Delay1ms(200);
     Delay1ms(200);

     INT0EN = 0x03;  /* CP2200  中断使能寄存器0*/     
                     /*1:允许接收FIFO满中断*/  	  
				     /*1:允许包接收中断。*/ 	      

             
     INT1EN = 0x00;  /*  CP2200   中断使能寄存器1*/     
                     /*CP2200   35/106    中文DATASHEET*/    
   
     /* Clear all Interrupt Flags by reading the self-clearing status registers*/                     
     /*temp_char = INT0;*/                      
     /*temp_char = INT1;*/  

     do
     {  
        err_val = PHY_Init();	  /*PHY初始化 等待完成*/
     }
     while(err_val!=0);

     Delay1ms(50);
     MAC_Init();    
     Delay1ms(50);

     ET2 = 1;		             /* Enable timer 2 interrupt*/	    
     RXCN = RXCLEAR;		 	 /*接收缓冲区清除 向该位写1将丢弃接收缓冲区中的所有包*/ 
	                             /*并将缓冲区指针和有效位清0。注:当前位于缓冲区中的*/ 
	                             /*任何包仍保留在存储器中,但所有信息如每个包的起始*/  
                        	     /*地址和长度都将丢失。任何新到达的包都会覆盖现有数据*/ 
}

⌨️ 快捷键说明

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