Subversion Repositories HomeAutomation

Rev

Rev 205 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  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.  * Ethernet remote device and sensor
  8.  *
  9.  * Title: Microchip ENC28J60 Ethernet Interface Driver
  10.  * Chip type           : ATMEGA88 with ENC28J60
  11.  *********************************************/
  12. /*-----------------------------------------------------------------------------
  13.  * Includes
  14.  *---------------------------------------------------------------------------*/
  15. /* system files */
  16. #include <avr/io.h>
  17.  
  18. /* lib files */
  19. #include <ip_arp_udp_tcp.h>
  20. #include <enc28j60.h>
  21. #include <timeout.h>
  22. #include <avr_compat.h>
  23. #include <net.h>
  24.  
  25. // please modify the following two lines. mac and ip have to be unique
  26. // in your local area network. You can not have the same numbers in
  27. // two devices:
  28. static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x24};
  29. static uint8_t myip[4] = {193,11,254,22};
  30. static uint16_t myport =1200; // listen port for udp
  31. // how did I get the mac addr? Translate the first 3 numbers into ascii is: TUX
  32.  
  33. #define BUFFER_SIZE 250
  34. static uint8_t buf[BUFFER_SIZE+1];
  35.  
  36. int main(void){
  37.  
  38.        
  39.         uint16_t plen;
  40.         uint8_t i=0;
  41.         uint8_t payloadlen=0;
  42.        
  43.         // set the clock speed to 8MHz
  44.         // set the clock prescaler. First write CLKPCE to enable setting of clock the
  45.         // next four instructions.
  46.         CLKPR=(1<<CLKPCE);
  47.         CLKPR=0; // 8 MHZ
  48.        
  49.         /* enable PB0, reset as output */
  50.         DDRB|= (1<<DDB0);
  51.  
  52.         /* set output to gnd, reset the ethernet chip */
  53.         PORTB &= ~(1<<PB0);
  54.         delay_ms(20);
  55.         /* set output to Vcc, reset inactive */
  56.         PORTB|= (1<<PB0);
  57.         delay_ms(100);
  58.        
  59.         // LED
  60.         /* enable PB1, LED as output */
  61.         DDRD|= (1<<DDD6);
  62.  
  63.         /* set output to Vcc, LED off */
  64.         PORTD|= (1<<PD6);
  65.  
  66.         /*initialize enc28j60*/
  67.         enc28j60Init(mymac);
  68.         delay_ms(20);
  69.        
  70.         /* Magjack leds configuration, see enc28j60 datasheet, page 11 */
  71.         // LEDB=yellow LEDA=green
  72.         //
  73.         // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit
  74.         // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10);
  75.         enc28j60PhyWrite(PHLCON,0x476);
  76.         delay_ms(20);
  77.        
  78.         /* set output to GND, red LED on */
  79.         PORTD &= ~(1<<PD6);
  80.         i=1;
  81.        
  82.         //init the ethernet/ip layer:
  83.         init_ip_arp_udp_tcp(mymac,myip,80);
  84.  
  85.         while(1){
  86.                 // get the next new packet:
  87.                 plen = enc28j60PacketReceive(BUFFER_SIZE, buf);
  88.  
  89.                 /*plen will ne unequal to zero if there is a valid
  90.                  * packet (without crc error) */
  91.                 if(plen==0){
  92.                         continue;
  93.                 }
  94.                 // arp is broadcast if unknown but a host may also
  95.                 // verify the mac address by sending it to
  96.                 // a unicast address.
  97.                 if(eth_type_is_arp_and_my_ip(buf,plen)){
  98.                         make_arp_answer_from_request(buf);
  99.                         continue;
  100.                 }
  101.                 // check if ip packets (icmp or udp) are for us:
  102.                 if(eth_type_is_ip_and_my_ip(buf,plen)==0){
  103.                         continue;
  104.                 }
  105.                
  106.                 if (i){
  107.                         /* set output to Vcc, LED off */
  108.                         PORTD|= (1<<PD6);
  109.                         i=0;
  110.                 }else{
  111.                         /* set output to GND, LED on */
  112.                         PORTD &= ~(1<<PD6);
  113.                         i=1;
  114.                 }
  115.  
  116.                        
  117.                 if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){
  118.                         // a ping packet, let's send pong
  119.                         make_echo_reply_from_request(buf,plen);
  120.                         continue;
  121.                 }
  122.                 if (buf[IP_PROTO_P]==IP_PROTO_UDP_V){
  123.                         payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
  124.                         if (buf[UDP_DATA_P]=='t' && payloadlen==5){
  125.                                 make_udp_reply_from_request(buf,"hello",6,myport);
  126.                         }
  127.                 }
  128.         }
  129.         return (0);
  130. }
  131.