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

📄 ethernet.c

📁 阿根廷教授编写的嵌入式internet的实验教程的高质量代码
💻 C
字号:
/******************************************************************************************
   Ethernet.c (v1.0)
-------------------------------------------------------------------------------------
This code is from the book:
"Embedded Internet: TCP/IP Basics, Implementation and Applications" by Sergio Scaglia
[Pearson Education, 2006 - ISBN: 0-32-130638-4]

This code is copyright (c) 2006 by Sergio Scaglia, and it may only be used for educational
purposes.  For commercial use, please contact me at sscaglia@intramarket.com.ar
For more information and updates, please visit www.embeddedinternet.org
******************************************************************************************/

#include "stack.h"
#include "Ethernet.h"
#include <iolpc2129.h>
#include <string.h>
#include <stdio.h>	


/* CS8900 PacketPage I/O Port Definitions  */
#define pp_RxTxData	    0x00	// Receive/Transmit data Port 0
#define pp_TxCmd	    0x04	// Transmit Command
#define pp_TxLen	    0x06	// Transmit Length
#define pp_Ptr	            0x0A	// PacketPage Pointer
#define pp_Data0	    0x0C	// PacketPage Data Port 0


/* CS8900 PacketPage Internal Registers  */
#define pp_RxCFG	    0x0102	// Receiver Configuration
#define pp_RxCTL	    0x0104	// Receiver Control
#define pp_LineCTL	    0x0112	// Line Control
#define pp_SelfCTL          0x0114	// Self Control
#define pp_TestCTL	    0x0118	// Test Control
#define pp_RxEvent	    0x0124	// Receiver Event
#define pp_SelfStatus       0x0136	// Self Status
#define pp_BusStatus	    0x0138 	// Bus Status
#define pp_IndividualA      0x0158	// Individual Address


char rx_buf[PACKET_BUF_SIZE];
char tx_buf[PACKET_BUF_SIZE];
char MyMAC[6] = MyMACAddress;
char MyIP[4]  = MyIPAddress;			       // device IPv4 address	
char Gateway[4] = GatewayAddress;
char SubNetMask[4] = SubNetMaskAddress;


/***************************************/
/* CS8900 Ethernet Private Functions  */
/***************************************/

char CS8900_read_port(char port_address) {
  char port_data;

  IO0CLR = SAB;					// Clear Address lines		
  IO0SET = (port_address<<4) & SAB;		// Set Address lines
  IO0CLR = IOR;				        // IOR=0 - Enable Read 		
  port_data = ((IO0PIN & SDB)>>16);		// Read Data from CS8900
  IO0SET = IOR;				        // IOR=1 - Disable Read
  return port_data;				// Return Data
}


void CS8900_write_port(char port_address, char port_data) {

  IO0DIR |= SDB;			        // SD7-SD0 as Outputs - Data lines
  IO0CLR = SDB;		                        // Clear Data lines		
  IO0SET = (port_data<<16);			// Set Data lines
  IO0CLR =  SAB;				// Clear Address lines
  IO0SET = (port_address<<4) & SAB;		// Set Address lines
  IO0CLR = IOW;			                // IOW=0 - Enable Write
  IO0SET = IOW;			                // IOW=1 - Disable Write
  IO0DIR &= (~SDB);      	                // SD7-SD0 as Inputs - Data lines
}


unsigned short CS8900_read_reg(unsigned short reg_address) {

  CS8900_write_port(pp_Ptr, (reg_address & 0x0FF)); 			    // Write Packet Page pointer - Lower byte
  CS8900_write_port(pp_Ptr+1, ((reg_address>>8) & 0x0FF));		    // Write Packet Page pointer - Higher byte
  return ((CS8900_read_port(pp_Data0+1)<<8) + CS8900_read_port(pp_Data0));  // Read Data Port 0 and return
}


void CS8900_write_reg(unsigned short reg_address, unsigned short reg_data)
{
  CS8900_write_port(pp_Ptr, (reg_address & 0x0FF)); 			    // Write Packet Page pointer - Lower byte
  CS8900_write_port(pp_Ptr+1, ((reg_address>>8) & 0x0FF));		    // Write Packet Page pointer - Higher byte
  CS8900_write_port(pp_Data0, (reg_data & 0x0FF));			    // Write Packet Page Data Port 0 - Lower byte
  CS8900_write_port(pp_Data0+1, ((reg_data>>8) & 0x0FF));		    // Write Packet Page Data Port 0 - Higher byte
}


void frame_send(unsigned short len) {
  unsigned short i, j=0xFFFF;

  if (len > PACKET_BUF_SIZE) {		//len exceeds maximum ethernet frame length
    printf("Ethernet: maximum frame length exceeded\n");
    return;
  }
  CS8900_write_port(pp_TxCmd, 0xC0);
  CS8900_write_port(pp_TxCmd+1, 0x00);
  CS8900_write_port(pp_TxLen, (len & 0xFF));
  CS8900_write_port(pp_TxLen+1, ((len>>8) & 0xFF));			
  do {
    j--;
  } while(!((CS8900_read_reg(pp_BusStatus) & 0x0100)) && j>0);
  if (j == 0) {
    printf("Ethernet: CS8900 not ready to accept a frame!\n");
    return;
  }
  for(i=0; i<len; i+=2) {
    CS8900_write_port(pp_RxTxData, tx_buf[i]);
    CS8900_write_port(pp_RxTxData+1, tx_buf[i+1]);
  }
}


#if debug_ethernet
void frame_display(unsigned short len) {
  unsigned short i, j;

  printf("Frame Received - Length: %d bytes\r\n", len);
  printf("Destination:    %02x-%02x-%02x-%02x-%02x-%02x\r\n", FRAMEr->destination[0], FRAMEr->destination[1],
        						FRAMEr->destination[2], FRAMEr->destination[3],
							FRAMEr->destination[4], FRAMEr->destination[5]);
	
  printf("Source:         %02x-%02x-%02x-%02x-%02x-%02x\r\n", FRAMEr->source[0], FRAMEr->source[1],
	        				        FRAMEr->source[2], FRAMEr->source[3],
							FRAMEr->source[4], FRAMEr->source[5]);

  printf("Type:           %04x\r\n", HTONS(FRAMEr->protocol));
  printf("Data:\r\n     ");
  j=0;
  for(i=14; i<len; i++) {
    printf("%02x ", rx_buf[i]);
    j++;
    if (j==16) {
      j=0;
      printf("\r\n     ");
    }
  }
  printf("\r\n----------------------------------------------------\r\n");
}
#endif //debug_ethernet


unsigned short frame_get(void) {
  char header[4];
  unsigned short RxLength;
  unsigned short i;

  header[0] = CS8900_read_port(pp_RxTxData + 1);
  header[1] = CS8900_read_port(pp_RxTxData);
  header[2] = CS8900_read_port(pp_RxTxData + 1);
  header[3] = CS8900_read_port(pp_RxTxData);
  RxLength = (header[2]<<8) + header[3];
  if (RxLength > PACKET_BUF_SIZE) {			// Skip Frame
    CS8900_write_reg(pp_RxCFG, (CS8900_read_reg(pp_RxCFG) | 0x0040));	   // Set Skip bit in RxCFG register
    return 0;
  }
  for(i=0; i<RxLength; i+=2) {
    rx_buf[i]   = CS8900_read_port(pp_RxTxData);
    rx_buf[i+1] = CS8900_read_port(pp_RxTxData + 1);
  }
#if debug_ethernet
  frame_display(RxLength);	
#endif  // debug_ethernet
  return RxLength;
}


void frame_process(void) {

  if (frame_get() == 0)
    return;
  switch (HTONS(FRAMEr->protocol)) {
    case ARP_PROTOCOL:
      //arp_process();		 ARP module Not yet implemented...
      break;
    case IP_PROTOCOL:
      //  ip_process();		 IP module Not yet implemented...
      break;
  }
}


/***************************************/
/*   Ethernet Public Functions         */
/***************************************/
void ethernet_init(void) {
  unsigned short ret;

  /* Define pin directions */
  IO0DIR |= (SAB | IOR |IOW);	        // SA3-SA0, IOR, and IOW as Outputs
  IO0DIR &= (~SDB);      	 	// SD7-SD0 as Inputs
  IO0SET = IOW | IOR;			// Set IOR=IOW=1

  /* Reset the CS8900A */
  CS8900_write_reg(pp_SelfCTL, 0x0040);

  while(!(CS8900_read_reg(pp_SelfStatus) & 0x0080));  // wait for INITD=1 indicating CS8900 Reset Ok

  /* Load parameters */
  CS8900_write_reg(pp_LineCTL, 0x0000);	      // Clear all bits for 10Base-T
  CS8900_write_reg(pp_TestCTL, 0x4000);	      // Set Full-Duplex bit
  CS8900_write_reg(pp_RxCTL, 0x0D00);	      // Set RXOkA, IndividualA, BroadcastA bits
  CS8900_write_reg(pp_RxCFG, 0x0000);	      // Clear BufferCRC bit

  /* Load MAC Address */
  CS8900_write_reg(pp_IndividualA,   (MyMAC[1]<<8) + MyMAC[0]);
  CS8900_write_reg(pp_IndividualA+2, (MyMAC[3]<<8) + MyMAC[2]);
  CS8900_write_reg(pp_IndividualA+4, (MyMAC[5]<<8) + MyMAC[4]);

  /* Enable Transmitter and Receiver  */
  ret = CS8900_read_reg(pp_LineCTL) | 0x00C0;	        // Set TxOn and RxOn bits
  CS8900_write_reg(pp_LineCTL, ret);			// in Line Control Register
}


void ethernet_poll(void) {

   if ((CS8900_read_reg(pp_RxEvent) & 0x0100)) {	// if RxOK bit set, there is a frame
	 frame_process();
   }
}


void ethernet_send(unsigned short protocol, unsigned short len) {

   memset(FRAMEt->destination, 0xFF, 6);	//we use the Broadcast address
   memcpy(FRAMEt->source, MyMAC, 6);
   FRAMEt->protocol = HTONS(protocol);
   frame_send(len + (sizeof(struct ethernet_hdr)));	
}

⌨️ 快捷键说明

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