// Shawn Nematbakhsh - network eBlock // modified from Phillip/Arun's 8051 web server //======================================================================= // Phillip Hoang // Arun Gupta // May 31, 2001 //======================================================================= // Version 1 // This code is a complete working version. // It sets up the UDP/IP/Ethernet Headers. // It also has the LCD and temperature components. // There is an while(1) loop that cycles through // reading the temperature, displaying it on the LCD, // and then sending the UDP/IP/Ethernet packet. // The Ethernet address is the MAC address. //======================================================================= #pragma SMALL DB OE #include #include "io4.h" #include "tmp_rec.h" //======================================================================= // network controller data #define addr P2 #define data P1 /* 7 6 5 4 3 2 1 0 +-----+-----+-----+-----+----+----+----+----+ addr | N/A | N/A | RST | AEN | A3 | A2 | A1 | A0 | +-----+-----+-----+-----+----+----+----+----+ */ //======================================================================= #define RxTxData 0x00 // Receive/Transmit data (port 0) #define RxTxData1 0x02 // Receive/Transmit data (port 1) #define TxCmd 0x04 // Transmit Command #define TxLength 0x06 // Transmit Length #define ISQ 0x08 // Interrupt status queue #define PPPtr 0x0a // PacketPage pointer #define PPData 0x0c // PacketPage data (port 0) #define PPData1 0x0e // PacketPage data (port 1) //======================================================================= // eBlock interface pins from PIC sbit EBLOCK_ERR = P3^0; sbit EBLOCK= P3^3; // LCD pins sbit write = P3^6; sbit read = P3^7; sbit aen = P2^4; sbit rst = P2^5; // keypad pins sbit ONE = 0x80; sbit TWO = 0x81; sbit THREE=0x82; sbit FOUR= 0x83; sbit FIVE= 0xa7; sbit SIX = 0xa6; sbit SEVEN=0xb1; //======================================================================= // function to check IP's inputted from the keypad. // Returns 1 if valud, 0 otherwise. // Places ip quad in ip[] if successful int validate(char buf[16],int on,int ip[4]) { int i; int ip_on=0; int val=0; for(i=0;i3) return 0; if(buf[i]=='.') { ip[ip_on++]=val; val=0; } else val=val*10+buf[i]-'0'; } if(ip_on!=3) return 0; ip[ip_on]=val; for(i=0;i<4;++i) if(ip[i]<0 || ip[i]>255) return 0; return 1; } // function to get input from keypad // returns index number of key pressed unsigned char key_scan(){ unsigned char i, j, temp1, temp2; while(1){ /* keep waiting for a key to be pressed */ for(i=0; i<4; i++){ /* Set each row to 0 */ //P1 = 0xff & ~(1<> j) & 1; if(j==4) temp1=FIVE; else if(j==5) temp1=SIX; else if(j==6) temp1=SEVEN; if(!temp1) { temp2 = i*4 + j - 4; return(temp2); } } } } } // Used to Read from the Data Bus unsigned char ioRead(unsigned char address) { unsigned char value; addr = (address&0x0f); aen = 1; aen = 0; read = 0; value = data; read = 1; return value; } // Used to write to the Data Bus void ioWrite(unsigned char address, unsigned char value) { data = value; addr = (address&0x0f); aen = 1; aen = 0; write = 0; write = 1; } //======================================================================= int main (void) { // conversion table for keypad inout unsigned char conv_table[] = { 1, 2, 3, 76 /*add*/, 4, 5, 6, 77 /*sub*/, 7, 8, 9, 12 /*mul*/, '.'-'0', 0, 11, 13 /*div*/ }; int i,j; char buf[16]; int ip[4]; int on; int num; unsigned char BusST0, BusST1; unsigned char temperature; unsigned long sum; InitIO(); AGAIN: // code to get IP address from keypad ClearScreen(); on=0; while(on<16) { /*read input from user */ num = conv_table[key_scan()]; /* display corresponding number */ //P2 = SetDisplay(num); // 11 = enter character if(num==11) break; else { PutChar(num+'0'); buf[on++]=num+'0'; } // delay routine for(i=0;i<1000;++i)for(j=0;j<50;++j); // skip over to second section of LCD if necessary if(on==8) GotoXY(1,0); } ClearScreen(); // check IP if(validate(buf,on,ip)) // valid, continue PrintString("GOOD IP"); else { // invalid, try again PrintString("BAD IP"); for(i=0;i<1000;++i)for(j=0;j<100;++j); ClearScreen(); PrintString("TRY AGAI"); GotoXY(1,0); PrintString("N IDIOT"); for(i=0;i<1000;++i)for(j=0;j<100;++j); goto AGAIN; } //////////////////////////////////////////////////////////// // Initialize Registers //////////////////////////////////////////////////////////// // Configure RxCTL fo Promiscious mode, RxOK // (1) Write 0x0104 to PacketPage Pointer // (2) Write 0x0180 to PacketPage Data Port ioWrite(PPPtr, 0x04); ioWrite(PPPtr + 1, 0x01); ioWrite(PPData, 0x80); ioWrite(PPData + 1, 0x01); // Set 10BaseT, SerRxOn, SerTxOn in LineCTL // (1) Write 0x0112 to PacketPage Pointer // (2) Write 0x00c0 to PacketPage Data Port ioWrite(PPPtr, 0x12); ioWrite(PPPtr + 1, 0x01); ioWrite(PPData, 0xc0); ioWrite(PPData + 1, 0x00); //////////////////////////////////////////////////////////// // Transmit //////////////////////////////////////////////////////////// while(1) { // checksum sum=0; // temperature = PrintTemperature(); // Send the transmit command ioWrite(TxCmd, 0xc0); ioWrite(TxCmd + 1, 0x00); // 60 bytes to be sent ioWrite(TxLength, 0x3c); ioWrite(TxLength + 1, 0x00); // BusST ioWrite(PPPtr, 0x38); ioWrite(PPPtr + 1, 0x01); // Bid for transmit do { BusST0 = ioRead(PPData); BusST1 = ioRead(PPData+1); }while(!(BusST1==0x01)); ///////////////////////////////////// // Ethernet Header ///////////////////////////////////// // Send Destination (6 bytes) // MAC address of Router of Embedded Systems Lab (00-00-1d-bc-79-d7) ioWrite(RxTxData, 0x00); ioWrite(RxTxData+1, 0x01); ioWrite(RxTxData, 0x30); ioWrite(RxTxData+1, 0xf4); ioWrite(RxTxData, 0xa6); ioWrite(RxTxData+1, 0xc0); //ioWrite(RxTxData, 0x52); //ioWrite(RxTxData+1, 0x54); //ioWrite(RxTxData, 0xab); //ioWrite(RxTxData+1, 0xdd); //ioWrite(RxTxData, 0x2e); //ioWrite(RxTxData+1, 0x78); // Send Source (6 bytes) // MAC address of my laptop (00-00-86-45-b7-b2) // this is arbitrary ioWrite(RxTxData, 0x00); ioWrite(RxTxData+1, 0x03); ioWrite(RxTxData, 0x47); ioWrite(RxTxData+1, 0x43); ioWrite(RxTxData, 0x13); ioWrite(RxTxData+1, 0x09); // Send Protocol Type (2 bytes) // 0x0806 (ARP) // 0x0800 (IP) ioWrite(RxTxData, 0x08); ioWrite(RxTxData+1, 0x00); ///////////////////////////////////// // IP Header ///////////////////////////////////// // Version Header Length (1 byte) // Using IPv4 ioWrite(RxTxData, 0x45); // Service (1 byte) // Normally set to zero because not used ioWrite(RxTxData+1, 0x00); sum+=0x4500; // Length (2 bytes) // 33 byte length ioWrite(RxTxData, 0x00); ioWrite(RxTxData+1, 0x1d); sum+=0x001d; // Identifier (2 bytes) // 0x0000 ioWrite(RxTxData, 0x3a); ioWrite(RxTxData+1, 0x27); sum+=0x3a27; // Flags Fragment offset (2 bytes) // 0x4000 ioWrite(RxTxData, 0x00); ioWrite(RxTxData+1, 0x00); sum+=0x0000; // Time to Live (1 byte) // 63 ioWrite(RxTxData, 0x80); // Protocol (1 byte) // ICMP (1), TCP (6), UDP (17) // UDP 0x11 = 17 ioWrite(RxTxData+1, 0x11); sum+=0x8011; sum+=0x8a17; sum+=0xae33; sum+=(ip[0]*(unsigned long)256)+ip[1]; sum+=(ip[2]*(unsigned long)256)+ip[3]; sum=(sum & 0x0000ffff)+(sum>>16); sum=(~sum) & 0x0000ffff; // Checksum (2 bytes) // 0xb273 // Checksum is 0xffffh - the sum of all IP header info //ioWrite(RxTxData, 0x90); //ioWrite(RxTxData+1, 0x1a); /* DEBUG ==================== */ ioWrite(RxTxData, sum>>8); ioWrite(RxTxData+1, sum&0x000000ff); // Source Address (4 bytes) // IP address 138.23.204.32 (arbitrary) // again, arbitrary ioWrite(RxTxData, 138); // 138 ioWrite(RxTxData+1, 23); // 23 ioWrite(RxTxData, 174); // 204 ioWrite(RxTxData+1, 51); // 32 // Destination Address (4 bytes) // IP address 138.23.169.9 (hill //ioWrite(RxTxData, 138); // 138 //ioWrite(RxTxData+1, 23); // 23 //ioWrite(RxTxData, 174); // 169 //ioWrite(RxTxData+1, 44); // 9 // destination, read from keypad ioWrite(RxTxData, ip[0]); // 138 ioWrite(RxTxData+1, ip[1]); // 23 ioWrite(RxTxData, ip[2]); // 169 ioWrite(RxTxData+1, ip[3]); // 9 ///////////////////////////////////// // UDP Header ///////////////////////////////////// // Source Port (2 bytes) // Port 47098 (b7fa) ioWrite(RxTxData, 0x0e); ioWrite(RxTxData+1, 0xcd); // Destination Port (2 bytes) // Port 4950 (1356h) ioWrite(RxTxData, 0x13); ioWrite(RxTxData+1, 0x56); // Message Length (2 bytes) // 13 bytes going to be sent ioWrite(RxTxData, 0x00); ioWrite(RxTxData+1, 0x09); // Checksum (2 bytes) // 0x0000 (no checksum used) ioWrite(RxTxData, 0x00); ioWrite(RxTxData+1, 0x00); // Write Message //ioWrite(RxTxData, temperature ); if(EBLOCK_ERR && !EBLOCK) // ff = error signal ioWrite(RxTxData,0xff); else // otherwise send 0/1 depending // on eblock input ioWrite(RxTxData,EBLOCK); ioWrite(RxTxData+1, 't'); ioWrite(RxTxData, 'e'); ioWrite(RxTxData+1, 'm'); ioWrite(RxTxData, 'p'); ioWrite(RxTxData+1, 0x00); // fill out packet for(i=0;i<6;++i) { ioWrite(RxTxData,0x00); ioWrite(RxTxData+1,0x00); } } return 0; }