Subversion Repositories HomeAutomation

Rev

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