Subversion Repositories HomeAutomation

Rev

Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
205 arune 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
}