Pastie now auto-senses if line-wrap is a bad or good idea. Feedback?
## mark a section (Learn more)
/********************************************* * vim:sw=8:ts=8:si:et * To use the above modeline in vim you must have "set modeline" in your .vimrc * Author: Guido Socher * Copyright: GPL V2 * * Ethernet remote device and sensor * * Title: Microchip ENC28J60 Ethernet Interface Driver * Chip type : ATMEGA88 with ENC28J60 *********************************************/ #include <avr/io.h> #include <stdlib.h> #include <string.h> #include "ip_arp_udp.h" //#include "timeout.h" #include "enc28j60.h" #include "avr_compat.h" #include "net.h" // please modify the following two lines. mac and ip have to be unique // in your local area network. You can not have the same numbers in // two devices: static uint8_t mymac[6] = {0x54,0x01,0x02,0x03,0x04,0x05}; static uint8_t myip[4] = {192,168,0,124}; static uint16_t myport = 1200; // listen port for udp // how did I get the mac addr? Translate the first 3 numbers into ascii is: TUX #define BUFFER_SIZE 250 static uint8_t buf[BUFFER_SIZE+1]; // the password string (only the first 5 char checked): static char password[]="secret"; uint8_t verify_password(char *str) { // the first characters of the received string are // a simple password/cookie: if (strncmp(password,str,5)==0){ return(1); } return(0); } uint16_t plen; uint8_t i=0; uint8_t cmd_pos=0; uint8_t payloadlen=0; char str[30]; char cmdval; void setup(void) { // set the clock speed to 8MHz // set the clock prescaler. First write CLKPCE to enable setting of clock the // next four instructions. CLKPR=(1<<CLKPCE); CLKPR=1; // 8 MHZ delay(10); /* enable PB0, reset as output */ DDRB|= (1<<DDB0); /* enable PD2/INT0, as input */ DDRD&= ~(1<<DDD2); /* set output to gnd, reset the ethernet chip */ PORTB &= ~(1<<PB0); delay(10); /* set output to Vcc, reset inactive */ PORTB|= (1<<PB0); delay(200); /*initialize enc28j60*/ enc28j60Init(mymac); delay(20); // LED /* enable PB1, LED as output */ DDRB|= (1<<DDB1); /* set output to Vcc, LED off */ PORTB|= (1<<PB1); // the transistor on PD7 DDRD|= (1<<DDD7); PORTD &= ~(1<<PD7);// transistor off /* Magjack leds configuration, see enc28j60 datasheet, page 11 */ // LEDB=yellow LEDA=green // // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10); enc28j60PhyWrite(PHLCON,0x476); delay(20); /* set output to GND, red LED on */ PORTB &= ~(1<<PB1); i=1; //init the ethernet/ip layer: init_ip_arp_udp(mymac,myip); Serial.begin(19200); Serial.println("AVR Initialized"); } int main(void) { init(); // Call user setup setup(); // Call user main loop while (1) { // get the next new packet: plen = enc28j60PacketReceive(BUFFER_SIZE, buf); /** plen will ne unequal to zero if there is a valid * packet (without crc error) **/ if(plen==0) { continue; } // led---------- if (i) { /* set output to Vcc, LED off */ PORTB|= (1<<PB1); i=0; } else{ /* set output to GND, LED on */ PORTB &= ~(1<<PB1); i=1; } // arp is broadcast if unknown but a host may also // verify the mac address by sending it to // a unicast address. if(eth_type_is_arp_and_my_ip(buf,plen)) { Serial.println("eth_type_is_arp_and_my_ip==1"); delay(2000); make_arp_answer_from_request(buf,plen); continue; } // check if ip packets (icmp or udp) are for us: if(eth_type_is_ip_and_my_ip(buf,plen)==0) { Serial.println("eth_type_is_arp_and_my_ip==0"); delay(2000); continue; } if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V) { Serial.println("buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V"); delay(2000); // a ping packet, let's send pong make_echo_reply_from_request(buf,plen); continue; } // we listen on port 1200=0x4B0 if (buf[IP_PROTO_P]==IP_PROTO_UDP_V&&buf[UDP_DST_PORT_H_P]==4&&buf[UDP_DST_PORT_L_P]==0xb0) { Serial.println("buf[IP_PROTO_P]==IP_PROTO_UDP_V&&buf[UDP_DST_PORT_H_P]==4&&buf[UDP_DST_PORT_L_P]==0xb0"); delay(2000); payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN; // you must sent a string starting with v // e.g udpcom version 10.0.0.24 if (verify_password((char *)&(buf[UDP_DATA_P]))) { // find the first comma which indicates // the start of a command: cmd_pos=0; while(cmd_pos<payloadlen) { cmd_pos++; if (buf[UDP_DATA_P+cmd_pos]==',') { cmd_pos++; // put on start of cmd break; } } // a command is one char and a value. At // least 3 characters long. It has an '=' on // position 2: if (cmd_pos<2 || cmd_pos>payloadlen-3 || buf[UDP_DATA_P+cmd_pos+1]!='=') { strcpy(str,"e=no_cmd"); goto ANSWER; } // supported commands are // t=1 t=0 t=? if (buf[UDP_DATA_P+cmd_pos]=='t') { cmdval=buf[UDP_DATA_P+cmd_pos+2]; if(cmdval=='1') { PORTD|= (1<<PD7);// transistor on strcpy(str,"t=1"); goto ANSWER; } else if(cmdval=='0') { PORTD &= ~(1<<PD7);// transistor off strcpy(str,"t=0"); goto ANSWER; } else if(cmdval=='?') { if (PORTD & (1<<PD7)) { strcpy(str,"t=1"); goto ANSWER; } strcpy(str,"t=0"); goto ANSWER; } } strcpy(str,"e=no_such_cmd"); goto ANSWER; } strcpy(str,"e=invalid_pw"); ANSWER: make_udp_reply_from_request(buf,str,strlen(str),myport); } } return 0; }
This paste will be private.
From the Design Piracy series on my blog: