├── .gitignore ├── README.md ├── SimpleLCD └── SimpleLCD.ino ├── libraries ├── ETHER_28J60 │ ├── examples │ │ ├── EchoParams │ │ │ └── EchoParams.pde │ │ ├── HelloWorld │ │ │ └── HelloWorld.pde │ │ ├── ServeReadings │ │ │ └── ServeReadings.pde │ │ └── WebRemote │ │ │ └── WebRemote.pde │ ├── keywords.txt │ ├── ETHER_28J60.h │ └── ETHER_28J60.cpp └── etherShield │ ├── keywords.txt │ ├── ip_arp_udp_tcp.h │ ├── etherShield.h │ ├── etherShield.cpp │ ├── net.h │ ├── enc28j60.h │ ├── enc28j60.c │ └── ip_arp_udp_tcp.c ├── Sensors └── Sensors.ino ├── popbotCircles ├── popbotCircles.ino └── bumper.ino ├── Servo └── Servo.ino ├── DhcpAddressPrinter └── DhcpAddressPrinter.ino ├── TestEthernet └── TestEthernet.ino ├── WebServer └── WebServer.ino └── simple_sensor └── simple_sensor.ino /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | arduino-projects 2 | ================ 3 | 4 | My Arduino Projects -------------------------------------------------------------------------------- /SimpleLCD/SimpleLCD.ino: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #define rxPin 17 4 | #define txPin 16 5 | 6 | SoftwareSerial mySerial = SoftwareSerial(rxPin,txPin); 7 | 8 | void setup() { 9 | digitalWrite(txPin,HIGH); 10 | delay(1000); 11 | pinMode(rxPin,INPUT); 12 | pinMode(txPin,OUTPUT); 13 | mySerial.begin(9600); 14 | delay(1000); 15 | } 16 | 17 | void loop() { 18 | mySerial.write(0xFE); 19 | mySerial.write(128); 20 | delay(10); 21 | mySerial.print("HI VITORIA"); 22 | mySerial.write(0xFE); 23 | mySerial.write(192); 24 | delay(10); 25 | mySerial.print("HI RAFAEL"); 26 | while(1); 27 | } 28 | -------------------------------------------------------------------------------- /libraries/ETHER_28J60/examples/EchoParams/EchoParams.pde: -------------------------------------------------------------------------------- 1 | #include "etherShield.h" 2 | #include "ETHER_28J60.h" 3 | 4 | int ledPin = 5; 5 | 6 | static uint8_t mac[6] = {0x54,0x55,0x58,0x10,0x00,0x24}; 7 | static uint8_t ip[4] = {192,168,1,15}; 8 | static uint16_t port = 80; 9 | 10 | ETHER_28J60 ethernet; 11 | 12 | void setup() 13 | { 14 | ethernet.setup(mac, ip, port); 15 | } 16 | 17 | void loop() 18 | { 19 | char* param; 20 | if (param = ethernet.serviceRequest()) 21 | { 22 | ethernet.print("

Arduino

"); 23 | ethernet.print("

"); 24 | ethernet.print(param); 25 | ethernet.print("

"); 26 | ethernet.respond(); 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /libraries/ETHER_28J60/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For ETHER_28J60 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | ETHER_28J60 KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | setup KEYWORD2 16 | serviceRequest KEYWORD2 17 | print KEYWORD2 18 | respond KEYWORD2 19 | 20 | # 21 | ####################################### 22 | # Constants (LITERAL1) 23 | ####################################### 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Sensors/Sensors.ino: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #define rxPin 17 5 | #define txPin 16 6 | 7 | SoftwareSerial lcd = SoftwareSerial(rxPin,txPin); 8 | 9 | int leftSensor; 10 | int rightSensor; 11 | 12 | void setup() { 13 | digitalWrite(txPin,HIGH); 14 | pinMode(txPin,OUTPUT); 15 | lcd.begin(9600); 16 | delay(1000); 17 | } 18 | 19 | void lcdCmd( int command ) { 20 | lcd.write(0xFE); 21 | lcd.write(command); 22 | delay(10); 23 | } 24 | 25 | void loop() { 26 | leftSensor = analogRead(7); 27 | rightSensor = analogRead(6); 28 | lcdCmd(0x80); 29 | lcd.print("L Sensor= "); 30 | lcdCmd(0x8a); 31 | lcd.print(leftSensor,DEC); 32 | 33 | lcdCmd(0xC0); 34 | lcd.print("R Sensor= "); 35 | lcdCmd(0xCA); 36 | lcd.print(rightSensor,DEC); 37 | 38 | delay(200); 39 | } 40 | -------------------------------------------------------------------------------- /popbotCircles/popbotCircles.ino: -------------------------------------------------------------------------------- 1 | 2 | //void setup() { 3 | // pinMode(3,OUTPUT); // Motor A1 4 | // pinMode(5,OUTPUT); // Motor A2 5 | // pinMode(6,OUTPUT); // Motor B2 6 | // pinMode(9,OUTPUT); // Motor B1 7 | // pinMode(2,INPUT); // Switch Left 8 | // pinMode(4,INPUT); // Switch Right 9 | //} 10 | 11 | void forward(int lSpeed, int rSpeed) { 12 | analogWrite(3,lSpeed); 13 | digitalWrite(5,LOW); 14 | analogWrite(6,rSpeed); 15 | digitalWrite(9,LOW); 16 | } 17 | 18 | void motorStop() { 19 | digitalWrite(3,LOW); 20 | digitalWrite(5,LOW); 21 | digitalWrite(6,LOW); 22 | digitalWrite(9,LOW); 23 | } 24 | 25 | void backward() { 26 | digitalWrite(3,LOW); 27 | digitalWrite(5,HIGH); 28 | digitalWrite(6,LOW); 29 | digitalWrite(9,HIGH); 30 | } 31 | 32 | //void loop() { 33 | // forward(50,100); 34 | // if(digitalRead(4)==0) { 35 | // motorStop(); 36 | // while(1); 37 | // } 38 | //// delay(1000); 39 | //// Backward(); 40 | //// delay(1000); 41 | //} 42 | -------------------------------------------------------------------------------- /popbotCircles/bumper.ino: -------------------------------------------------------------------------------- 1 | 2 | void setup() { 3 | pinMode(3,OUTPUT); // Motor A1 4 | pinMode(5,OUTPUT); // Motor A2 5 | pinMode(6,OUTPUT); // Motor B2 6 | pinMode(9,OUTPUT); // Motor B1 7 | 8 | pinMode(15,INPUT); // Left switch 9 | pinMode(17,INPUT); // Right switch 10 | } 11 | 12 | void loop() { 13 | forward(150); 14 | if(digitalRead(15)==0) { 15 | backward(150);delay(500); 16 | spinRight(200);delay(400); 17 | } 18 | if(digitalRead(17)==0) { 19 | backward(150);delay(400); 20 | spinLeft(200);delay(400); 21 | } 22 | } 23 | 24 | /*** functions ***/ 25 | 26 | void forward(int speed) { 27 | analogWrite(3,speed); 28 | digitalWrite(5,LOW); 29 | analogWrite(6,speed); 30 | digitalWrite(9,LOW); 31 | } 32 | 33 | void backward(int speed) { 34 | analogWrite(5,speed); 35 | digitalWrite(3,LOW); 36 | analogWrite(9,speed); 37 | digitalWrite(6,LOW); 38 | } 39 | 40 | void spinLeft(int speed) { 41 | analogWrite(5,speed); 42 | digitalWrite(3,LOW); 43 | analogWrite(6,speed); 44 | digitalWrite(9,LOW); 45 | } 46 | 47 | void spinRight(int speed) { 48 | analogWrite(3,speed); 49 | digitalWrite(5,LOW); 50 | analogWrite(9,speed); 51 | digitalWrite(6,LOW); 52 | } 53 | 54 | -------------------------------------------------------------------------------- /libraries/etherShield/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Matrix 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | EtherShield KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | ES_fill_tcp_data_p KEYWORD2 16 | ES_fill_tcp_data KEYWORD2 17 | ES_enc28j60Init KEYWORD2 18 | ES_enc28j60clkout KEYWORD2 19 | ES_enc28j60PhyWrite KEYWORD2 20 | ES_enc28j60PacketReceive KEYWORD2 21 | ES_init_ip_arp_udp_tcp KEYWORD2 22 | ES_eth_type_is_arp_and_my_ip KEYWORD2 23 | ES_make_arp_answer_from_request KEYWORD2 24 | ES_eth_type_is_ip_and_my_ip KEYWORD2 25 | ES_make_echo_reply_from_request KEYWORD2 26 | ES_make_tcp_synack_from_syn KEYWORD2 27 | ES_init_len_info KEYWORD2 28 | ES_get_tcp_data_pointer KEYWORD2 29 | ES_make_tcp_ack_from_any KEYWORD2 30 | ES_make_tcp_ack_with_data KEYWORD2 31 | ES_make_arp_request KEYWORD2 32 | ES_arp_packet_is_myreply_arp KEYWORD2 33 | ES_tcp_client_send_packet KEYWORD2 34 | ES_tcp_get_dlength KEYWORD2 35 | 36 | ####################################### 37 | # Constants (LITERAL1) 38 | ####################################### 39 | 40 | -------------------------------------------------------------------------------- /Servo/Servo.ino: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #define rxPin 17 5 | #define txPin 16 6 | 7 | SoftwareSerial lcd = SoftwareSerial(rxPin,txPin); 8 | int oldI,i=1500,j=0,k; 9 | 10 | void setup() { 11 | pinMode(8,OUTPUT); 12 | pinMode(7,OUTPUT); 13 | pinMode(14,OUTPUT); 14 | pinMode(2,INPUT); 15 | pinMode(4,INPUT); 16 | pinMode(txPin,OUTPUT); 17 | lcd.begin(9600); 18 | delay(1000); 19 | i=1560; 20 | 21 | // digitalWrite(txPin,HIGH); 22 | // delay(1000); 23 | // pinMode(rxPin,INPUT); 24 | } 25 | 26 | void loop() { 27 | if(digitalRead(2)==0) { 28 | if(i<2500) { 29 | i+=20; 30 | } else { 31 | beep(); 32 | } 33 | } 34 | if(digitalRead(4)==0) { 35 | if(i>400) { 36 | i-=20; 37 | } else { 38 | beep(); 39 | } 40 | } 41 | 42 | if(i!=oldI) { 43 | lcdCmd(0x01); 44 | lcd.print(i,DEC); 45 | oldI = i; 46 | } 47 | digitalWrite(7,HIGH); 48 | digitalWrite(8,HIGH); 49 | delayMicroseconds(i); 50 | digitalWrite(7,LOW); 51 | digitalWrite(8,LOW); 52 | delay(20); 53 | } 54 | 55 | void lcdCmd( int command ) { 56 | lcd.write(0xFE); 57 | lcd.write(command); 58 | delay(10); 59 | } 60 | 61 | 62 | void beep() { 63 | int i; 64 | for(i=0;i<600;i++) { 65 | digitalWrite(14,HIGH); 66 | delayMicroseconds(150); 67 | digitalWrite(14,LOW); 68 | delayMicroseconds(150); 69 | } 70 | } 71 | 72 | -------------------------------------------------------------------------------- /libraries/ETHER_28J60/examples/HelloWorld/HelloWorld.pde: -------------------------------------------------------------------------------- 1 | // A simple web server that always just says "Hello World" 2 | 3 | #include "etherShield.h" 4 | #include "ETHER_28J60.h" 5 | 6 | static uint8_t mac[6] = {0x54, 0x55, 0x58, 0x10, 0x00, 0x24}; // this just needs to be unique for your network, 7 | // so unless you have more than one of these boards 8 | // connected, you should be fine with this value. 9 | 10 | static uint8_t ip[4] = {192, 168, 1, 15}; // the IP address for your board. Check your home hub 11 | // to find an IP address not in use and pick that 12 | // this or 10.0.0.15 are likely formats for an address 13 | // that will work. 14 | 15 | static uint16_t port = 80; // Use port 80 - the standard for HTTP 16 | 17 | ETHER_28J60 ethernet; 18 | 19 | void setup() 20 | { 21 | ethernet.setup(mac, ip, port); 22 | } 23 | 24 | void loop() 25 | { 26 | if (ethernet.serviceRequest()) 27 | { 28 | ethernet.print("

Hello World

"); 29 | ethernet.respond(); 30 | } 31 | delay(100); 32 | } 33 | 34 | -------------------------------------------------------------------------------- /libraries/ETHER_28J60/ETHER_28J60.h: -------------------------------------------------------------------------------- 1 | /* 2 | ETHER_28J60.h - Ethernet library 3 | Copyright (c) 2010 Simon Monk. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef ETHER_28J60_h 21 | #define ETHER_28J60_h 22 | 23 | #include 24 | 25 | class ETHER_28J60 26 | { 27 | public: 28 | void setup(uint8_t macAddress[], uint8_t ipAddress[], uint16_t port); 29 | char* serviceRequest(); // returns a char* containing the requestString 30 | // or NULL if no request to service 31 | void print(char* text); // append the text to the response 32 | void print(int value); // append the number to the response 33 | void respond(); // write the final response 34 | private: 35 | uint16_t _port; 36 | 37 | }; 38 | 39 | #endif 40 | 41 | -------------------------------------------------------------------------------- /libraries/ETHER_28J60/examples/ServeReadings/ServeReadings.pde: -------------------------------------------------------------------------------- 1 | // A simple web server that always just says "Hello World" 2 | 3 | #include "etherShield.h" 4 | #include "ETHER_28J60.h" 5 | 6 | static uint8_t mac[6] = {0x54, 0x55, 0x58, 0x10, 0x00, 0x24}; // this just needs to be unique for your network, 7 | // so unless you have more than one of these boards 8 | // connected, you should be fine with this value. 9 | 10 | static uint8_t ip[4] = {192, 168, 1, 15}; // the IP address for your board. Check your home hub 11 | // to find an IP address not in use and pick that 12 | // this or 10.0.0.15 are likely formats for an address 13 | // that will work. 14 | 15 | static uint16_t port = 80; // Use port 80 - the standard for HTTP 16 | 17 | ETHER_28J60 e; 18 | 19 | void setup() 20 | { 21 | e.setup(mac, ip, port); 22 | } 23 | 24 | void loop() 25 | { 26 | if (e.serviceRequest()) 27 | { 28 | e.print("

Analog Values


"); 29 | e.print(""); 30 | for (int i = 0; i < 6; i++) 31 | { 32 | e.print(""); 33 | } 34 | e.print("
InputValue
"); e.print(i); e.print(""); e.print(analogRead(i)); e.print("
"); 35 | e.respond(); 36 | } 37 | delay(100); 38 | } 39 | 40 | -------------------------------------------------------------------------------- /DhcpAddressPrinter/DhcpAddressPrinter.ino: -------------------------------------------------------------------------------- 1 | /* 2 | DHCP-based IP printer 3 | 4 | This sketch uses the DHCP extensions to the Ethernet library 5 | to get an IP address via DHCP and print the address obtained. 6 | using an Arduino Wiznet Ethernet shield. 7 | 8 | Circuit: 9 | * Ethernet shield attached to pins 10, 11, 12, 13 10 | 11 | created 12 April 2011 12 | modified 9 Apr 2012 13 | by Tom Igoe 14 | 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | // Enter a MAC address for your controller below. 21 | // Newer Ethernet shields have a MAC address printed on a sticker on the shield 22 | byte mac[] = { 23 | 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 }; 24 | 25 | // Initialize the Ethernet client library 26 | // with the IP address and port of the server 27 | // that you want to connect to (port 80 is default for HTTP): 28 | EthernetClient client; 29 | 30 | void setup() { 31 | // Open serial communications and wait for port to open: 32 | Serial.begin(9600); 33 | // this check is only needed on the Leonardo: 34 | // while (!Serial) { 35 | // ; // wait for serial port to connect. Needed for Leonardo only 36 | // } 37 | 38 | // start the Ethernet connection: 39 | if (Ethernet.begin(mac) == 0) { 40 | Serial.println("Failed to configure Ethernet using DHCP"); 41 | // no point in carrying on, so do nothing forevermore: 42 | for(;;) 43 | ; 44 | } 45 | // print your local IP address: 46 | Serial.print("My IP address: "); 47 | for (byte thisByte = 0; thisByte < 4; thisByte++) { 48 | // print the value of each byte of the IP address: 49 | Serial.print(Ethernet.localIP()[thisByte], DEC); 50 | Serial.print("."); 51 | } 52 | Serial.println(); 53 | } 54 | 55 | void loop() { 56 | 57 | } 58 | 59 | 60 | -------------------------------------------------------------------------------- /libraries/ETHER_28J60/examples/WebRemote/WebRemote.pde: -------------------------------------------------------------------------------- 1 | // A simple web server that always just says "Hello World" 2 | 3 | #include "etherShield.h" 4 | #include "ETHER_28J60.h" 5 | 6 | int outputPin = 6; 7 | 8 | static uint8_t mac[6] = {0x54, 0x55, 0x58, 0x10, 0x00, 0x24}; // this just needs to be unique for your network, 9 | // so unless you have more than one of these boards 10 | // connected, you should be fine with this value. 11 | 12 | static uint8_t ip[4] = {192, 168, 1, 15}; // the IP address for your board. Check your home hub 13 | // to find an IP address not in use and pick that 14 | // this or 10.0.0.15 are likely formats for an address 15 | // that will work. 16 | 17 | static uint16_t port = 80; // Use port 80 - the standard for HTTP 18 | 19 | ETHER_28J60 e; 20 | 21 | void setup() 22 | { 23 | e.setup(mac, ip, port); 24 | pinMode(outputPin, OUTPUT); 25 | } 26 | 27 | void loop() 28 | { 29 | char* params; 30 | if (params = e.serviceRequest()) 31 | { 32 | e.print("

Web Remote

"); 33 | if (strcmp(params, "?cmd=on") == 0) 34 | { 35 | digitalWrite(outputPin, HIGH); 36 | e.print("Turn off"); 37 | } 38 | else if (strcmp(params, "?cmd=off") == 0) // Modified -- 2011 12 15 # Ben Schueler 39 | { 40 | digitalWrite(outputPin, LOW); 41 | e.print("Turn on"); 42 | } 43 | e.respond(); 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /libraries/etherShield/ip_arp_udp_tcp.h: -------------------------------------------------------------------------------- 1 | /********************************************* 2 | * vim:sw=8:ts=8:si:et 3 | * To use the above modeline in vim you must have "set modeline" in your .vimrc 4 | * Author: Guido Socher 5 | * Copyright: GPL V2 6 | * 7 | * IP/ARP/UDP/TCP functions 8 | * 9 | * Chip type : ATMEGA88 with ENC28J60 10 | *********************************************/ 11 | /********************************************* 12 | * Modified: nuelectronics.com -- Ethershield for Arduino 13 | *********************************************/ 14 | //@{ 15 | #ifndef IP_ARP_UDP_TCP_H 16 | #define IP_ARP_UDP_TCP_H 17 | #include 18 | 19 | // you must call this function once before you use any of the other functions: 20 | extern void init_ip_arp_udp_tcp(uint8_t *mymac,uint8_t *myip,uint8_t wwwp); 21 | // 22 | extern uint8_t eth_type_is_arp_and_my_ip(uint8_t *buf,uint16_t len); 23 | extern uint8_t eth_type_is_ip_and_my_ip(uint8_t *buf,uint16_t len); 24 | extern void make_arp_answer_from_request(uint8_t *buf); 25 | extern void make_echo_reply_from_request(uint8_t *buf,uint16_t len); 26 | extern void make_udp_reply_from_request(uint8_t *buf,char *data,uint8_t datalen,uint16_t port); 27 | 28 | 29 | extern void make_tcp_synack_from_syn(uint8_t *buf); 30 | extern void init_len_info(uint8_t *buf); 31 | extern uint16_t get_tcp_data_pointer(void); 32 | extern uint16_t fill_tcp_data_p(uint8_t *buf,uint16_t pos, const char *progmem_s PROGMEM); 33 | extern uint16_t fill_tcp_data(uint8_t *buf,uint16_t pos, const char *s); 34 | extern void make_tcp_ack_from_any(uint8_t *buf); 35 | extern void make_tcp_ack_with_data(uint8_t *buf,uint16_t dlen); 36 | extern void make_arp_request(uint8_t *buf, uint8_t *server_ip); 37 | extern uint8_t arp_packet_is_myreply_arp ( uint8_t *buf ); 38 | extern void tcp_client_send_packet(uint8_t *buf,uint16_t dest_port, uint16_t src_port, uint8_t flags, uint8_t max_segment_size, 39 | uint8_t clear_seqck, uint16_t next_ack_num, uint16_t dlength, uint8_t *dest_mac, uint8_t *dest_ip); 40 | extern uint16_t tcp_get_dlength ( uint8_t *buf ); 41 | 42 | 43 | #endif /* IP_ARP_UDP_TCP_H */ 44 | //@} 45 | -------------------------------------------------------------------------------- /libraries/etherShield/etherShield.h: -------------------------------------------------------------------------------- 1 | /* 2 | EHTERSHIELD_H library for Arduino etherShield 3 | Copyright (c) 2008 Xing Yu. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef ETHERSHIELD_H 21 | #define ETHERSHIELD_H 22 | 23 | #include 24 | #include "enc28j60.h" 25 | #include "ip_arp_udp_tcp.h" 26 | #include "net.h" 27 | 28 | 29 | class EtherShield 30 | { 31 | public: 32 | 33 | EtherShield(); 34 | uint16_t ES_fill_tcp_data_p(uint8_t *buf,uint16_t pos, const char *progmem_s PROGMEM); 35 | uint16_t ES_fill_tcp_data(uint8_t *buf,uint16_t pos, const char *s); 36 | void ES_enc28j60Init(uint8_t* macaddr); 37 | void ES_enc28j60clkout(uint8_t clk); 38 | void ES_enc28j60PhyWrite(uint8_t address, uint16_t data); 39 | uint16_t ES_enc28j60PacketReceive(uint16_t len, uint8_t* packet); 40 | void ES_init_ip_arp_udp_tcp(uint8_t *mymac,uint8_t *myip,uint8_t wwwp); 41 | uint8_t ES_eth_type_is_arp_and_my_ip(uint8_t *buf,uint16_t len); 42 | void ES_make_arp_answer_from_request(uint8_t *buf); 43 | uint8_t ES_eth_type_is_ip_and_my_ip(uint8_t *buf,uint16_t len); 44 | void ES_make_echo_reply_from_request(uint8_t *buf,uint16_t len); 45 | void ES_make_tcp_synack_from_syn(uint8_t *buf); 46 | void ES_init_len_info(uint8_t *buf); 47 | uint16_t ES_get_tcp_data_pointer(void); 48 | void ES_make_tcp_ack_from_any(uint8_t *buf); 49 | void ES_make_tcp_ack_with_data(uint8_t *buf,uint16_t dlen); 50 | 51 | // new web client functions 52 | void ES_make_arp_request(uint8_t *buf, uint8_t *server_ip); 53 | uint8_t ES_arp_packet_is_myreply_arp ( uint8_t *buf ); 54 | void ES_tcp_client_send_packet(uint8_t *buf,uint16_t dest_port, uint16_t src_port, uint8_t flags, uint8_t max_segment_size, 55 | uint8_t clear_seqck, uint16_t next_ack_num, uint16_t dlength, uint8_t *dest_mac, uint8_t *dest_ip); 56 | uint16_t ES_tcp_get_dlength( uint8_t *buf ); 57 | 58 | }; 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /libraries/etherShield/etherShield.cpp: -------------------------------------------------------------------------------- 1 | // a wrapper class for EtherShield 2 | 3 | extern "C" { 4 | #include "enc28j60.h" 5 | #include "ip_arp_udp_tcp.h" 6 | 7 | } 8 | #include "EtherShield.h" 9 | 10 | //constructor 11 | EtherShield::EtherShield(){ 12 | } 13 | 14 | uint16_t EtherShield::ES_fill_tcp_data_p(uint8_t *buf,uint16_t pos, const char *progmem_s PROGMEM){ 15 | return fill_tcp_data_p(buf, pos, progmem_s); 16 | } 17 | 18 | uint16_t EtherShield::ES_fill_tcp_data(uint8_t *buf,uint16_t pos, const char *s){ 19 | return fill_tcp_data(buf,pos, s); 20 | } 21 | 22 | 23 | void EtherShield::ES_enc28j60Init(uint8_t* macaddr){ 24 | enc28j60Init(macaddr); 25 | 26 | } 27 | void EtherShield::ES_enc28j60clkout(uint8_t clk){ 28 | enc28j60clkout(clk); 29 | } 30 | 31 | void EtherShield::ES_enc28j60PhyWrite(uint8_t address, uint16_t data){ 32 | enc28j60PhyWrite(address, data); 33 | } 34 | 35 | uint16_t EtherShield::ES_enc28j60PacketReceive(uint16_t len, uint8_t* packet){ 36 | return enc28j60PacketReceive(len, packet); 37 | } 38 | 39 | 40 | void EtherShield::ES_init_ip_arp_udp_tcp(uint8_t *mymac,uint8_t *myip,uint8_t wwwp){ 41 | init_ip_arp_udp_tcp(mymac,myip,wwwp); 42 | } 43 | 44 | uint8_t EtherShield::ES_eth_type_is_arp_and_my_ip(uint8_t *buf,uint16_t len){ 45 | return eth_type_is_arp_and_my_ip(buf,len); 46 | } 47 | 48 | void EtherShield::ES_make_arp_answer_from_request(uint8_t *buf){ 49 | make_arp_answer_from_request(buf); 50 | } 51 | 52 | uint8_t EtherShield::ES_eth_type_is_ip_and_my_ip(uint8_t *buf,uint16_t len){ 53 | return eth_type_is_ip_and_my_ip(buf, len); 54 | } 55 | 56 | 57 | void EtherShield::ES_make_echo_reply_from_request(uint8_t *buf,uint16_t len){ 58 | make_echo_reply_from_request(buf,len); 59 | } 60 | 61 | void EtherShield::ES_make_tcp_synack_from_syn(uint8_t *buf){ 62 | make_tcp_synack_from_syn(buf); 63 | } 64 | 65 | void EtherShield::ES_init_len_info(uint8_t *buf){ 66 | init_len_info(buf); 67 | } 68 | 69 | uint16_t EtherShield::ES_get_tcp_data_pointer(void){ 70 | return get_tcp_data_pointer(); 71 | } 72 | 73 | void EtherShield::ES_make_tcp_ack_from_any(uint8_t *buf){ 74 | make_tcp_ack_from_any(buf); 75 | } 76 | 77 | void EtherShield::ES_make_tcp_ack_with_data(uint8_t *buf,uint16_t dlen){ 78 | make_tcp_ack_with_data(buf,dlen); 79 | } 80 | 81 | void EtherShield::ES_make_arp_request(uint8_t *buf, uint8_t *server_ip){ 82 | make_arp_request(buf, server_ip); 83 | } 84 | 85 | uint8_t EtherShield::ES_arp_packet_is_myreply_arp ( uint8_t *buf ){ 86 | return arp_packet_is_myreply_arp (buf); 87 | } 88 | 89 | void EtherShield::ES_tcp_client_send_packet(uint8_t *buf,uint16_t dest_port, uint16_t src_port, uint8_t flags, uint8_t max_segment_size, 90 | uint8_t clear_seqck, uint16_t next_ack_num, uint16_t dlength, uint8_t *dest_mac, uint8_t *dest_ip){ 91 | 92 | tcp_client_send_packet(buf, dest_port, src_port, flags, max_segment_size, clear_seqck, next_ack_num, dlength,dest_mac,dest_ip); 93 | } 94 | 95 | uint16_t EtherShield::ES_tcp_get_dlength( uint8_t *buf ){ 96 | return tcp_get_dlength(buf); 97 | } 98 | -------------------------------------------------------------------------------- /TestEthernet/TestEthernet.ino: -------------------------------------------------------------------------------- 1 | //zoomkat 4-05-12 2 | //web LED code 3 | //for use with IDE 1.0 4 | //open serial monitor to see what the arduino receives 5 | //use the \ slash to escape the " in the html (or use ') 6 | //address will look like http://192.168.1.102:84 when submited 7 | //for use with W5100 based ethernet shields 8 | //turns pin 5 on/off 9 | 10 | #include 11 | #include 12 | 13 | byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address 14 | byte ip[] = { 192, 168, 1, 102 }; // arduino server ip in lan 15 | byte gateway[] = { 192, 168, 1, 1 }; // internet access via router gateway 16 | byte subnet[] = { 255, 255, 255, 0 }; //subnet mask 17 | EthernetServer server(84); //arduino server port 18 | 19 | String readString; 20 | 21 | ////////////////////// 22 | 23 | void setup(){ 24 | 25 | pinMode(5, OUTPUT); //pin selected to control 26 | //start Ethernet 27 | Ethernet.begin(mac, ip, gateway, subnet); 28 | server.begin(); 29 | 30 | //enable serial data print 31 | Serial.begin(9600); 32 | Serial.println("servertest1"); // so I can keep track of what is loaded 33 | } 34 | 35 | void loop(){ 36 | // Create a client connection 37 | EthernetClient client = server.available(); 38 | if (client) { 39 | while (client.connected()) { 40 | if (client.available()) { 41 | char c = client.read(); 42 | 43 | //read char by char HTTP request 44 | if (readString.length() < 100) { 45 | 46 | //store characters to string 47 | readString += c; 48 | Serial.print(c); //print what server receives to serial monitor 49 | } 50 | 51 | //if HTTP request has ended 52 | if (c == '\n') { 53 | 54 | /////////////// 55 | Serial.println(readString); 56 | 57 | //now output HTML data header 58 | 59 | client.println("HTTP/1.1 200 OK"); 60 | client.println("Content-Type: text/html"); 61 | client.println(); 62 | 63 | client.println(""); 64 | client.println(""); 65 | client.println("Arduino GET test page"); 66 | client.println(""); 67 | client.println(""); 68 | 69 | client.println("

HTML form GET example

"); 70 | 71 | client.println("
"); 72 | 73 | client.println("Pin 5 \"on\" or \"off\":
"); 74 | 75 | client.println(""); 76 | 77 | client.println("
"); 78 | 79 | client.println("
"); 80 | 81 | client.println(""); 82 | client.println(""); 83 | 84 | delay(1); 85 | //stopping client 86 | client.stop(); 87 | 88 | ///////////////////// 89 | if(readString.indexOf("on") >0)//checks for on 90 | { 91 | digitalWrite(5, HIGH); // set pin 5 high 92 | Serial.println("Led On"); 93 | } 94 | if(readString.indexOf("off") >0)//checks for off 95 | { 96 | digitalWrite(5, LOW); // set pin 5 low 97 | Serial.println("Led Off"); 98 | } 99 | //clearing string for next read 100 | readString=""; 101 | 102 | } 103 | } 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /WebServer/WebServer.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Web Server 3 | 4 | A simple web server that shows the value of the analog input pins. 5 | using an Arduino Wiznet Ethernet shield. 6 | 7 | Circuit: 8 | * Ethernet shield attached to pins 10, 11, 12, 13 9 | * Analog inputs attached to pins A0 through A5 (optional) 10 | 11 | created 18 Dec 2009 12 | by David A. Mellis 13 | modified 9 Apr 2012 14 | by Tom Igoe 15 | 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | // Enter a MAC address and IP address for your controller below. 22 | // The IP address will be dependent on your local network: 23 | byte mac[] = { 24 | 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 25 | IPAddress ip(192,168,1, 103); 26 | 27 | // Initialize the Ethernet server library 28 | // with the IP address and port you want to use 29 | // (port 80 is default for HTTP): 30 | EthernetServer server(80); 31 | 32 | void setup() { 33 | // Open serial communications and wait for port to open: 34 | Serial.begin(9600); 35 | while (!Serial) { 36 | ; // wait for serial port to connect. Needed for Leonardo only 37 | } 38 | 39 | 40 | // start the Ethernet connection and the server: 41 | Ethernet.begin(mac, ip); 42 | server.begin(); 43 | Serial.print("server is at "); 44 | Serial.println(Ethernet.localIP()); 45 | } 46 | 47 | 48 | void loop() { 49 | // listen for incoming clients 50 | EthernetClient client = server.available(); 51 | if (client) { 52 | Serial.println("new client"); 53 | // an http request ends with a blank line 54 | boolean currentLineIsBlank = true; 55 | while (client.connected()) { 56 | if (client.available()) { 57 | char c = client.read(); 58 | Serial.write(c); 59 | // if you've gotten to the end of the line (received a newline 60 | // character) and the line is blank, the http request has ended, 61 | // so you can send a reply 62 | if (c == '\n' && currentLineIsBlank) { 63 | // send a standard http response header 64 | client.println("HTTP/1.1 200 OK"); 65 | client.println("Content-Type: text/html"); 66 | client.println("Connnection: close"); 67 | client.println(); 68 | client.println(""); 69 | client.println(""); 70 | // add a meta refresh tag, so the browser pulls again every 5 seconds: 71 | client.println(""); 72 | // output the value of each analog input pin 73 | for (int analogChannel = 0; analogChannel < 6; analogChannel++) { 74 | int sensorReading = analogRead(analogChannel); 75 | client.print("analog input "); 76 | client.print(analogChannel); 77 | client.print(" is "); 78 | client.print(sensorReading); 79 | client.println("
"); 80 | } 81 | client.println(""); 82 | break; 83 | } 84 | if (c == '\n') { 85 | // you're starting a new line 86 | currentLineIsBlank = true; 87 | } 88 | else if (c != '\r') { 89 | // you've gotten a character on the current line 90 | currentLineIsBlank = false; 91 | } 92 | } 93 | } 94 | // give the web browser time to receive the data 95 | delay(1); 96 | // close the connection: 97 | client.stop(); 98 | Serial.println("client disonnected"); 99 | } 100 | } 101 | 102 | -------------------------------------------------------------------------------- /simple_sensor/simple_sensor.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x32,0x31 }; 4 | byte Ethernet::buffer[700]; 5 | static uint32_t timer; 6 | 7 | static byte hisip[] = { 192,168,16,103 }; 8 | 9 | int sensorPin = A1; 10 | int sensorPin2 = A2; 11 | int sensorPin3 = A3; 12 | int sensorPin4 = A4; 13 | int sensorPin5 = A5; 14 | int sensorValue = 0; 15 | float tempC= 0.0; 16 | 17 | 18 | void setup () { 19 | Serial.begin(57600); 20 | Serial.println(F("\n[simple_sensor]")); 21 | 22 | Serial.print("MAC: "); 23 | for (byte i = 0; i < 6; ++i) { 24 | Serial.print(mymac[i], HEX); 25 | if (i < 5) 26 | Serial.print(':'); 27 | } 28 | Serial.println(); 29 | 30 | // Ethernet Shield v.1.0 by SeeedStudio on top of Duemilanove 31 | // if (ether.begin(sizeof Ethernet::buffer, mymac, 10) == 0) 32 | // Serial.println(F("Failed to access Ethernet controller")); 33 | // 34 | // Serial.println(F("[Setting up DHCP]")); 35 | // if (!ether.dhcpSetup()) 36 | // Serial.println(F("DHCP failed")); 37 | // 38 | // ether.printIp("My IP: ", ether.myip); 39 | // ether.printIp("Netmask: ", ether.netmask); 40 | // ether.printIp("GW IP: ", ether.gwip); 41 | // ether.printIp("DNS IP: ", ether.dnsip); 42 | // 43 | // ether.copyIp(ether.hisip, hisip); 44 | // ether.printIp("DST IP: ", ether.hisip); 45 | // ether.hisport = 8888; 46 | 47 | // sendToServer(); 48 | } 49 | 50 | static byte session; 51 | Stash stash; 52 | 53 | static void sendToServer (int temp) { 54 | 55 | 56 | Serial.print("Sending temperature to server ... "); 57 | Serial.print(temp); 58 | // byte sd = stash.create(); 59 | // stash.print("t1="); 60 | // stash.print(temp); 61 | // stash.save(); 62 | // int stash_size = stash.size(); 63 | 64 | // Compose the http POST request, taking the headers below and appending 65 | // previously created stash in the sd holder. 66 | // Stash::prepare(PSTR("POST /register-temp HTTP/1.0" "\r\n" 67 | // "Content-Length: $D" "\r\n" 68 | // "Content-Type: application/x-www-form-urlencoded" "\r\n" 69 | // "\r\n" 70 | // "$H"), 71 | // stash_size, sd); 72 | 73 | 74 | 75 | // send the packet - this also releases all stash buffers once done 76 | // Save the session ID so we can watch for it in the main loop. 77 | // session = ether.tcpSend(); 78 | Serial.println(" sent"); 79 | } 80 | 81 | void loop () { 82 | // ether.packetLoop(ether.packetReceive()); 83 | 84 | if (millis() > timer) { 85 | timer = millis() + 2000; 86 | sensorValue = analogRead(sensorPin); 87 | tempC = (((float)sensorValue * (5000.0/1024.0)) - 500)/10.0; 88 | Serial.print("1: "); 89 | Serial.print(tempC); 90 | delay(3); 91 | 92 | sensorValue = analogRead(sensorPin2); 93 | tempC = (((float)sensorValue * (5000.0/1024.0)) - 500)/10.0; 94 | Serial.print(" 2: "); 95 | Serial.print(tempC); 96 | delay(3); 97 | 98 | sensorValue = analogRead(sensorPin3); 99 | tempC = (((float)sensorValue * (5000.0/1024.0)) - 500)/10.0; 100 | Serial.print(" 3: "); 101 | Serial.print(tempC); 102 | delay(3); 103 | 104 | sensorValue = analogRead(sensorPin4); 105 | tempC = (((float)sensorValue * (5000.0/1024.0)) - 500)/10.0; 106 | Serial.print(" 4: "); 107 | Serial.print(tempC); 108 | delay(3); 109 | 110 | sensorValue = analogRead(sensorPin5); 111 | tempC = (((float)sensorValue * (5000.0/1024.0)) - 500)/10.0; 112 | Serial.print(" 5: "); 113 | Serial.println(tempC); 114 | 115 | //sendToServer(sensorValue); 116 | 117 | } 118 | 119 | 120 | // const char* reply = ether.tcpReply(session); 121 | // if (reply != 0) { 122 | // Serial.println("Got a response!"); 123 | // Serial.println(reply); 124 | // } 125 | } 126 | 127 | static void my_callback (byte status, word off, word len) { 128 | Serial.println(">>>"); 129 | Ethernet::buffer[off+300] = 0; 130 | Serial.print((const char*) Ethernet::buffer + off); 131 | Serial.println("..."); 132 | } 133 | 134 | 135 | -------------------------------------------------------------------------------- /libraries/etherShield/net.h: -------------------------------------------------------------------------------- 1 | /********************************************* 2 | * vim:sw=8:ts=8:si:et 3 | * To use the above modeline in vim you must have "set modeline" in your .vimrc 4 | * Author: Guido Socher 5 | * Copyright: GPL V2 6 | * 7 | * Based on the net.h file from the AVRlib library by Pascal Stang. 8 | * For AVRlib See http://www.procyonengineering.com/ 9 | * Used with explicit permission of Pascal Stang. 10 | * 11 | * Chip type : ATMEGA88 with ENC28J60 12 | *********************************************/ 13 | /********************************************* 14 | * Modified: nuelectronics.com -- Ethershield for Arduino 15 | *********************************************/ 16 | 17 | // notation: _P = position of a field 18 | // _V = value of a field 19 | 20 | //@{ 21 | 22 | #ifndef NET_H 23 | #define NET_H 24 | 25 | // ******* ETH ******* 26 | #define ETH_HEADER_LEN 14 27 | // values of certain bytes: 28 | #define ETHTYPE_ARP_H_V 0x08 29 | #define ETHTYPE_ARP_L_V 0x06 30 | #define ETHTYPE_IP_V 0x0800 31 | #define ETHTYPE_IP_H_V 0x08 32 | #define ETHTYPE_IP_L_V 0x00 33 | // byte positions in the ethernet frame: 34 | // 35 | // Ethernet type field (2bytes): 36 | #define ETH_TYPE_H_P 12 37 | #define ETH_TYPE_L_P 13 38 | // 39 | #define ETH_DST_MAC 0 40 | #define ETH_SRC_MAC 6 41 | 42 | 43 | // ******* ARP ******* 44 | #define ETH_ARP_OPCODE_REPLY_H_V 0x0 45 | #define ETH_ARP_OPCODE_REPLY_L_V 0x02 46 | // 47 | #define ETHTYPE_ARP_L_V 0x06 48 | // arp.dst.ip 49 | #define ETH_ARP_DST_IP_P 0x26 50 | // arp.opcode 51 | #define ETH_ARP_OPCODE_H_P 0x14 52 | #define ETH_ARP_OPCODE_L_P 0x15 53 | // arp.src.mac 54 | #define ETH_ARP_SRC_MAC_P 0x16 55 | #define ETH_ARP_SRC_IP_P 0x1c 56 | #define ETH_ARP_DST_MAC_P 0x20 57 | #define ETH_ARP_DST_IP_P 0x26 58 | 59 | #define ARP_OPCODE_REQUEST_H_V 0x00 60 | #define ARP_OPCODE_REQUEST_L_V 0x01 61 | #define ARP_OPCODE_REPLY_H_V 0x00 62 | #define ARP_OPCODE_REPLY_L_V 0x02 63 | 64 | #define ARP_HARDWARE_TYPE_H_V 0x00 65 | #define ARP_HARDWARE_TYPE_L_V 0x01 66 | #define ARP_PROTOCOL_H_V 0x08 67 | #define ARP_PROTOCOL_L_V 0x00 68 | #define ARP_HARDWARE_SIZE_V 0x06 69 | #define ARP_PROTOCOL_SIZE_V 0x04 70 | 71 | #define ARP_HARDWARE_TYPE_H_P 0x0E 72 | #define ARP_HARDWARE_TYPE_L_P 0x0F 73 | #define ARP_PROTOCOL_H_P 0x10 74 | #define ARP_PROTOCOL_L_P 0x11 75 | #define ARP_HARDWARE_SIZE_P 0x12 76 | #define ARP_PROTOCOL_SIZE_P 0x13 77 | #define ARP_OPCODE_H_P 0x14 78 | #define ARP_OPCODE_L_P 0x15 79 | #define ARP_SRC_MAC_P 0x16 80 | #define ARP_SRC_IP_P 0x1C 81 | #define ARP_DST_MAC_P 0x20 82 | #define ARP_DST_IP_P 0x26 83 | 84 | 85 | // ******* IP ******* 86 | #define IP_HEADER_LEN 20 87 | 88 | #define IP_PROTO_ICMP_V 0x01 89 | #define IP_PROTO_TCP_V 0x06 90 | #define IP_PROTO_UDP_V 0x11 91 | #define IP_V4_V 0x40 92 | #define IP_HEADER_LENGTH_V 0x05 93 | 94 | #define IP_P 0x0E 95 | #define IP_HEADER_VER_LEN_P 0x0E 96 | #define IP_TOS_P 0x0F 97 | #define IP_TOTLEN_H_P 0x10 98 | #define IP_TOTLEN_L_P 0x11 99 | #define IP_ID_H_P 0x12 100 | #define IP_ID_L_P 0x13 101 | #define IP_FLAGS_P 0x14 102 | #define IP_FLAGS_H_P 0x14 103 | #define IP_FLAGS_L_P 0x15 104 | #define IP_TTL_P 0x16 105 | #define IP_PROTO_P 0x17 106 | #define IP_CHECKSUM_P 0x18 107 | #define IP_CHECKSUM_H_P 0x18 108 | #define IP_CHECKSUM_L_P 0x19 109 | #define IP_SRC_IP_P 0x1A 110 | #define IP_DST_IP_P 0x1E 111 | 112 | #define IP_SRC_P 0x1a 113 | #define IP_DST_P 0x1e 114 | #define IP_HEADER_LEN_VER_P 0xe 115 | // ******* ICMP ******* 116 | #define ICMP_TYPE_ECHOREPLY_V 0 117 | #define ICMP_TYPE_ECHOREQUEST_V 8 118 | // 119 | #define ICMP_TYPE_P 0x22 120 | #define ICMP_CHECKSUM_P 0x24 121 | 122 | // ******* UDP ******* 123 | #define UDP_HEADER_LEN 8 124 | // 125 | #define UDP_SRC_PORT_H_P 0x22 126 | #define UDP_SRC_PORT_L_P 0x23 127 | #define UDP_DST_PORT_H_P 0x24 128 | #define UDP_DST_PORT_L_P 0x25 129 | // 130 | #define UDP_LEN_H_P 0x26 131 | #define UDP_LEN_L_P 0x27 132 | #define UDP_CHECKSUM_H_P 0x28 133 | #define UDP_CHECKSUM_L_P 0x29 134 | #define UDP_DATA_P 0x2a 135 | 136 | // ******* TCP ******* 137 | // plain len without the options: 138 | #define TCP_HEADER_LEN_PLAIN 20 139 | 140 | 141 | #define TCP_FLAG_FIN_V 0x01 142 | #define TCP_FLAGS_FIN_V 0x01 143 | #define TCP_FLAGS_SYN_V 0x02 144 | #define TCP_FLAG_SYN_V 0x02 145 | #define TCP_FLAG_RST_V 0x04 146 | #define TCP_FLAG_PUSH_V 0x08 147 | #define TCP_FLAGS_ACK_V 0x10 148 | #define TCP_FLAG_ACK_V 0x10 149 | #define TCP_FLAG_URG_V 0x20 150 | #define TCP_FLAG_ECE_V 0x40 151 | #define TCP_FLAG_CWR_V 0x80 152 | #define TCP_FLAGS_SYNACK_V 0x12 153 | 154 | #define TCP_SRC_PORT_H_P 0x22 155 | #define TCP_SRC_PORT_L_P 0x23 156 | #define TCP_DST_PORT_H_P 0x24 157 | #define TCP_DST_PORT_L_P 0x25 158 | #define TCP_SEQ_P 0x26 // the tcp seq number is 4 bytes 0x26-0x29 159 | #define TCP_SEQ_H_P 0x26 160 | #define TCP_SEQACK_P 0x2A // 4 bytes 161 | #define TCP_SEQACK_H_P 0x2A 162 | #define TCP_HEADER_LEN_P 0x2E 163 | #define TCP_FLAGS_P 0x2F 164 | #define TCP_FLAG_P 0x2F 165 | #define TCP_WINDOWSIZE_H_P 0x30 // 2 bytes 166 | #define TCP_WINDOWSIZE_L_P 0x31 167 | #define TCP_CHECKSUM_H_P 0x32 168 | #define TCP_CHECKSUM_L_P 0x33 169 | #define TCP_URGENT_PTR_H_P 0x34 // 2 bytes 170 | #define TCP_URGENT_PTR_L_P 0x35 171 | #define TCP_OPTIONS_P 0x36 172 | #define TCP_DATA_P 0x36 173 | 174 | // 175 | #endif 176 | //@} 177 | 178 | -------------------------------------------------------------------------------- /libraries/ETHER_28J60/ETHER_28J60.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ETHER_28J60.cpp - Ethernet library 3 | Copyright (c) 2010 Simon Monk. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | /****************************************************************************** 21 | * Includes 22 | ******************************************************************************/ 23 | 24 | #include "etherShield.h" 25 | #include "ETHER_28J60.h" 26 | //#include "WProgram.h" // Arduino 0.23 27 | #include "Arduino.h" // Arduino 1.0 -- 2011 12 15 # Ben Schueler 28 | 29 | /****************************************************************************** 30 | * Definitions 31 | ******************************************************************************/ 32 | #define BUFFER_SIZE 500 33 | #define STR_BUFFER_SIZE 32 34 | static uint8_t buf[BUFFER_SIZE+1]; 35 | static char strbuf[STR_BUFFER_SIZE+1]; 36 | EtherShield es=EtherShield(); 37 | uint16_t plen; 38 | 39 | 40 | /****************************************************************************** 41 | * Constructors 42 | ******************************************************************************/ 43 | 44 | /****************************************************************************** 45 | * User API 46 | ******************************************************************************/ 47 | 48 | void ETHER_28J60::setup(uint8_t macAddress[], uint8_t ipAddress[], uint16_t port) 49 | { 50 | _port = port; 51 | es.ES_enc28j60Init(macAddress); 52 | es.ES_enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz 53 | delay(10); 54 | es.ES_enc28j60PhyWrite(PHLCON,0x880); 55 | delay(500); 56 | es.ES_enc28j60PhyWrite(PHLCON,0x990); 57 | delay(500); 58 | es.ES_enc28j60PhyWrite(PHLCON,0x880); 59 | delay(500); 60 | es.ES_enc28j60PhyWrite(PHLCON,0x990); 61 | delay(500); 62 | es.ES_enc28j60PhyWrite(PHLCON,0x476); 63 | delay(100); 64 | es.ES_init_ip_arp_udp_tcp(macAddress, ipAddress, _port); 65 | } 66 | 67 | 68 | char* ETHER_28J60::serviceRequest() 69 | { 70 | uint16_t dat_p; 71 | int8_t cmd; 72 | plen = es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf); 73 | 74 | /*plen will ne unequal to zero if there is a valid packet (without crc error) */ 75 | if(plen!=0) 76 | { 77 | // arp is broadcast if unknown but a host may also verify the mac address by sending it to a unicast address. 78 | if (es.ES_eth_type_is_arp_and_my_ip(buf, plen)) 79 | { 80 | es.ES_make_arp_answer_from_request(buf); 81 | return 0; 82 | } 83 | // check if ip packets are for us: 84 | if (es.ES_eth_type_is_ip_and_my_ip(buf, plen) == 0) 85 | { 86 | return 0; 87 | } 88 | if (buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V) 89 | { 90 | es.ES_make_echo_reply_from_request(buf, plen); 91 | return 0; 92 | } 93 | // tcp port www start, compare only the lower byte 94 | if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P] == _port) 95 | { 96 | if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V) 97 | { 98 | es.ES_make_tcp_synack_from_syn(buf); // make_tcp_synack_from_syn does already send the syn,ack 99 | return 0; 100 | } 101 | if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V) 102 | { 103 | es.ES_init_len_info(buf); // init some data structures 104 | dat_p=es.ES_get_tcp_data_pointer(); 105 | if (dat_p==0) 106 | { // we can possibly have no data, just ack: 107 | if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V) 108 | { 109 | es.ES_make_tcp_ack_from_any(buf); 110 | } 111 | return 0; 112 | } 113 | if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0) 114 | { 115 | // head, post and other methods for possible status codes see: 116 | // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html 117 | plen=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n

200 OK

")); 118 | plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("

A

")); 119 | respond(); 120 | } 121 | if (strncmp("/",(char *)&(buf[dat_p+4]),1)==0) // was "/ " and 2 122 | { 123 | // Copy the request action before we overwrite it with the response 124 | int i = 0; 125 | while (buf[dat_p+5+i] != ' ' && i < STR_BUFFER_SIZE) 126 | { 127 | strbuf[i] = buf[dat_p+5+i]; 128 | i++; 129 | } 130 | strbuf[i] = '\0'; 131 | plen=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n")); 132 | return (char*)strbuf; 133 | } 134 | } 135 | } 136 | } 137 | } 138 | 139 | 140 | void ETHER_28J60::print(char* text) 141 | { 142 | int j = 0; 143 | while (text[j]) 144 | { 145 | buf[TCP_CHECKSUM_L_P+3+plen]=text[j++]; 146 | plen++; 147 | } 148 | } 149 | 150 | void ETHER_28J60::print(int number) 151 | { 152 | char tempString[9]; 153 | itoa(number, tempString, 10); 154 | print(tempString); 155 | } 156 | 157 | void ETHER_28J60::respond() 158 | { 159 | es.ES_make_tcp_ack_from_any(buf); // send ack for http get 160 | es.ES_make_tcp_ack_with_data(buf,plen); // send data 161 | } 162 | -------------------------------------------------------------------------------- /libraries/etherShield/enc28j60.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * vim:sw=8:ts=8:si:et 3 | * 4 | * Title : Microchip ENC28J60 Ethernet Interface Driver 5 | * Author : Pascal Stang (c)2005 6 | * Modified by Guido Socher 7 | * Copyright: GPL V2 8 | * 9 | *This driver provides initialization and transmit/receive 10 | *functions for the Microchip ENC28J60 10Mb Ethernet Controller and PHY. 11 | *This chip is novel in that it is a full MAC+PHY interface all in a 28-pin 12 | *chip, using an SPI interface to the host processor. 13 | * 14 | * 15 | *****************************************************************************/ 16 | /********************************************* 17 | * Modified: nuelectronics.com -- Ethershield for Arduino 18 | *********************************************/ 19 | //@{ 20 | 21 | 22 | #ifndef ENC28J60_H 23 | #define ENC28J60_H 24 | #include 25 | 26 | // ENC28J60 Control Registers 27 | // Control register definitions are a combination of address, 28 | // bank number, and Ethernet/MAC/PHY indicator bits. 29 | // - Register address (bits 0-4) 30 | // - Bank number (bits 5-6) 31 | // - MAC/PHY indicator (bit 7) 32 | #define ADDR_MASK 0x1F 33 | #define BANK_MASK 0x60 34 | #define SPRD_MASK 0x80 35 | // All-bank registers 36 | #define EIE 0x1B 37 | #define EIR 0x1C 38 | #define ESTAT 0x1D 39 | #define ECON2 0x1E 40 | #define ECON1 0x1F 41 | // Bank 0 registers 42 | #define ERDPTL (0x00|0x00) 43 | #define ERDPTH (0x01|0x00) 44 | #define EWRPTL (0x02|0x00) 45 | #define EWRPTH (0x03|0x00) 46 | #define ETXSTL (0x04|0x00) 47 | #define ETXSTH (0x05|0x00) 48 | #define ETXNDL (0x06|0x00) 49 | #define ETXNDH (0x07|0x00) 50 | #define ERXSTL (0x08|0x00) 51 | #define ERXSTH (0x09|0x00) 52 | #define ERXNDL (0x0A|0x00) 53 | #define ERXNDH (0x0B|0x00) 54 | #define ERXRDPTL (0x0C|0x00) 55 | #define ERXRDPTH (0x0D|0x00) 56 | #define ERXWRPTL (0x0E|0x00) 57 | #define ERXWRPTH (0x0F|0x00) 58 | #define EDMASTL (0x10|0x00) 59 | #define EDMASTH (0x11|0x00) 60 | #define EDMANDL (0x12|0x00) 61 | #define EDMANDH (0x13|0x00) 62 | #define EDMADSTL (0x14|0x00) 63 | #define EDMADSTH (0x15|0x00) 64 | #define EDMACSL (0x16|0x00) 65 | #define EDMACSH (0x17|0x00) 66 | // Bank 1 registers 67 | #define EHT0 (0x00|0x20) 68 | #define EHT1 (0x01|0x20) 69 | #define EHT2 (0x02|0x20) 70 | #define EHT3 (0x03|0x20) 71 | #define EHT4 (0x04|0x20) 72 | #define EHT5 (0x05|0x20) 73 | #define EHT6 (0x06|0x20) 74 | #define EHT7 (0x07|0x20) 75 | #define EPMM0 (0x08|0x20) 76 | #define EPMM1 (0x09|0x20) 77 | #define EPMM2 (0x0A|0x20) 78 | #define EPMM3 (0x0B|0x20) 79 | #define EPMM4 (0x0C|0x20) 80 | #define EPMM5 (0x0D|0x20) 81 | #define EPMM6 (0x0E|0x20) 82 | #define EPMM7 (0x0F|0x20) 83 | #define EPMCSL (0x10|0x20) 84 | #define EPMCSH (0x11|0x20) 85 | #define EPMOL (0x14|0x20) 86 | #define EPMOH (0x15|0x20) 87 | #define EWOLIE (0x16|0x20) 88 | #define EWOLIR (0x17|0x20) 89 | #define ERXFCON (0x18|0x20) 90 | #define EPKTCNT (0x19|0x20) 91 | // Bank 2 registers 92 | #define MACON1 (0x00|0x40|0x80) 93 | #define MACON2 (0x01|0x40|0x80) 94 | #define MACON3 (0x02|0x40|0x80) 95 | #define MACON4 (0x03|0x40|0x80) 96 | #define MABBIPG (0x04|0x40|0x80) 97 | #define MAIPGL (0x06|0x40|0x80) 98 | #define MAIPGH (0x07|0x40|0x80) 99 | #define MACLCON1 (0x08|0x40|0x80) 100 | #define MACLCON2 (0x09|0x40|0x80) 101 | #define MAMXFLL (0x0A|0x40|0x80) 102 | #define MAMXFLH (0x0B|0x40|0x80) 103 | #define MAPHSUP (0x0D|0x40|0x80) 104 | #define MICON (0x11|0x40|0x80) 105 | #define MICMD (0x12|0x40|0x80) 106 | #define MIREGADR (0x14|0x40|0x80) 107 | #define MIWRL (0x16|0x40|0x80) 108 | #define MIWRH (0x17|0x40|0x80) 109 | #define MIRDL (0x18|0x40|0x80) 110 | #define MIRDH (0x19|0x40|0x80) 111 | // Bank 3 registers 112 | #define MAADR1 (0x00|0x60|0x80) 113 | #define MAADR0 (0x01|0x60|0x80) 114 | #define MAADR3 (0x02|0x60|0x80) 115 | #define MAADR2 (0x03|0x60|0x80) 116 | #define MAADR5 (0x04|0x60|0x80) 117 | #define MAADR4 (0x05|0x60|0x80) 118 | #define EBSTSD (0x06|0x60) 119 | #define EBSTCON (0x07|0x60) 120 | #define EBSTCSL (0x08|0x60) 121 | #define EBSTCSH (0x09|0x60) 122 | #define MISTAT (0x0A|0x60|0x80) 123 | #define EREVID (0x12|0x60) 124 | #define ECOCON (0x15|0x60) 125 | #define EFLOCON (0x17|0x60) 126 | #define EPAUSL (0x18|0x60) 127 | #define EPAUSH (0x19|0x60) 128 | // PHY registers 129 | #define PHCON1 0x00 130 | #define PHSTAT1 0x01 131 | #define PHHID1 0x02 132 | #define PHHID2 0x03 133 | #define PHCON2 0x10 134 | #define PHSTAT2 0x11 135 | #define PHIE 0x12 136 | #define PHIR 0x13 137 | #define PHLCON 0x14 138 | 139 | // ENC28J60 ERXFCON Register Bit Definitions 140 | #define ERXFCON_UCEN 0x80 141 | #define ERXFCON_ANDOR 0x40 142 | #define ERXFCON_CRCEN 0x20 143 | #define ERXFCON_PMEN 0x10 144 | #define ERXFCON_MPEN 0x08 145 | #define ERXFCON_HTEN 0x04 146 | #define ERXFCON_MCEN 0x02 147 | #define ERXFCON_BCEN 0x01 148 | // ENC28J60 EIE Register Bit Definitions 149 | #define EIE_INTIE 0x80 150 | #define EIE_PKTIE 0x40 151 | #define EIE_DMAIE 0x20 152 | #define EIE_LINKIE 0x10 153 | #define EIE_TXIE 0x08 154 | #define EIE_WOLIE 0x04 155 | #define EIE_TXERIE 0x02 156 | #define EIE_RXERIE 0x01 157 | // ENC28J60 EIR Register Bit Definitions 158 | #define EIR_PKTIF 0x40 159 | #define EIR_DMAIF 0x20 160 | #define EIR_LINKIF 0x10 161 | #define EIR_TXIF 0x08 162 | #define EIR_WOLIF 0x04 163 | #define EIR_TXERIF 0x02 164 | #define EIR_RXERIF 0x01 165 | // ENC28J60 ESTAT Register Bit Definitions 166 | #define ESTAT_INT 0x80 167 | #define ESTAT_LATECOL 0x10 168 | #define ESTAT_RXBUSY 0x04 169 | #define ESTAT_TXABRT 0x02 170 | #define ESTAT_CLKRDY 0x01 171 | // ENC28J60 ECON2 Register Bit Definitions 172 | #define ECON2_AUTOINC 0x80 173 | #define ECON2_PKTDEC 0x40 174 | #define ECON2_PWRSV 0x20 175 | #define ECON2_VRPS 0x08 176 | // ENC28J60 ECON1 Register Bit Definitions 177 | #define ECON1_TXRST 0x80 178 | #define ECON1_RXRST 0x40 179 | #define ECON1_DMAST 0x20 180 | #define ECON1_CSUMEN 0x10 181 | #define ECON1_TXRTS 0x08 182 | #define ECON1_RXEN 0x04 183 | #define ECON1_BSEL1 0x02 184 | #define ECON1_BSEL0 0x01 185 | // ENC28J60 MACON1 Register Bit Definitions 186 | #define MACON1_LOOPBK 0x10 187 | #define MACON1_TXPAUS 0x08 188 | #define MACON1_RXPAUS 0x04 189 | #define MACON1_PASSALL 0x02 190 | #define MACON1_MARXEN 0x01 191 | // ENC28J60 MACON2 Register Bit Definitions 192 | #define MACON2_MARST 0x80 193 | #define MACON2_RNDRST 0x40 194 | #define MACON2_MARXRST 0x08 195 | #define MACON2_RFUNRST 0x04 196 | #define MACON2_MATXRST 0x02 197 | #define MACON2_TFUNRST 0x01 198 | // ENC28J60 MACON3 Register Bit Definitions 199 | #define MACON3_PADCFG2 0x80 200 | #define MACON3_PADCFG1 0x40 201 | #define MACON3_PADCFG0 0x20 202 | #define MACON3_TXCRCEN 0x10 203 | #define MACON3_PHDRLEN 0x08 204 | #define MACON3_HFRMLEN 0x04 205 | #define MACON3_FRMLNEN 0x02 206 | #define MACON3_FULDPX 0x01 207 | // ENC28J60 MICMD Register Bit Definitions 208 | #define MICMD_MIISCAN 0x02 209 | #define MICMD_MIIRD 0x01 210 | // ENC28J60 MISTAT Register Bit Definitions 211 | #define MISTAT_NVALID 0x04 212 | #define MISTAT_SCAN 0x02 213 | #define MISTAT_BUSY 0x01 214 | // ENC28J60 PHY PHCON1 Register Bit Definitions 215 | #define PHCON1_PRST 0x8000 216 | #define PHCON1_PLOOPBK 0x4000 217 | #define PHCON1_PPWRSV 0x0800 218 | #define PHCON1_PDPXMD 0x0100 219 | // ENC28J60 PHY PHSTAT1 Register Bit Definitions 220 | #define PHSTAT1_PFDPX 0x1000 221 | #define PHSTAT1_PHDPX 0x0800 222 | #define PHSTAT1_LLSTAT 0x0004 223 | #define PHSTAT1_JBSTAT 0x0002 224 | // ENC28J60 PHY PHCON2 Register Bit Definitions 225 | #define PHCON2_FRCLINK 0x4000 226 | #define PHCON2_TXDIS 0x2000 227 | #define PHCON2_JABBER 0x0400 228 | #define PHCON2_HDLDIS 0x0100 229 | 230 | // ENC28J60 Packet Control Byte Bit Definitions 231 | #define PKTCTRL_PHUGEEN 0x08 232 | #define PKTCTRL_PPADEN 0x04 233 | #define PKTCTRL_PCRCEN 0x02 234 | #define PKTCTRL_POVERRIDE 0x01 235 | 236 | // SPI operation codes 237 | #define ENC28J60_READ_CTRL_REG 0x00 238 | #define ENC28J60_READ_BUF_MEM 0x3A 239 | #define ENC28J60_WRITE_CTRL_REG 0x40 240 | #define ENC28J60_WRITE_BUF_MEM 0x7A 241 | #define ENC28J60_BIT_FIELD_SET 0x80 242 | #define ENC28J60_BIT_FIELD_CLR 0xA0 243 | #define ENC28J60_SOFT_RESET 0xFF 244 | 245 | 246 | // The RXSTART_INIT should be zero. See Rev. B4 Silicon Errata 247 | // buffer boundaries applied to internal 8K ram 248 | // the entire available packet buffer space is allocated 249 | // 250 | // start with recbuf at 0/ 251 | #define RXSTART_INIT 0x0 252 | // receive buffer end 253 | #define RXSTOP_INIT (0x1FFF-0x0600-1) 254 | // start TX buffer at 0x1FFF-0x0600, pace for one full ethernet frame (~1500 bytes) 255 | #define TXSTART_INIT (0x1FFF-0x0600) 256 | // stp TX buffer at end of mem 257 | #define TXSTOP_INIT 0x1FFF 258 | // 259 | // max frame length which the conroller will accept: 260 | #define MAX_FRAMELEN 1500 // (note: maximum ethernet frame length would be 1518) 261 | //#define MAX_FRAMELEN 600 262 | 263 | 264 | // functions 265 | extern uint8_t enc28j60ReadOp(uint8_t op, uint8_t address); 266 | extern void enc28j60WriteOp(uint8_t op, uint8_t address, uint8_t data); 267 | extern void enc28j60ReadBuffer(uint16_t len, uint8_t* data); 268 | extern void enc28j60WriteBuffer(uint16_t len, uint8_t* data); 269 | extern void enc28j60SetBank(uint8_t address); 270 | extern uint8_t enc28j60Read(uint8_t address); 271 | extern void enc28j60Write(uint8_t address, uint8_t data); 272 | extern void enc28j60PhyWrite(uint8_t address, uint16_t data); 273 | extern void enc28j60clkout(uint8_t clk); 274 | extern void enc28j60Init(uint8_t* macaddr); 275 | extern void enc28j60PacketSend(uint16_t len, uint8_t* packet); 276 | extern uint16_t enc28j60PacketReceive(uint16_t maxlen, uint8_t* packet); 277 | extern uint8_t enc28j60getrev(void); 278 | 279 | #endif 280 | //@} 281 | -------------------------------------------------------------------------------- /libraries/etherShield/enc28j60.c: -------------------------------------------------------------------------------- 1 | /********************************************* 2 | * vim:sw=8:ts=8:si:et 3 | * To use the above modeline in vim you must have "set modeline" in your .vimrc 4 | * Author: Guido Socher 5 | * Copyright: GPL V2 6 | * http://www.gnu.org/licenses/gpl.html 7 | * 8 | * Based on the enc28j60.c file from the AVRlib library by Pascal Stang. 9 | * For AVRlib See http://www.procyonengineering.com/ 10 | * Used with explicit permission of Pascal Stang. 11 | * 12 | * Title: Microchip ENC28J60 Ethernet Interface Driver 13 | * Chip type : ATMEGA88 with ENC28J60 14 | *********************************************/ 15 | #include 16 | //#include "avr_compat.h" 17 | #include "enc28j60.h" 18 | //#include "WConstants.h" //all things wiring / arduino 0.23 19 | #include "wiring_private.h" //all things wiring / arduino 1.0 20 | //#include "timeout.h" 21 | // 22 | //#define F_CPU 10000000UL // 12.5 MHz 23 | /* 24 | #ifndef ALIBC_OLD 25 | #include 26 | #else 27 | #include 28 | #endif 29 | */ 30 | 31 | static uint8_t Enc28j60Bank; 32 | static uint16_t NextPacketPtr; 33 | 34 | #define ENC28J60_CONTROL_CS 10 35 | #define SPI_MOSI 11 36 | #define SPI_MISO 12 37 | #define SPI_SCK 13 38 | // set CS to 0 = active 39 | #define CSACTIVE digitalWrite(ENC28J60_CONTROL_CS, LOW) 40 | // set CS to 1 = passive 41 | #define CSPASSIVE digitalWrite(ENC28J60_CONTROL_CS, HIGH) 42 | // 43 | #define waitspi() while(!(SPSR&(1<>5); 121 | Enc28j60Bank = (address & BANK_MASK); 122 | } 123 | } 124 | 125 | uint8_t enc28j60Read(uint8_t address) 126 | { 127 | // set the bank 128 | enc28j60SetBank(address); 129 | // do the read 130 | return enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address); 131 | } 132 | 133 | void enc28j60Write(uint8_t address, uint8_t data) 134 | { 135 | // set the bank 136 | enc28j60SetBank(address); 137 | // do the write 138 | enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data); 139 | } 140 | 141 | void enc28j60PhyWrite(uint8_t address, uint16_t data) 142 | { 143 | // set the PHY register address 144 | enc28j60Write(MIREGADR, address); 145 | // write the PHY data 146 | enc28j60Write(MIWRL, data); 147 | enc28j60Write(MIWRH, data>>8); 148 | // wait until the PHY write completes 149 | while(enc28j60Read(MISTAT) & MISTAT_BUSY){ 150 | delayMicroseconds(15); 151 | } 152 | } 153 | 154 | void enc28j60clkout(uint8_t clk) 155 | { 156 | //setup clkout: 2 is 12.5MHz: 157 | enc28j60Write(ECOCON, clk & 0x7); 158 | } 159 | 160 | void enc28j60Init(uint8_t* macaddr) 161 | { 162 | // initialize I/O 163 | // ss as output: 164 | pinMode(ENC28J60_CONTROL_CS, OUTPUT); 165 | CSPASSIVE; // ss=0 166 | // 167 | pinMode(SPI_MOSI, OUTPUT); 168 | 169 | pinMode(SPI_SCK, OUTPUT); 170 | 171 | pinMode(SPI_MISO, INPUT); 172 | 173 | 174 | digitalWrite(SPI_MOSI, LOW); 175 | 176 | digitalWrite(SPI_SCK, LOW); 177 | 178 | /*DDRB |= 1<>8); 203 | // set receive pointer address 204 | enc28j60Write(ERXRDPTL, RXSTART_INIT&0xFF); 205 | enc28j60Write(ERXRDPTH, RXSTART_INIT>>8); 206 | // RX end 207 | enc28j60Write(ERXNDL, RXSTOP_INIT&0xFF); 208 | enc28j60Write(ERXNDH, RXSTOP_INIT>>8); 209 | // TX start 210 | enc28j60Write(ETXSTL, TXSTART_INIT&0xFF); 211 | enc28j60Write(ETXSTH, TXSTART_INIT>>8); 212 | // TX end 213 | enc28j60Write(ETXNDL, TXSTOP_INIT&0xFF); 214 | enc28j60Write(ETXNDH, TXSTOP_INIT>>8); 215 | // do bank 1 stuff, packet filter: 216 | // For broadcast packets we allow only ARP packtets 217 | // All other packets should be unicast only for our mac (MAADR) 218 | // 219 | // The pattern to match on is therefore 220 | // Type ETH.DST 221 | // ARP BROADCAST 222 | // 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9 223 | // in binary these poitions are:11 0000 0011 1111 224 | // This is hex 303F->EPMM0=0x3f,EPMM1=0x30 225 | enc28j60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN); 226 | enc28j60Write(EPMM0, 0x3f); 227 | enc28j60Write(EPMM1, 0x30); 228 | enc28j60Write(EPMCSL, 0xf9); 229 | enc28j60Write(EPMCSH, 0xf7); 230 | // 231 | // 232 | // do bank 2 stuff 233 | // enable MAC receive 234 | enc28j60Write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS); 235 | // bring MAC out of reset 236 | enc28j60Write(MACON2, 0x00); 237 | // enable automatic padding to 60bytes and CRC operations 238 | enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN); 239 | // set inter-frame gap (non-back-to-back) 240 | enc28j60Write(MAIPGL, 0x12); 241 | enc28j60Write(MAIPGH, 0x0C); 242 | // set inter-frame gap (back-to-back) 243 | enc28j60Write(MABBIPG, 0x12); 244 | // Set the maximum packet size which the controller will accept 245 | // Do not send packets longer than MAX_FRAMELEN: 246 | enc28j60Write(MAMXFLL, MAX_FRAMELEN&0xFF); 247 | enc28j60Write(MAMXFLH, MAX_FRAMELEN>>8); 248 | // do bank 3 stuff 249 | // write MAC address 250 | // NOTE: MAC address in ENC28J60 is byte-backward 251 | enc28j60Write(MAADR5, macaddr[0]); 252 | enc28j60Write(MAADR4, macaddr[1]); 253 | enc28j60Write(MAADR3, macaddr[2]); 254 | enc28j60Write(MAADR2, macaddr[3]); 255 | enc28j60Write(MAADR1, macaddr[4]); 256 | enc28j60Write(MAADR0, macaddr[5]); 257 | // no loopback of transmitted frames 258 | enc28j60PhyWrite(PHCON2, PHCON2_HDLDIS); 259 | // switch to bank 0 260 | enc28j60SetBank(ECON1); 261 | // enable interrutps 262 | enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE); 263 | // enable packet reception 264 | enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); 265 | } 266 | 267 | // read the revision of the chip: 268 | uint8_t enc28j60getrev(void) 269 | { 270 | return(enc28j60Read(EREVID)); 271 | } 272 | 273 | void enc28j60PacketSend(uint16_t len, uint8_t* packet) 274 | { 275 | // Set the write pointer to start of transmit buffer area 276 | enc28j60Write(EWRPTL, TXSTART_INIT&0xFF); 277 | enc28j60Write(EWRPTH, TXSTART_INIT>>8); 278 | // Set the TXND pointer to correspond to the packet size given 279 | enc28j60Write(ETXNDL, (TXSTART_INIT+len)&0xFF); 280 | enc28j60Write(ETXNDH, (TXSTART_INIT+len)>>8); 281 | // write per-packet control byte (0x00 means use macon3 settings) 282 | enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00); 283 | // copy the packet into the transmit buffer 284 | enc28j60WriteBuffer(len, packet); 285 | // send the contents of the transmit buffer onto the network 286 | enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS); 287 | // Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12. 288 | if( (enc28j60Read(EIR) & EIR_TXERIF) ){ 289 | enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS); 290 | } 291 | } 292 | 293 | // Gets a packet from the network receive buffer, if one is available. 294 | // The packet will by headed by an ethernet header. 295 | // maxlen The maximum acceptable length of a retrieved packet. 296 | // packet Pointer where packet data should be stored. 297 | // Returns: Packet length in bytes if a packet was retrieved, zero otherwise. 298 | uint16_t enc28j60PacketReceive(uint16_t maxlen, uint8_t* packet) 299 | { 300 | uint16_t rxstat; 301 | uint16_t len; 302 | // check if a packet has been received and buffered 303 | //if( !(enc28j60Read(EIR) & EIR_PKTIF) ){ 304 | // The above does not work. See Rev. B4 Silicon Errata point 6. 305 | if( enc28j60Read(EPKTCNT) ==0 ){ 306 | return(0); 307 | } 308 | 309 | // Set the read pointer to the start of the received packet 310 | enc28j60Write(ERDPTL, (NextPacketPtr)); 311 | enc28j60Write(ERDPTH, (NextPacketPtr)>>8); 312 | // read the next packet pointer 313 | NextPacketPtr = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); 314 | NextPacketPtr |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; 315 | // read the packet length (see datasheet page 43) 316 | len = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); 317 | len |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; 318 | len-=4; //remove the CRC count 319 | // read the receive status (see datasheet page 43) 320 | rxstat = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0); 321 | rxstat |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8; 322 | // limit retrieve length 323 | if (len>maxlen-1){ 324 | len=maxlen-1; 325 | } 326 | // check CRC and symbol errors (see datasheet page 44, table 7-3): 327 | // The ERXFCON.CRCEN is set by default. Normally we should not 328 | // need to check this. 329 | if ((rxstat & 0x80)==0){ 330 | // invalid 331 | len=0; 332 | }else{ 333 | // copy the packet from the receive buffer 334 | enc28j60ReadBuffer(len, packet); 335 | } 336 | // Move the RX read pointer to the start of the next received packet 337 | // This frees the memory we just read out 338 | enc28j60Write(ERXRDPTL, (NextPacketPtr)); 339 | enc28j60Write(ERXRDPTH, (NextPacketPtr)>>8); 340 | // decrement the packet counter indicate we are done with this packet 341 | enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC); 342 | return(len); 343 | } 344 | 345 | -------------------------------------------------------------------------------- /libraries/etherShield/ip_arp_udp_tcp.c: -------------------------------------------------------------------------------- 1 | /********************************************* 2 | * vim:sw=8:ts=8:si:et 3 | * To use the above modeline in vim you must have "set modeline" in your .vimrc 4 | * 5 | * Author: Guido Socher 6 | * Copyright: GPL V2 7 | * See http://www.gnu.org/licenses/gpl.html 8 | * 9 | * IP, Arp, UDP and TCP functions. 10 | * 11 | * The TCP implementation uses some size optimisations which are valid 12 | * only if all data can be sent in one single packet. This is however 13 | * not a big limitation for a microcontroller as you will anyhow use 14 | * small web-pages. The TCP stack is therefore a SDP-TCP stack (single data packet TCP). 15 | * 16 | * Chip type : ATMEGA88 with ENC28J60 17 | *********************************************/ 18 | /********************************************* 19 | * Modified: nuelectronics.com -- Ethershield for Arduino 20 | *********************************************/ 21 | #include 22 | #include 23 | //#include "avr_compat.h" 24 | #include "net.h" 25 | #include "enc28j60.h" 26 | 27 | static uint8_t wwwport=80; 28 | static uint8_t macaddr[6]; 29 | static uint8_t ipaddr[4]; 30 | static int16_t info_hdr_len=0; 31 | static int16_t info_data_len=0; 32 | static uint8_t seqnum=0xa; // my initial tcp sequence number 33 | 34 | // The Ip checksum is calculated over the ip header only starting 35 | // with the header length field and a total length of 20 bytes 36 | // unitl ip.dst 37 | // You must set the IP checksum field to zero before you start 38 | // the calculation. 39 | // len for ip is 20. 40 | // 41 | // For UDP/TCP we do not make up the required pseudo header. Instead we 42 | // use the ip.src and ip.dst fields of the real packet: 43 | // The udp checksum calculation starts with the ip.src field 44 | // Ip.src=4bytes,Ip.dst=4 bytes,Udp header=8bytes + data length=16+len 45 | // In other words the len here is 8 + length over which you actually 46 | // want to calculate the checksum. 47 | // You must set the checksum field to zero before you start 48 | // the calculation. 49 | // len for udp is: 8 + 8 + data length 50 | // len for tcp is: 4+4 + 20 + option len + data length 51 | // 52 | // For more information on how this algorithm works see: 53 | // http://www.netfor2.com/checksum.html 54 | // http://www.msc.uky.edu/ken/cs471/notes/chap3.htm 55 | // The RFC has also a C code example: http://www.faqs.org/rfcs/rfc1071.html 56 | uint16_t checksum(uint8_t *buf, uint16_t len,uint8_t type){ 57 | // type 0=ip 58 | // 1=udp 59 | // 2=tcp 60 | uint32_t sum = 0; 61 | 62 | //if(type==0){ 63 | // // do not add anything 64 | //} 65 | if(type==1){ 66 | sum+=IP_PROTO_UDP_V; // protocol udp 67 | // the length here is the length of udp (data+header len) 68 | // =length given to this function - (IP.scr+IP.dst length) 69 | sum+=len-8; // = real tcp len 70 | } 71 | if(type==2){ 72 | sum+=IP_PROTO_TCP_V; 73 | // the length here is the length of tcp (data+header len) 74 | // =length given to this function - (IP.scr+IP.dst length) 75 | sum+=len-8; // = real tcp len 76 | } 77 | // build the sum of 16bit words 78 | while(len >1){ 79 | sum += 0xFFFF & (*buf<<8|*(buf+1)); 80 | buf+=2; 81 | len-=2; 82 | } 83 | // if there is a byte left then add it (padded with zero) 84 | if (len){ 85 | sum += (0xFF & *buf)<<8; 86 | } 87 | // now calculate the sum over the bytes in the sum 88 | // until the result is only 16bit long 89 | while (sum>>16){ 90 | sum = (sum & 0xFFFF)+(sum >> 16); 91 | } 92 | // build 1's complement: 93 | return( (uint16_t) sum ^ 0xFFFF); 94 | } 95 | 96 | // you must call this function once before you use any of the other functions: 97 | void init_ip_arp_udp_tcp(uint8_t *mymac,uint8_t *myip,uint8_t wwwp){ 98 | uint8_t i=0; 99 | wwwport=wwwp; 100 | while(i<4){ 101 | ipaddr[i]=myip[i]; 102 | i++; 103 | } 104 | i=0; 105 | while(i<6){ 106 | macaddr[i]=mymac[i]; 107 | i++; 108 | } 109 | } 110 | 111 | uint8_t eth_type_is_arp_and_my_ip(uint8_t *buf,uint16_t len){ 112 | uint8_t i=0; 113 | // 114 | if (len<41){ 115 | return(0); 116 | } 117 | if(buf[ETH_TYPE_H_P] != ETHTYPE_ARP_H_V || 118 | buf[ETH_TYPE_L_P] != ETHTYPE_ARP_L_V){ 119 | return(0); 120 | } 121 | while(i<4){ 122 | if(buf[ETH_ARP_DST_IP_P+i] != ipaddr[i]){ 123 | return(0); 124 | } 125 | i++; 126 | } 127 | return(1); 128 | } 129 | 130 | uint8_t eth_type_is_ip_and_my_ip(uint8_t *buf,uint16_t len){ 131 | uint8_t i=0; 132 | //eth+ip+udp header is 42 133 | if (len<42){ 134 | return(0); 135 | } 136 | if(buf[ETH_TYPE_H_P]!=ETHTYPE_IP_H_V || 137 | buf[ETH_TYPE_L_P]!=ETHTYPE_IP_L_V){ 138 | return(0); 139 | } 140 | if (buf[IP_HEADER_LEN_VER_P]!=0x45){ 141 | // must be IP V4 and 20 byte header 142 | return(0); 143 | } 144 | while(i<4){ 145 | if(buf[IP_DST_P+i]!=ipaddr[i]){ 146 | return(0); 147 | } 148 | i++; 149 | } 150 | return(1); 151 | } 152 | // make a return eth header from a received eth packet 153 | void make_eth(uint8_t *buf) 154 | { 155 | uint8_t i=0; 156 | // 157 | //copy the destination mac from the source and fill my mac into src 158 | while(i<6){ 159 | buf[ETH_DST_MAC +i]=buf[ETH_SRC_MAC +i]; 160 | buf[ETH_SRC_MAC +i]=macaddr[i]; 161 | i++; 162 | } 163 | } 164 | 165 | // make a new eth header for IP packet 166 | void make_eth_ip_new(uint8_t *buf, uint8_t* dst_mac) 167 | { 168 | uint8_t i=0; 169 | // 170 | //copy the destination mac from the source and fill my mac into src 171 | while(i<6){ 172 | buf[ETH_DST_MAC +i]=dst_mac[i]; 173 | buf[ETH_SRC_MAC +i]=macaddr[i]; 174 | i++; 175 | } 176 | 177 | buf[ ETH_TYPE_H_P ] = ETHTYPE_IP_H_V; 178 | buf[ ETH_TYPE_L_P ] = ETHTYPE_IP_L_V; 179 | } 180 | 181 | 182 | void fill_ip_hdr_checksum(uint8_t *buf) 183 | { 184 | uint16_t ck; 185 | // clear the 2 byte checksum 186 | buf[IP_CHECKSUM_P]=0; 187 | buf[IP_CHECKSUM_P+1]=0; 188 | buf[IP_FLAGS_P]=0x40; // don't fragment 189 | buf[IP_FLAGS_P+1]=0; // fragement offset 190 | buf[IP_TTL_P]=64; // ttl 191 | // calculate the checksum: 192 | ck=checksum(&buf[IP_P], IP_HEADER_LEN,0); 193 | buf[IP_CHECKSUM_P]=ck>>8; 194 | buf[IP_CHECKSUM_P+1]=ck& 0xff; 195 | } 196 | 197 | static uint16_t ip_identifier = 1; 198 | 199 | // make a new ip header for tcp packet 200 | 201 | // make a return ip header from a received ip packet 202 | void make_ip_tcp_new(uint8_t *buf, uint16_t len,uint8_t *dst_ip) 203 | { 204 | uint8_t i=0; 205 | 206 | // set ipv4 and header length 207 | buf[ IP_P ] = IP_V4_V | IP_HEADER_LENGTH_V; 208 | 209 | // set TOS to default 0x00 210 | buf[ IP_TOS_P ] = 0x00; 211 | 212 | // set total length 213 | buf[ IP_TOTLEN_H_P ] = (len >>8)& 0xff; 214 | buf[ IP_TOTLEN_L_P ] = len & 0xff; 215 | 216 | // set packet identification 217 | buf[ IP_ID_H_P ] = (ip_identifier >>8) & 0xff; 218 | buf[ IP_ID_L_P ] = ip_identifier & 0xff; 219 | ip_identifier++; 220 | 221 | // set fragment flags 222 | buf[ IP_FLAGS_H_P ] = 0x00; 223 | buf[ IP_FLAGS_L_P ] = 0x00; 224 | 225 | // set Time To Live 226 | buf[ IP_TTL_P ] = 128; 227 | 228 | // set ip packettype to tcp/udp/icmp... 229 | buf[ IP_PROTO_P ] = IP_PROTO_TCP_V; 230 | 231 | // set source and destination ip address 232 | while(i<4){ 233 | buf[IP_DST_P+i]=dst_ip[i]; 234 | buf[IP_SRC_P+i]=ipaddr[i]; 235 | i++; 236 | } 237 | fill_ip_hdr_checksum(buf); 238 | } 239 | 240 | 241 | // make a return ip header from a received ip packet 242 | void make_ip(uint8_t *buf) 243 | { 244 | uint8_t i=0; 245 | while(i<4){ 246 | buf[IP_DST_P+i]=buf[IP_SRC_P+i]; 247 | buf[IP_SRC_P+i]=ipaddr[i]; 248 | i++; 249 | } 250 | fill_ip_hdr_checksum(buf); 251 | } 252 | 253 | // make a return tcp header from a received tcp packet 254 | // rel_ack_num is how much we must step the seq number received from the 255 | // other side. We do not send more than 255 bytes of text (=data) in the tcp packet. 256 | // If mss=1 then mss is included in the options list 257 | // 258 | // After calling this function you can fill in the first data byte at TCP_OPTIONS_P+4 259 | // If cp_seq=0 then an initial sequence number is used (should be use in synack) 260 | // otherwise it is copied from the packet we received 261 | void make_tcphead(uint8_t *buf,uint16_t rel_ack_num,uint8_t mss,uint8_t cp_seq) 262 | { 263 | uint8_t i=0; 264 | uint8_t tseq; 265 | while(i<2){ 266 | buf[TCP_DST_PORT_H_P+i]=buf[TCP_SRC_PORT_H_P+i]; 267 | buf[TCP_SRC_PORT_H_P+i]=0; // clear source port 268 | i++; 269 | } 270 | // set source port (http): 271 | buf[TCP_SRC_PORT_L_P]=wwwport; 272 | i=4; 273 | // sequence numbers: 274 | // add the rel ack num to SEQACK 275 | while(i>0){ 276 | rel_ack_num=buf[TCP_SEQ_H_P+i-1]+rel_ack_num; 277 | tseq=buf[TCP_SEQACK_H_P+i-1]; 278 | buf[TCP_SEQACK_H_P+i-1]=0xff&rel_ack_num; 279 | if (cp_seq){ 280 | // copy the acknum sent to us into the sequence number 281 | buf[TCP_SEQ_H_P+i-1]=tseq; 282 | }else{ 283 | buf[TCP_SEQ_H_P+i-1]= 0; // some preset vallue 284 | } 285 | rel_ack_num=rel_ack_num>>8; 286 | i--; 287 | } 288 | if (cp_seq==0){ 289 | // put inital seq number 290 | buf[TCP_SEQ_H_P+0]= 0; 291 | buf[TCP_SEQ_H_P+1]= 0; 292 | // we step only the second byte, this allows us to send packts 293 | // with 255 bytes or 512 (if we step the initial seqnum by 2) 294 | buf[TCP_SEQ_H_P+2]= seqnum; 295 | buf[TCP_SEQ_H_P+3]= 0; 296 | // step the inititial seq num by something we will not use 297 | // during this tcp session: 298 | seqnum+=2; 299 | } 300 | // zero the checksum 301 | buf[TCP_CHECKSUM_H_P]=0; 302 | buf[TCP_CHECKSUM_L_P]=0; 303 | 304 | // The tcp header length is only a 4 bit field (the upper 4 bits). 305 | // It is calculated in units of 4 bytes. 306 | // E.g 24 bytes: 24/4=6 => 0x60=header len field 307 | //buf[TCP_HEADER_LEN_P]=(((TCP_HEADER_LEN_PLAIN+4)/4)) <<4; // 0x60 308 | if (mss){ 309 | // the only option we set is MSS to 1408: 310 | // 1408 in hex is 0x580 311 | buf[TCP_OPTIONS_P]=2; 312 | buf[TCP_OPTIONS_P+1]=4; 313 | buf[TCP_OPTIONS_P+2]=0x05; 314 | buf[TCP_OPTIONS_P+3]=0x80; 315 | // 24 bytes: 316 | buf[TCP_HEADER_LEN_P]=0x60; 317 | }else{ 318 | // no options: 319 | // 20 bytes: 320 | buf[TCP_HEADER_LEN_P]=0x50; 321 | } 322 | } 323 | 324 | 325 | 326 | 327 | void make_arp_answer_from_request(uint8_t *buf) 328 | { 329 | uint8_t i=0; 330 | // 331 | make_eth(buf); 332 | buf[ETH_ARP_OPCODE_H_P]=ETH_ARP_OPCODE_REPLY_H_V; 333 | buf[ETH_ARP_OPCODE_L_P]=ETH_ARP_OPCODE_REPLY_L_V; 334 | // fill the mac addresses: 335 | while(i<6){ 336 | buf[ETH_ARP_DST_MAC_P+i]=buf[ETH_ARP_SRC_MAC_P+i]; 337 | buf[ETH_ARP_SRC_MAC_P+i]=macaddr[i]; 338 | i++; 339 | } 340 | i=0; 341 | while(i<4){ 342 | buf[ETH_ARP_DST_IP_P+i]=buf[ETH_ARP_SRC_IP_P+i]; 343 | buf[ETH_ARP_SRC_IP_P+i]=ipaddr[i]; 344 | i++; 345 | } 346 | // eth+arp is 42 bytes: 347 | enc28j60PacketSend(42,buf); 348 | } 349 | 350 | void make_echo_reply_from_request(uint8_t *buf,uint16_t len) 351 | { 352 | make_eth(buf); 353 | make_ip(buf); 354 | buf[ICMP_TYPE_P]=ICMP_TYPE_ECHOREPLY_V; 355 | // we changed only the icmp.type field from request(=8) to reply(=0). 356 | // we can therefore easily correct the checksum: 357 | if (buf[ICMP_CHECKSUM_P] > (0xff-0x08)){ 358 | buf[ICMP_CHECKSUM_P+1]++; 359 | } 360 | buf[ICMP_CHECKSUM_P]+=0x08; 361 | // 362 | enc28j60PacketSend(len,buf); 363 | } 364 | 365 | // you can send a max of 220 bytes of data 366 | void make_udp_reply_from_request(uint8_t *buf,char *data,uint8_t datalen,uint16_t port) 367 | { 368 | uint8_t i=0; 369 | uint16_t ck; 370 | make_eth(buf); 371 | if (datalen>220){ 372 | datalen=220; 373 | } 374 | // total length field in the IP header must be set: 375 | buf[IP_TOTLEN_H_P]=0; 376 | buf[IP_TOTLEN_L_P]=IP_HEADER_LEN+UDP_HEADER_LEN+datalen; 377 | make_ip(buf); 378 | buf[UDP_DST_PORT_H_P]=port>>8; 379 | buf[UDP_DST_PORT_L_P]=port & 0xff; 380 | // source port does not matter and is what the sender used. 381 | // calculte the udp length: 382 | buf[UDP_LEN_H_P]=0; 383 | buf[UDP_LEN_L_P]=UDP_HEADER_LEN+datalen; 384 | // zero the checksum 385 | buf[UDP_CHECKSUM_H_P]=0; 386 | buf[UDP_CHECKSUM_L_P]=0; 387 | // copy the data: 388 | while(i>8; 394 | buf[UDP_CHECKSUM_L_P]=ck& 0xff; 395 | enc28j60PacketSend(UDP_HEADER_LEN+IP_HEADER_LEN+ETH_HEADER_LEN+datalen,buf); 396 | } 397 | 398 | void make_tcp_synack_from_syn(uint8_t *buf) 399 | { 400 | uint16_t ck; 401 | make_eth(buf); 402 | // total length field in the IP header must be set: 403 | // 20 bytes IP + 24 bytes (20tcp+4tcp options) 404 | buf[IP_TOTLEN_H_P]=0; 405 | buf[IP_TOTLEN_L_P]=IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+4; 406 | make_ip(buf); 407 | buf[TCP_FLAG_P]=TCP_FLAGS_SYNACK_V; 408 | make_tcphead(buf,1,1,0); 409 | // calculate the checksum, len=8 (start from ip.src) + TCP_HEADER_LEN_PLAIN + 4 (one option: mss) 410 | ck=checksum(&buf[IP_SRC_P], 8+TCP_HEADER_LEN_PLAIN+4,2); 411 | buf[TCP_CHECKSUM_H_P]=ck>>8; 412 | buf[TCP_CHECKSUM_L_P]=ck& 0xff; 413 | // add 4 for option mss: 414 | enc28j60PacketSend(IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+4+ETH_HEADER_LEN,buf); 415 | } 416 | 417 | // get a pointer to the start of tcp data in buf 418 | // Returns 0 if there is no data 419 | // You must call init_len_info once before calling this function 420 | uint16_t get_tcp_data_pointer(void) 421 | { 422 | if (info_data_len){ 423 | return((uint16_t)TCP_SRC_PORT_H_P+info_hdr_len); 424 | }else{ 425 | return(0); 426 | } 427 | } 428 | 429 | // do some basic length calculations and store the result in static varibales 430 | void init_len_info(uint8_t *buf) 431 | { 432 | info_data_len=(buf[IP_TOTLEN_H_P]<<8)|(buf[IP_TOTLEN_L_P]&0xff); 433 | info_data_len-=IP_HEADER_LEN; 434 | info_hdr_len=(buf[TCP_HEADER_LEN_P]>>4)*4; // generate len in bytes; 435 | info_data_len-=info_hdr_len; 436 | if (info_data_len<=0){ 437 | info_data_len=0; 438 | } 439 | } 440 | 441 | // fill in tcp data at position pos. pos=0 means start of 442 | // tcp data. Returns the position at which the string after 443 | // this string could be filled. 444 | uint16_t fill_tcp_data_p(uint8_t *buf,uint16_t pos, const char *progmem_s PROGMEM) 445 | { 446 | char c; 447 | // fill in tcp data at position pos 448 | // 449 | // with no options the data starts after the checksum + 2 more bytes (urgent ptr) 450 | while ((c = pgm_read_byte(progmem_s++))) { 451 | buf[TCP_CHECKSUM_L_P+3+pos]=c; 452 | pos++; 453 | } 454 | return(pos); 455 | } 456 | 457 | // fill in tcp data at position pos. pos=0 means start of 458 | // tcp data. Returns the position at which the string after 459 | // this string could be filled. 460 | uint16_t fill_tcp_data(uint8_t *buf,uint16_t pos, const char *s) 461 | { 462 | // fill in tcp data at position pos 463 | // 464 | // with no options the data starts after the checksum + 2 more bytes (urgent ptr) 465 | while (*s) { 466 | buf[TCP_CHECKSUM_L_P+3+pos]=*s; 467 | pos++; 468 | s++; 469 | } 470 | return(pos); 471 | } 472 | 473 | // Make just an ack packet with no tcp data inside 474 | // This will modify the eth/ip/tcp header 475 | void make_tcp_ack_from_any(uint8_t *buf) 476 | { 477 | uint16_t j; 478 | make_eth(buf); 479 | // fill the header: 480 | buf[TCP_FLAG_P]=TCP_FLAG_ACK_V; 481 | if (info_data_len==0){ 482 | // if there is no data then we must still acknoledge one packet 483 | make_tcphead(buf,1,0,1); // no options 484 | }else{ 485 | make_tcphead(buf,info_data_len,0,1); // no options 486 | } 487 | 488 | // total length field in the IP header must be set: 489 | // 20 bytes IP + 20 bytes tcp (when no options) 490 | j=IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN; 491 | buf[IP_TOTLEN_H_P]=j>>8; 492 | buf[IP_TOTLEN_L_P]=j& 0xff; 493 | make_ip(buf); 494 | // calculate the checksum, len=8 (start from ip.src) + TCP_HEADER_LEN_PLAIN + data len 495 | j=checksum(&buf[IP_SRC_P], 8+TCP_HEADER_LEN_PLAIN,2); 496 | buf[TCP_CHECKSUM_H_P]=j>>8; 497 | buf[TCP_CHECKSUM_L_P]=j& 0xff; 498 | enc28j60PacketSend(IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+ETH_HEADER_LEN,buf); 499 | } 500 | 501 | // you must have called init_len_info at some time before calling this function 502 | // dlen is the amount of tcp data (http data) we send in this packet 503 | // You can use this function only immediately after make_tcp_ack_from_any 504 | // This is because this function will NOT modify the eth/ip/tcp header except for 505 | // length and checksum 506 | void make_tcp_ack_with_data(uint8_t *buf,uint16_t dlen) 507 | { 508 | uint16_t j; 509 | // fill the header: 510 | // This code requires that we send only one data packet 511 | // because we keep no state information. We must therefore set 512 | // the fin here: 513 | buf[TCP_FLAG_P]=TCP_FLAG_ACK_V|TCP_FLAG_PUSH_V|TCP_FLAG_FIN_V; 514 | 515 | // total length field in the IP header must be set: 516 | // 20 bytes IP + 20 bytes tcp (when no options) + len of data 517 | j=IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+dlen; 518 | buf[IP_TOTLEN_H_P]=j>>8; 519 | buf[IP_TOTLEN_L_P]=j& 0xff; 520 | fill_ip_hdr_checksum(buf); 521 | // zero the checksum 522 | buf[TCP_CHECKSUM_H_P]=0; 523 | buf[TCP_CHECKSUM_L_P]=0; 524 | // calculate the checksum, len=8 (start from ip.src) + TCP_HEADER_LEN_PLAIN + data len 525 | j=checksum(&buf[IP_SRC_P], 8+TCP_HEADER_LEN_PLAIN+dlen,2); 526 | buf[TCP_CHECKSUM_H_P]=j>>8; 527 | buf[TCP_CHECKSUM_L_P]=j& 0xff; 528 | enc28j60PacketSend(IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+dlen+ETH_HEADER_LEN,buf); 529 | } 530 | 531 | 532 | /* new functions for web client interface */ 533 | void make_arp_request(uint8_t *buf, uint8_t *server_ip) 534 | { 535 | uint8_t i=0; 536 | 537 | while(i<6) 538 | { 539 | buf[ETH_DST_MAC +i]=0xff; 540 | buf[ETH_SRC_MAC +i]=macaddr[i]; 541 | i++; 542 | } 543 | 544 | buf[ ETH_TYPE_H_P ] = ETHTYPE_ARP_H_V; 545 | buf[ ETH_TYPE_L_P ] = ETHTYPE_ARP_L_V; 546 | 547 | // generate arp packet 548 | buf[ARP_OPCODE_H_P]=ARP_OPCODE_REQUEST_H_V; 549 | buf[ARP_OPCODE_L_P]=ARP_OPCODE_REQUEST_L_V; 550 | 551 | // fill in arp request packet 552 | // setup hardware type to ethernet 0x0001 553 | buf[ ARP_HARDWARE_TYPE_H_P ] = ARP_HARDWARE_TYPE_H_V; 554 | buf[ ARP_HARDWARE_TYPE_L_P ] = ARP_HARDWARE_TYPE_L_V; 555 | 556 | // setup protocol type to ip 0x0800 557 | buf[ ARP_PROTOCOL_H_P ] = ARP_PROTOCOL_H_V; 558 | buf[ ARP_PROTOCOL_L_P ] = ARP_PROTOCOL_L_V; 559 | 560 | // setup hardware length to 0x06 561 | buf[ ARP_HARDWARE_SIZE_P ] = ARP_HARDWARE_SIZE_V; 562 | 563 | // setup protocol length to 0x04 564 | buf[ ARP_PROTOCOL_SIZE_P ] = ARP_PROTOCOL_SIZE_V; 565 | 566 | // setup arp destination and source mac address 567 | for ( i=0; i<6; i++) 568 | { 569 | buf[ ARP_DST_MAC_P + i ] = 0x00; 570 | buf[ ARP_SRC_MAC_P + i ] = macaddr[i]; 571 | } 572 | 573 | // setup arp destination and source ip address 574 | for ( i=0; i<4; i++) 575 | { 576 | buf[ ARP_DST_IP_P + i ] = server_ip[i]; 577 | buf[ ARP_SRC_IP_P + i ] = ipaddr[i]; 578 | } 579 | 580 | // eth+arp is 42 bytes: 581 | enc28j60PacketSend(42,buf); 582 | 583 | } 584 | 585 | 586 | uint8_t arp_packet_is_myreply_arp ( uint8_t *buf ) 587 | { 588 | uint8_t i; 589 | 590 | // if packet type is not arp packet exit from function 591 | if( buf[ ETH_TYPE_H_P ] != ETHTYPE_ARP_H_V || buf[ ETH_TYPE_L_P ] != ETHTYPE_ARP_L_V) 592 | return 0; 593 | // check arp request opcode 594 | if ( buf[ ARP_OPCODE_H_P ] != ARP_OPCODE_REPLY_H_V || buf[ ARP_OPCODE_L_P ] != ARP_OPCODE_REPLY_L_V ) 595 | return 0; 596 | // if destination ip address in arp packet not match with avr ip address 597 | for(i=0; i<4; i++){ 598 | if(buf[ETH_ARP_DST_IP_P+i] != ipaddr[i]){ 599 | return 0; 600 | } 601 | } 602 | return 1; 603 | } 604 | 605 | // make a tcp header 606 | void tcp_client_send_packet(uint8_t *buf,uint16_t dest_port, uint16_t src_port, uint8_t flags, uint8_t max_segment_size, 607 | uint8_t clear_seqack, uint16_t next_ack_num, uint16_t dlength, uint8_t *dest_mac, uint8_t *dest_ip) 608 | { 609 | uint8_t i=0; 610 | uint8_t tseq; 611 | uint16_t ck; 612 | 613 | make_eth_ip_new(buf, dest_mac); 614 | 615 | buf[TCP_DST_PORT_H_P]= (uint8_t) ( (dest_port>>8) & 0xff); 616 | buf[TCP_DST_PORT_L_P]= (uint8_t) (dest_port & 0xff); 617 | 618 | buf[TCP_SRC_PORT_H_P]= (uint8_t) ( (src_port>>8) & 0xff); 619 | buf[TCP_SRC_PORT_L_P]= (uint8_t) (src_port & 0xff); 620 | 621 | // sequence numbers: 622 | // add the rel ack num to SEQACK 623 | 624 | if(next_ack_num) 625 | { 626 | for(i=4; i>0; i--) 627 | { 628 | next_ack_num=buf[TCP_SEQ_H_P+i-1]+next_ack_num; 629 | tseq=buf[TCP_SEQACK_H_P+i-1]; 630 | buf[TCP_SEQACK_H_P+i-1]=0xff&next_ack_num; 631 | // copy the acknum sent to us into the sequence number 632 | buf[TCP_SEQ_P + i - 1 ] = tseq; 633 | next_ack_num>>=8; 634 | } 635 | } 636 | 637 | // initial tcp sequence number,require to setup for first transmit/receive 638 | if(max_segment_size) 639 | { 640 | // put inital seq number 641 | buf[TCP_SEQ_H_P+0]= 0; 642 | buf[TCP_SEQ_H_P+1]= 0; 643 | // we step only the second byte, this allows us to send packts 644 | // with 255 bytes or 512 (if we step the initial seqnum by 2) 645 | buf[TCP_SEQ_H_P+2]= seqnum; 646 | buf[TCP_SEQ_H_P+3]= 0; 647 | // step the inititial seq num by something we will not use 648 | // during this tcp session: 649 | seqnum+=2; 650 | 651 | // setup maximum segment size 652 | buf[TCP_OPTIONS_P]=2; 653 | buf[TCP_OPTIONS_P+1]=4; 654 | buf[TCP_OPTIONS_P+2]=0x05; 655 | buf[TCP_OPTIONS_P+3]=0x80; 656 | // 24 bytes: 657 | buf[TCP_HEADER_LEN_P]=0x60; 658 | 659 | dlength +=4; 660 | } 661 | else{ 662 | // no options: 663 | // 20 bytes: 664 | buf[TCP_HEADER_LEN_P]=0x50; 665 | } 666 | 667 | make_ip_tcp_new(buf,IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+dlength, dest_ip); 668 | 669 | // clear sequence ack numer before send tcp SYN packet 670 | if(clear_seqack) 671 | { 672 | buf[TCP_SEQACK_P] = 0; 673 | buf[TCP_SEQACK_P+1] = 0; 674 | buf[TCP_SEQACK_P+2] = 0; 675 | buf[TCP_SEQACK_P+3] = 0; 676 | } 677 | // zero the checksum 678 | buf[TCP_CHECKSUM_H_P]=0; 679 | buf[TCP_CHECKSUM_L_P]=0; 680 | 681 | // set up flags 682 | buf[TCP_FLAG_P] = flags; 683 | // setup maximum windows size 684 | buf[ TCP_WINDOWSIZE_H_P ] = ((600 - IP_HEADER_LEN - ETH_HEADER_LEN)>>8) & 0xff; 685 | buf[ TCP_WINDOWSIZE_L_P ] = (600 - IP_HEADER_LEN - ETH_HEADER_LEN) & 0xff; 686 | 687 | // setup urgend pointer (not used -> 0) 688 | buf[ TCP_URGENT_PTR_H_P ] = 0; 689 | buf[ TCP_URGENT_PTR_L_P ] = 0; 690 | 691 | // check sum 692 | ck=checksum(&buf[IP_SRC_P], 8+TCP_HEADER_LEN_PLAIN+dlength,2); 693 | buf[TCP_CHECKSUM_H_P]=ck>>8; 694 | buf[TCP_CHECKSUM_L_P]=ck& 0xff; 695 | // add 4 for option mss: 696 | enc28j60PacketSend(IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+dlength+ETH_HEADER_LEN,buf); 697 | 698 | } 699 | 700 | uint16_t tcp_get_dlength ( uint8_t *buf ) 701 | { 702 | int dlength, hlength; 703 | 704 | dlength = ( buf[ IP_TOTLEN_H_P ] <<8 ) | ( buf[ IP_TOTLEN_L_P ] ); 705 | dlength -= IP_HEADER_LEN; 706 | hlength = (buf[ TCP_HEADER_LEN_P ]>>4) * 4; // generate len in bytes; 707 | dlength -= hlength; 708 | if ( dlength <= 0 ) 709 | dlength=0; 710 | 711 | return ((uint16_t)dlength); 712 | } 713 | 714 | /* end of ip_arp_udp.c */ 715 | --------------------------------------------------------------------------------