URL
https://opencores.org/ocsvn/turbo8051/turbo8051/trunk
Subversion Repositories turbo8051
Compare Revisions
- This comparison shows the changes necessary to convert path
/turbo8051/trunk
- from Rev 41 to Rev 42
- ↔ Reverse comparison
Rev 41 → Rev 42
/apps/webserver/ip.c
1,3 → 1,47
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Tubo 8051 WebServer Project //// |
//// //// |
//// This file is part of the Turbo 8051 cores project //// |
//// http://www.opencores.org/cores/turbo8051/ //// |
//// //// |
//// Description //// |
//// The basic code is taken from MicroWeb project and necessary //// |
// upgrade is done to match the Turbo 8051 Webserver //// |
//// //// |
//// To Do: //// |
//// nothing //// |
//// //// |
//// Author(s): //// |
//// - Dinesh Annayya, dinesha@opencores.org //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// Basic Code is from : |
// Copyright (C) 2002 Mason Kidd (mrkidd@nettaxi.com) |
// |
// This file is part of MicroWeb. |
17,7 → 61,63
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
// ip.c: IP protocol processing |
/************************************************************ |
IP4 header: |
|
1. Version. 4 bits. |
Specifies the format of the IP packet header. |
4 --- IP, Internet Protocol. |
2. IHL, Internet Header Length. 4 bits. |
Specifies the length of the IP packet header in 32 bit words. |
The minimum value for a valid header is 5. |
|
3. Differentiated Services. 8 bits. |
|
4. Codepoint. 6 bits. |
|
5. unused. 2 bits. |
|
6. TOS, Type of Service. 8 bits. |
|
7. Total length. 16 bits. |
Contains the length of the datagram. |
|
8. Identification. 16 bits. |
Used to identify the fragments of one datagram from those of another. |
The originating protocol module of an internet datagram sets the identification field to a value that must be unique for that source-destination pair and protocol for the time the datagram will be active in the internet system. The originating protocol module of a complete datagram clears the MF bit to zero and the Fragment Offset field to zero. |
|
9. Flags. 3 bits. |
9.A R, reserved. 1 bit. |
Should be cleared to 0. |
9.B DF, Don't fragment. 1 bit. |
Controls the fragmentation of the datagram. |
9.C MF, More fragments. 1 bit. |
Indicates if the datagram contains additional fragments. |
|
10. Fragment Offset. 13 bits. |
|
11. TTL, Time to Live. 8 bits. |
A timer field used to track the lifetime of the datagram. |
When the TTL field is decremented down to zero, the datagram is discarded. |
|
12. Protocol. 8 bits. |
This field specifies the next encapsulated protocol. |
|
1 -- ICMP, Internet Control Message Protocol. |
2 -- IGAP, IGMP for user Authentication Protocol. |
IGMP, Internet Group Management Protocol. |
RGMP, Router-port Group Management Protocol. |
4 -- IP in IP encapsulation. |
6 -- TCP, Transmission Control Protocol. |
17-- UDP, User Datagram Protocol. |
41-- IPv6 over IPv4. |
58-- ICMPv6, Internet Control Message Protocol for IPv6. |
MLD, Multicast Listener Discovery. |
59-- IPv6 No Next Header. |
97-- EtherIP. |
**********************************************************************/ |
|
|
#include <string.h> |
#include "packets.h" |
#include "csio.h" |
/apps/webserver/arp.c
1,3 → 1,49
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Tubo 8051 WebServer Project //// |
//// //// |
//// This file is part of the Turbo 8051 cores project //// |
//// http://www.opencores.org/cores/turbo8051/ //// |
//// //// |
//// Description //// |
//// The basic code is taken from MicroWeb project and necessary //// |
// upgrade is done to match the Turbo 8051 Webserver //// |
//// //// |
//// To Do: //// |
//// nothing //// |
//// //// |
//// Author(s): //// |
//// - Dinesh Annayya, dinesha@opencores.org //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
///////////////////////////////////////////////////////////////////// |
// Basic Code is from : |
// Copyright (C) 2002 Mason Kidd (mrkidd@nettaxi.com) |
// |
// This file is part of MicroWeb. |
17,7 → 63,69
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
// arp.c: processing for ARP packets |
/******************************************************* |
Arp Packet Format |
[15:0] - HRD = 1 |
[15:0] - PRO = 0x0800 |
[7:0] - HLN = 6 |
[7:0] - PLN = 4 |
[15:0] - OP |
[47:0] - SHA [0-5] |
[31:0] - SPA [0-3] |
[47:0] - THA [0-5] |
[31:0] - TPA [0-3] |
|
HRD (Hardware Type): This field specfies the type of hardware used for the local network |
transmitting the ARP message. |
1 - Ethernet (10MB) |
6 - IEEE 802 Networks |
7 - ARCNET |
15 - Frame Relay |
16 - Asynhronous Transfer Mode (ATM) |
17 - HDLC |
18 - Fibre Channel |
19 - Asynchronous |
|
|
PRO (Protocol Type): This field is the complement of the Hardware Type field, |
specifying the type of layer three addresses used in the message. |
For IPv4 addresses, this value is 2048 (0800 hex), |
which corresponds to the EtherType code for the Internet Protocol. |
|
HLN (Hardware Address Length): |
Specifies how long hardware addresses are in this message. |
For Ethernet or other networks using IEEE 802 MAC addresses, the value is 6. |
|
PLN (Protocol Address Length): |
The complement of the preceding field; specifies how long protocol (layer three) |
addresses are in this message. For IP(v4) addresses this value is of course 4. |
|
OP (Opcode): This field specifes the nature of the Arp Message being sent |
1 -- ARP Request |
2 -- ARP Reply |
3 -- RARP Request |
4 -- RARP Reply |
5 -- DRARP Request |
6 -- DRARP Reply |
7 -- DRARP Error |
8 -- InARP Request |
9 -- InARP Reply |
|
SHA (Sender Hardware Address): |
The hardware (layer two) address of the device sending this message |
|
SPA (Sender Protocol Address): |
The IP address of the device sending this message. |
|
THA (Target Hardware Address): |
The hardware (layer two) address of the device this message is being sent to. |
|
TPA (Target Protocol Address): |
The IP address of the device this message is being sent to. |
|
|
********************************************************/ |
|
#include <string.h> |
#include "packets.h" |
#include "csio.h" |
/apps/avr-webserver/enc28j60.c
0,0 → 1,602
+
+
+ // enable PB0, reset as output /
+ ENC28J60_DDR |= _BV(ENC28J60_RESET_PIN_DDR);
+
+ // enable PD2/INT0, as input /
+ ENC28J60_DDR &= ~_BV(ENC28J60_INT_PIN_DDR);
+
+ // set output to gnd, reset the ethernet chip /
+ ENC28J60_PORT &= ~_BV(ENC28J60_RESET_PIN);
+ _delay_ms(10);
+ // set output to Vcc, reset inactive /
+ ENC28J60_PORT |= _BV(ENC28J60_RESET_PIN);
+ _delay_ms(200);
+
+ //initialize enc28j60/
+ //enc28j60Init( avr_mac );
+ //_delay_ms( 20 );
+
+
+ DDRB |= _BV( DDB4 ) | _BV( DDB5 ) | _BV( DDB7 ); // mosi, sck, ss output
+ //DDRB &= ~_BV( DDB6 ); // MISO is input
+
+
+ PORTB &= ~(_BV( PB5 ) | _BV( PB7 ) );
+
+ // initialize SPI interface
+ // master mode and Fosc/2 clock:
+ SPCR = _BV( SPE ) | _BV( MSTR );
+ SPSR |= _BV( SPI2X );
+
+ // perform system reset
+ enc28j60WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
+ _delay_ms(50);
+
+ // check CLKRDY bit to see if reset is complete
+ // The CLKRDY does not work. See Rev. B4 Silicon Errata point. Just wait.
+ //while(!(enc28j60Read(ESTAT) & ESTAT_CLKRDY));
+ // do bank 0 stuff
+ // initialize receive buffer
+ // 16-bit transfers, must write low byte first
+ // set receive buffer start address
+ next_packet_ptr.word = RXSTART_INIT;
+ // Rx start
+ enc28j60Write(ERXSTL, RXSTART_INIT&0xFF);
+ enc28j60Write(ERXSTH, RXSTART_INIT>>8);
+ // set receive pointer address
+ enc28j60Write(ERXRDPTL, RXSTART_INIT&0xFF);
+ enc28j60Write(ERXRDPTH, RXSTART_INIT>>8);
+ // RX end
+ enc28j60Write(ERXNDL, RXSTOP_INIT&0xFF);
+ enc28j60Write(ERXNDH, RXSTOP_INIT>>8);
+ // TX start
+ enc28j60Write(ETXSTL, TXSTART_INIT&0xFF);
+ enc28j60Write(ETXSTH, TXSTART_INIT>>8);
+ // TX end
+ enc28j60Write(ETXNDL, TXSTOP_INIT&0xFF);
+ enc28j60Write(ETXNDH, TXSTOP_INIT>>8);
+ // do bank 1 stuff, packet filter:
+ // For broadcast packets we allow only ARP packtets
+ // All other packets should be unicast only for our mac (MAADR)
+ //
+ // The pattern to match on is therefore
+ // Type ETH.DST
+ // ARP BROADCAST
+ // 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9
+ // in binary these poitions are:11 0000 0011 1111
+ // This is hex 303F->EPMM0=0x3f,EPMM1=0x30
+ enc28j60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN);
+ enc28j60Write(EPMM0, 0x3f);
+ enc28j60Write(EPMM1, 0x30);
+ enc28j60Write(EPMCSL, 0xf9);
+
+
+ // do bank 2 stuff
+ // enable MAC receive
+ enc28j60Write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);
+ // bring MAC out of reset
+ //enc28j60Write(MACON2, 0x00);
+ // enable automatic padding to 60bytes and CRC operations
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);
+ // set inter-frame gap (non-back-to-back)
+ enc28j60Write(MAIPGL, 0x12);
+ enc28j60Write(MAIPGH, 0x0C);
+ // set inter-frame gap (back-to-back)
+ enc28j60Write(MABBIPG, 0x12);
+ // Set the maximum packet size which the controller will accept
+ // Do not send packets longer than MAX_FRAMELEN:
+ enc28j60Write(MAMXFLL, MAX_FRAMELEN&0xFF);
+ enc28j60Write(MAMXFLH, MAX_FRAMELEN>>8);
+ // do bank 3 stuff
+ // write MAC address
+
+ // ENC28J60 is big-endian avr gcc is little-endian
+ enc28j60Write(MAADR5, avr_mac[0]);
+ enc28j60Write(MAADR4, avr_mac[1]);
+ enc28j60Write(MAADR3, avr_mac[2]);
+ enc28j60Write(MAADR2, avr_mac[3]);
+ enc28j60Write(MAADR1, avr_mac[4]);
+ enc28j60Write(MAADR0, avr_mac[5]);
+ // no loopback of transmitted frames
+ enc28j60PhyWrite(PHCON2, (WORD_BYTES){PHCON2_HDLDIS});
+ // switch to bank 0
+ enc28j60SetBank(ECON1);
+ // enable interrutps
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);
+ // enable packet reception
+
+
+ // 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);
+
+
+
+
+ //enc28j60_flag.rx_buffer_is_free = 1;
+ _delay_ms(20);
+}
+*/
+void enc28j60_init( BYTE *avr_mac)
+{
+ // initialize I/O
+ //DDRB |= _BV( DDB4 );
+ //CSPASSIVE;
+
+ // enable PB0, reset as output
+ ENC28J60_DDR |= _BV(ENC28J60_RESET_PIN_DDR);
+
+ // enable PD2/INT0, as input
+ ENC28J60_DDR &= ~_BV(ENC28J60_INT_PIN_DDR);
+ ENC28J60_PORT |= _BV(ENC28J60_INT_PIN);
+
+ // set output to gnd, reset the ethernet chip
+ ENC28J60_PORT &= ~_BV(ENC28J60_RESET_PIN);
+ _delay_ms(10);
+
+ // set output to Vcc, reset inactive
+ ENC28J60_PORT |= _BV(ENC28J60_RESET_PIN);
+ _delay_ms(200);
+
+ //
+ DDRB |= _BV( DDB4 ) | _BV( DDB5 ) | _BV( DDB7 ); // mosi, sck, ss output
+ //DDRB &= ~_BV( DDB6 ); // MISO is input
+
+ CSPASSIVE;
+ PORTB &= ~(_BV( PB5 ) | _BV( PB7 ) );
+ //
+ // initialize SPI interface
+ // master mode and Fosc/2 clock:
+ SPCR = _BV( SPE ) | _BV( MSTR );
+ SPSR |= _BV( SPI2X );
+
+ // perform system reset
+ enc28j60WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
+ _delay_ms(50);
+
+ // check CLKRDY bit to see if reset is complete
+ // The CLKRDY does not work. See Rev. B4 Silicon Errata point. Just wait.
+ //while(!(enc28j60Read(ESTAT) & ESTAT_CLKRDY));
+ // do bank 0 stuff
+ // initialize receive buffer
+ // 16-bit transfers, must write low byte first
+ // set receive buffer start address
+ next_packet_ptr.word = RXSTART_INIT;
+ // Rx start
+ enc28j60Write(ERXSTL, RXSTART_INIT&0xFF);
+ enc28j60Write(ERXSTH, RXSTART_INIT>>8);
+ // set receive pointer address
+ enc28j60Write(ERXRDPTL, RXSTART_INIT&0xFF);
+ enc28j60Write(ERXRDPTH, RXSTART_INIT>>8);
+ // RX end
+ enc28j60Write(ERXNDL, RXSTOP_INIT&0xFF);
+ enc28j60Write(ERXNDH, RXSTOP_INIT>>8);
+ // TX start
+ enc28j60Write(ETXSTL, TXSTART_INIT&0xFF);
+ enc28j60Write(ETXSTH, TXSTART_INIT>>8);
+ // TX end
+ enc28j60Write(ETXNDL, TXSTOP_INIT&0xFF);
+ enc28j60Write(ETXNDH, TXSTOP_INIT>>8);
+
+ // do bank 2 stuff
+ // enable MAC receive
+ enc28j60Write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);
+
+ // bring MAC out of reset
+ //enc28j60Write(MACON2, 0x00);
+
+ // enable automatic padding to 60bytes and CRC operations
+ enc28j60Write(MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);
+
+ // Allow infinite deferals if the medium is continuously busy
+ // (do not time out a transmission if the half duplex medium is
+ // completely saturated with other people's data)
+ enc28j60Write(MACON4, MACON4_DEFER);
+
+ // Late collisions occur beyond 63+8 bytes (8 bytes for preamble/start of frame delimiter)
+ // 55 is all that is needed for IEEE 802.3, but ENC28J60 B5 errata for improper link pulse
+ // collisions will occur less often with a larger number.
+ enc28j60Write(MACLCON2, 63);
+
+ // Set non-back-to-back inter-packet gap to 9.6us. The back-to-back
+ // inter-packet gap (MABBIPG) is set by MACSetDuplex() which is called
+ // later.
+ enc28j60Write(MAIPGL, 0x12);
+ enc28j60Write(MAIPGH, 0x0C);
+
+ // Set the maximum packet size which the controller will accept
+ // Do not send packets longer than MAX_FRAMELEN:
+ enc28j60Write(MAMXFLL, MAX_FRAMELEN&0xFF);
+ enc28j60Write(MAMXFLH, MAX_FRAMELEN>>8);
+
+ // do bank 3 stuff
+ // write MAC address
+ // NOTE: MAC address in ENC28J60 is byte-backward
+ // ENC28J60 is big-endian avr gcc is little-endian
+ enc28j60Write(MAADR5, avr_mac[0]);
+ enc28j60Write(MAADR4, avr_mac[1]);
+ enc28j60Write(MAADR3, avr_mac[2]);
+ enc28j60Write(MAADR2, avr_mac[3]);
+ enc28j60Write(MAADR1, avr_mac[4]);
+ enc28j60Write(MAADR0, avr_mac[5]);
+
+ // no loopback of transmitted frames
+ enc28j60PhyWrite(PHCON2, (WORD_BYTES){PHCON2_HDLDIS});
+
+ // Magjack leds configuration, see enc28j60 datasheet, page 11
+ // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit
+ // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 00 10);
+ enc28j60PhyWrite(PHLCON,(WORD_BYTES){0x0472});
+
+ // do bank 1 stuff, packet filter:
+ // For broadcast packets we allow only ARP packtets
+ // All other packets should be unicast only for our mac (MAADR)
+ //
+ // The pattern to match on is therefore
+ // Type ETH.DST
+ // ARP BROADCAST
+ // 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9
+ // in binary these poitions are:11 0000 0011 1111
+ // This is hex 303F->EPMM0=0x3f,EPMM1=0x30
+ enc28j60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN);
+ enc28j60Write(EPMM0, 0x3f);
+ enc28j60Write(EPMM1, 0x30);
+ enc28j60Write(EPMCSL, 0xf9);
+ enc28j60Write(EPMCSH, 0xf7);
+
+ // set inter-frame gap (back-to-back)
+ enc28j60Write(MABBIPG, 0x12);
+
+ // switch to bank 0
+ enc28j60SetBank(ECON1);
+
+ // enable interrutps
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);
+
+ // enable packet reception
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
+
+ _delay_ms(20);
+}
+//*******************************************************************************************
+//
+// Function : enc28j60getrev
+// Description : read the revision of the chip.
+//
+//*******************************************************************************************
+BYTE enc28j60getrev(void)
+{
+ return(enc28j60Read(EREVID));
+}
+//*******************************************************************************************
+//
+// Function : enc28j60_packet_send
+// Description : Send packet to network.
+//
+//*******************************************************************************************
+void enc28j60_packet_send ( BYTE *buffer, WORD length )
+{
+ //Set the write pointer to start of transmit buffer area
+ enc28j60Write(EWRPTL, LOW(TXSTART_INIT) );
+ enc28j60Write(EWRPTH, HIGH(TXSTART_INIT) );
+
+ // Set the TXND pointer to correspond to the packet size given
+ enc28j60Write(ETXNDL, LOW((TXSTART_INIT+length)) );
+ enc28j60Write(ETXNDH, HIGH((TXSTART_INIT+length)) );
+
+ // write per-packet control byte (0x00 means use macon3 settings)
+ enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00);
+
+ CSACTIVE;
+ // issue write command
+ SPDR = ENC28J60_WRITE_BUF_MEM;
+ waitspi();
+ while(length)
+ {
+ length--;
+ // write data
+ SPDR = *buffer++;
+ waitspi();
+ }
+ CSPASSIVE;
+
+ // send the contents of the transmit buffer onto the network
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
+
+ // Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12.
+ if( (enc28j60Read(EIR) & EIR_TXERIF) )
+ {
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS);
+ }
+}
+//*******************************************************************************************
+//
+// Function : enc28j60_mac_is_linked
+// Description : return MAC link status.
+//
+//*******************************************************************************************
+/*
+BYTE enc28j60_mac_is_linked(void)
+{
+ if ( (enc28j60_read_phyreg(PHSTAT1) & PHSTAT1_LLSTAT ) )
+ return 1;
+ else
+ return 0;
+}
+*/
+//*******************************************************************************************
+//
+// Function : enc28j60_packet_receive
+// Description : check received packet and return length of data
+//
+//*******************************************************************************************
+//WORD data_length;
+WORD enc28j60_packet_receive ( BYTE *rxtx_buffer, WORD max_length )
+{
+ WORD_BYTES rx_status, data_length;
+
+ // check if a packet has been received and buffered
+ // if( !(enc28j60Read(EIR) & EIR_PKTIF) ){
+ // The above does not work. See Rev. B4 Silicon Errata point 6.
+ if( enc28j60Read(EPKTCNT) == 0 )
+ {
+ return 0;
+ }
+
+ // Set the read pointer to the start of the received packet
+ enc28j60Write(ERDPTL, next_packet_ptr.bytes[0]);
+ enc28j60Write(ERDPTH, next_packet_ptr.bytes[1]);
+
+ // read the next packet pointer
+ next_packet_ptr.bytes[0] = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
+ next_packet_ptr.bytes[1] = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
+
+ // read the packet length (see datasheet page 43)
+ data_length.bytes[0] = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
+ data_length.bytes[1] = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
+ data_length.word -=4; //remove the CRC count
+
+ // read the receive status (see datasheet page 43)
+ rx_status.bytes[0] = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
+ rx_status.bytes[1] = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);
+
+ if ( data_length.word > (max_length-1) )
+ {
+ data_length.word = max_length-1;
+ }
+
+ // check CRC and symbol errors (see datasheet page 44, table 7-3):
+ // The ERXFCON.CRCEN is set by default. Normally we should not
+ // need to check this.
+ if ( (rx_status.word & 0x80)==0 )
+ {
+ // invalid
+ data_length.word = 0;
+ }
+ else
+ {
+ // read data from rx buffer and save to rxtx_buffer
+ rx_status.word = data_length.word;
+ CSACTIVE;
+ // issue read command
+ SPDR = ENC28J60_READ_BUF_MEM;
+ waitspi();
+ while(rx_status.word)
+ {
+ rx_status.word--;
+ SPDR = 0x00;
+ waitspi();
+ *rxtx_buffer++ = SPDR;
+ }
+ CSPASSIVE;
+ }
+
+ // Move the RX read pointer to the start of the next received packet
+ // This frees the memory we just read out
+ enc28j60Write(ERXRDPTL, next_packet_ptr.bytes[0]);
+ enc28j60Write(ERXRDPTH, next_packet_ptr.bytes[1]);
+
+ // decrement the packet counter indicate we are done with this packet
+ enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
+
+ return( data_length.word );
+}
+
//******************************************************************************************** |
// |
// File : enc28j60.c Microchip ENC28J60 Ethernet Interface Driver |
// |
//******************************************************************************************** |
// |
// Copyright (C) 2007 |
// |
// This program is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free Software |
// Foundation; either version 2 of the License, or (at your option) any later |
// version. |
// This program is distributed in the hope that it will be useful, but |
// |
// WITHOUT ANY WARRANTY; |
// |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License along with |
// this program; if not, write to the Free Software Foundation, Inc., 51 |
// Franklin St, Fifth Floor, Boston, MA 02110, USA |
// |
// http://www.gnu.de/gpl-ger.html |
// |
//******************************************************************************************** |
#include "includes.h" |
// |
//#define F_CPU 8000000UL // 8 MHz |
|
//struct enc28j60_flag |
//{ |
// unsigned rx_buffer_is_free:1; |
// unsigned unuse:7; |
//}enc28j60_flag; |
static BYTE Enc28j60Bank; |
static WORD_BYTES next_packet_ptr; |
|
//******************************************************************************************* |
// |
// Function : icmp_send_request |
// Description : Send ARP request packet to destination. |
// |
//******************************************************************************************* |
BYTE enc28j60ReadOp(BYTE op, BYTE address) |
{ |
// activate CS |
CSACTIVE; |
// issue read command |
SPDR = op | (address & ADDR_MASK); |
waitspi(); |
// read data |
SPDR = 0x00; |
waitspi(); |
// do dummy read if needed (for mac and mii, see datasheet page 29) |
if(address & 0x80) |
{ |
SPDR = 0x00; |
waitspi(); |
} |
// release CS |
CSPASSIVE; |
return(SPDR); |
} |
//******************************************************************************************* |
// |
// Function : icmp_send_request |
// Description : Send ARP request packet to destination. |
// |
//******************************************************************************************* |
void enc28j60WriteOp(BYTE op, BYTE address, BYTE data) |
{ |
CSACTIVE; |
// issue write command |
SPDR = op | (address & ADDR_MASK); |
waitspi(); |
// write data |
SPDR = data; |
waitspi(); |
CSPASSIVE; |
} |
//******************************************************************************************* |
// |
// Function : icmp_send_request |
// Description : Send ARP request packet to destination. |
// |
//******************************************************************************************* |
void enc28j60SetBank(BYTE address) |
{ |
// set the bank (if needed) |
if((address & BANK_MASK) != Enc28j60Bank) |
{ |
// set the bank |
enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1|ECON1_BSEL0)); |
enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK)>>5); |
Enc28j60Bank = (address & BANK_MASK); |
} |
} |
//******************************************************************************************* |
// |
// Function : icmp_send_request |
// Description : Send ARP request packet to destination. |
// |
//******************************************************************************************* |
BYTE enc28j60Read(BYTE address) |
{ |
// select bank to read |
enc28j60SetBank(address); |
|
// do the read |
return enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address); |
} |
//******************************************************************************************* |
// |
// Function : icmp_send_request |
// Description : Send ARP request packet to destination. |
// |
//******************************************************************************************* |
void enc28j60Write(BYTE address, BYTE data) |
{ |
// select bank to write |
enc28j60SetBank(address); |
|
// do the write |
enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data); |
} |
//******************************************************************************************* |
// |
// Function : icmp_send_request |
// Description : Send ARP request packet to destination. |
// |
//******************************************************************************************* |
WORD enc28j60_read_phyreg(BYTE address) |
{ |
WORD data; |
|
// set the PHY register address |
enc28j60Write(MIREGADR, address); |
enc28j60Write(MICMD, MICMD_MIIRD); |
|
// Loop to wait until the PHY register has been read through the MII |
// This requires 10.24us |
while( (enc28j60Read(MISTAT) & MISTAT_BUSY) ); |
|
// Stop reading |
enc28j60Write(MICMD, MICMD_MIIRD); |
|
// Obtain results and return |
data = enc28j60Read ( MIRDL ); |
data |= enc28j60Read ( MIRDH ); |
|
return data; |
} |
//******************************************************************************************* |
// |
// Function : icmp_send_request |
// Description : Send ARP request packet to destination. |
// |
//******************************************************************************************* |
void enc28j60PhyWrite(BYTE address, WORD_BYTES data) |
{ |
// set the PHY register address |
enc28j60Write(MIREGADR, address); |
// write the PHY data |
enc28j60Write(MIWRL, data.byte.low); |
enc28j60Write(MIWRH, data.byte.high); |
// wait until the PHY write completes |
while(enc28j60Read(MISTAT) & MISTAT_BUSY) |
{ |
_delay_us(15); |
} |
} |
//******************************************************************************************* |
// |
// Function : icmp_send_request |
// Description : Send ARP request packet to destination. |
// |
//******************************************************************************************* |
/* |
void enc28j60_init( BYTE *avr_mac) |
{ |
// initialize I/O |
//DDRB |= _BV( DDB4 ); |
/apps/avr-webserver/avrnet.aps
0,0 → 1,602
<AVRStudio><MANAGEMENT><ProjectName>avrnet</ProjectName><Created>14-Dec-2006 13:47:01</Created><LastEdit>24-Jun-2007 13:47:20</LastEdit><ICON>241</ICON><ProjectType>0</ProjectType><Created>14-Dec-2006 13:47:01</Created><Version>4</Version><Build>4, 12, 0, 491</Build><ProjectTypeName>AVR GCC</ProjectTypeName></MANAGEMENT><CODE_CREATION><ObjectFile>default\avrnet.elf</ObjectFile><EntryFile></EntryFile><SaveFolder>D:\Work\AVR\avrnet-v1.0\</SaveFolder></CODE_CREATION><DEBUG_TARGET><CURRENT_TARGET>JTAG ICE</CURRENT_TARGET><CURRENT_PART>ATmega32</CURRENT_PART><BREAKPOINTS></BREAKPOINTS><IO_EXPAND><HIDE>false</HIDE></IO_EXPAND><REGISTERNAMES><Register>R00</Register><Register>R01</Register><Register>R02</Register><Register>R03</Register><Register>R04</Register><Register>R05</Register><Register>R06</Register><Register>R07</Register><Register>R08</Register><Register>R09</Register><Register>R10</Register><Register>R11</Register><Register>R12</Register><Register>R13</Register><Register>R14</Register><Register>R15</Register><Register>R16</Register><Register>R17</Register><Register>R18</Register><Register>R19</Register><Register>R20</Register><Register>R21</Register><Register>R22</Register><Register>R23</Register><Register>R24</Register><Register>R25</Register><Register>R26</Register><Register>R27</Register><Register>R28</Register><Register>R29</Register><Register>R30</Register><Register>R31</Register></REGISTERNAMES><COM>Auto</COM><COMType>1</COMType><WATCHNUM>0</WATCHNUM><WATCHNAMES><Pane0></Pane0><Pane1></Pane1><Pane2></Pane2><Pane3></Pane3></WATCHNAMES><BreakOnTrcaeFull>0</BreakOnTrcaeFull></DEBUG_TARGET><Debugger><modules><module></module></modules><Triggers></Triggers></Debugger><AVRGCCPLUGIN><FILES><SOURCEFILE>enc28j60.c</SOURCEFILE><SOURCEFILE>main.c</SOURCEFILE><SOURCEFILE>http.c</SOURCEFILE><SOURCEFILE>arp.c</SOURCEFILE><SOURCEFILE>tcp.c</SOURCEFILE><SOURCEFILE>ip.c</SOURCEFILE><SOURCEFILE>ethernet.c</SOURCEFILE><SOURCEFILE>icmp.c</SOURCEFILE><SOURCEFILE>menu.c</SOURCEFILE><SOURCEFILE>lcd.c</SOURCEFILE><SOURCEFILE>adc.c</SOURCEFILE><SOURCEFILE>udp.c</SOURCEFILE><HEADERFILE>enc28j60.h</HEADERFILE><HEADERFILE>http.h</HEADERFILE><HEADERFILE>arp.h</HEADERFILE><HEADERFILE>tcp.h</HEADERFILE><HEADERFILE>ip.h</HEADERFILE><HEADERFILE>ethernet.h</HEADERFILE><HEADERFILE>icmp.h</HEADERFILE><HEADERFILE>menu.h</HEADERFILE><HEADERFILE>lcd.h</HEADERFILE><HEADERFILE>adc.h</HEADERFILE><HEADERFILE>includes.h</HEADERFILE><HEADERFILE>struct.h</HEADERFILE><HEADERFILE>udp.h</HEADERFILE><OTHERFILE>default\avrnet.lss</OTHERFILE><OTHERFILE>default\avrnet.map</OTHERFILE></FILES><CONFIGS><CONFIG><NAME>default</NAME><USESEXTERNALMAKEFILE>NO</USESEXTERNALMAKEFILE><EXTERNALMAKEFILE></EXTERNALMAKEFILE><PART>atmega32</PART><HEX>1</HEX><LIST>1</LIST><MAP>1</MAP><OUTPUTFILENAME>avrnet.elf</OUTPUTFILENAME><OUTPUTDIR>default\</OUTPUTDIR><ISDIRTY>1</ISDIRTY><OPTIONS><OPTION><FILE>adc.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>arp.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>enc28j60.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>ethernet.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>http.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>icmp.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>ip.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>lcd.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>main.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>menu.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>tcp.c</FILE><OPTIONLIST></OPTIONLIST></OPTION></OPTIONS><INCDIRS/><LIBDIRS/><LIBS/><LINKOBJECTS/><OPTIONSFORALL>-Wall -gdwarf-2 -DF_CPU=16000000UL -Os -fsigned-char</OPTIONSFORALL><LINKEROPTIONS></LINKEROPTIONS><SEGMENTS/></CONFIG></CONFIGS><LASTCONFIG>default</LASTCONFIG><USES_WINAVR>1</USES_WINAVR><GCC_LOC>C:\WinAVR-20070525\bin\avr-gcc.exe</GCC_LOC><MAKE_LOC>C:\WinAVR-20070525\utils\bin\make.exe</MAKE_LOC></AVRGCCPLUGIN><AVRSimulator><FuseExt>0</FuseExt><FuseHigh>214</FuseHigh><FuseLow>224</FuseLow><LockBits>131</LockBits><Frequency>4000000</Frequency><ExtSRAM>0</ExtSRAM><SimBoot>1</SimBoot><SimBootnew>1</SimBootnew></AVRSimulator><JTAG_ICE><BAUDRATE>19200</BAUDRATE><OCD_FREQUENCY>50000</OCD_FREQUENCY><PRESERVE_EEPROM>0</PRESERVE_EEPROM><RUN_TIMERS>0</RUN_TIMERS><REPROGRAM>0</REPROGRAM><EXT_RESET>0</EXT_RESET><RESTORE>1</RESTORE><DAISY_CHAIN>0</DAISY_CHAIN><DEVS_BEFORE>0</DEVS_BEFORE><DEVS_AFTER>0</DEVS_AFTER><INSTRBITS_BEFORE>0</INSTRBITS_BEFORE><INSTRBITS_AFTER>0</INSTRBITS_AFTER><NOJTAGIN_RUNMODE>0</NOJTAGIN_RUNMODE><BREAKON_CHANGEOFFLOW>0</BREAKON_CHANGEOFFLOW><ALLOW_BREAKINSTR>0</ALLOW_BREAKINSTR><PRINT_BREAKCAUSE>1</PRINT_BREAKCAUSE><ENTRY_FUNCTION>main</ENTRY_FUNCTION><STOPIF_ENTRYFUNC_NOTFOUND>1</STOPIF_ENTRYFUNC_NOTFOUND><PRINT_BREAKWARNING>1</PRINT_BREAKWARNING><CURRENT_BUILDTIME>-654736</CURRENT_BUILDTIME></JTAG_ICE><ProjectFiles><Files><Name>D:\Work\AVR\avrnet-v1.0\enc28j60.h</Name><Name>D:\Work\AVR\avrnet-v1.0\http.h</Name><Name>D:\Work\AVR\avrnet-v1.0\arp.h</Name><Name>D:\Work\AVR\avrnet-v1.0\tcp.h</Name><Name>D:\Work\AVR\avrnet-v1.0\ip.h</Name><Name>D:\Work\AVR\avrnet-v1.0\ethernet.h</Name><Name>D:\Work\AVR\avrnet-v1.0\icmp.h</Name><Name>D:\Work\AVR\avrnet-v1.0\menu.h</Name><Name>D:\Work\AVR\avrnet-v1.0\lcd.h</Name><Name>D:\Work\AVR\avrnet-v1.0\adc.h</Name><Name>D:\Work\AVR\avrnet-v1.0\includes.h</Name><Name>D:\Work\AVR\avrnet-v1.0\struct.h</Name><Name>D:\Work\AVR\avrnet-v1.0\udp.h</Name><Name>D:\Work\AVR\avrnet-v1.0\enc28j60.c</Name><Name>D:\Work\AVR\avrnet-v1.0\main.c</Name><Name>D:\Work\AVR\avrnet-v1.0\http.c</Name><Name>D:\Work\AVR\avrnet-v1.0\arp.c</Name><Name>D:\Work\AVR\avrnet-v1.0\tcp.c</Name><Name>D:\Work\AVR\avrnet-v1.0\ip.c</Name><Name>D:\Work\AVR\avrnet-v1.0\ethernet.c</Name><Name>D:\Work\AVR\avrnet-v1.0\icmp.c</Name><Name>D:\Work\AVR\avrnet-v1.0\menu.c</Name><Name>D:\Work\AVR\avrnet-v1.0\lcd.c</Name><Name>D:\Work\AVR\avrnet-v1.0\adc.c</Name><Name>D:\Work\AVR\avrnet-v1.0\udp.c</Name></Files></ProjectFiles><IOView><usergroups/></IOView><Files><File00000><FileId>00000</FileId><FileName>enc28j60.c</FileName><Status>259</Status></File00000><File00001><FileId>00001</FileId><FileName>http.c</FileName><Status>259</Status></File00001><File00002><FileId>00002</FileId><FileName>tcp.c</FileName><Status>259</Status></File00002><File00003><FileId>00003</FileId><FileName>menu.c</FileName><Status>259</Status></File00003><File00004><FileId>00004</FileId><FileName>lcd.c</FileName><Status>259</Status></File00004><File00005><FileId>00005</FileId><FileName>main.c</FileName><Status>259</Status></File00005><File00006><FileId>00006</FileId><FileName>arp.c</FileName><Status>257</Status></File00006><File00007><FileId>00007</FileId><FileName>includes.h</FileName><Status>257</Status></File00007><File00008><FileId>00008</FileId><FileName>adc.c</FileName><Status>259</Status></File00008><File00009><FileId>00009</FileId><FileName>ethernet.c</FileName><Status>257</Status></File00009><File00010><FileId>00010</FileId><FileName>icmp.c</FileName><Status>257</Status></File00010><File00011><FileId>00011</FileId><FileName>ip.c</FileName><Status>257</Status></File00011><File00012><FileId>00012</FileId><FileName>ip.h</FileName><Status>1</Status></File00012><File00013><FileId>00013</FileId><FileName>enc28j60.h</FileName><Status>1</Status></File00013><File00014><FileId>00014</FileId><FileName>ethernet.h</FileName><Status>1</Status></File00014><File00015><FileId>00015</FileId><FileName>arp.h</FileName><Status>1</Status></File00015><File00016><FileId>00016</FileId><FileName>menu.h</FileName><Status>257</Status></File00016><File00017><FileId>00017</FileId><FileName>adc.h</FileName><Status>1</Status></File00017><File00018><FileId>00018</FileId><FileName>icmp.h</FileName><Status>1</Status></File00018><File00019><FileId>00019</FileId><FileName>http.h</FileName><Status>1</Status></File00019><File00020><FileId>00020</FileId><FileName>lcd.h</FileName><Status>1</Status></File00020><File00021><FileId>00021</FileId><FileName>struct.h</FileName><Status>257</Status></File00021><File00022><FileId>00022</FileId><FileName>tcp.h</FileName><Status>1</Status></File00022><File00023><FileId>00023</FileId><FileName>udp.c</FileName><Status>257</Status></File00023><File00024><FileId>00024</FileId><FileName>udp.h</FileName><Status>1</Status></File00024></Files><Workspace><File00000><Position>198 91 1053 577</Position><LineCol>0 0</LineCol></File00000><File00001><Position>186 64 1041 550</Position><LineCol>0 0</LineCol></File00001><File00002><Position>123 22 978 508</Position><LineCol>0 0</LineCol></File00002><File00003><Position>159 46 1014 532</Position><LineCol>0 0</LineCol></File00003><File00004><Position>38 -73 725 256</Position><LineCol>0 0</LineCol></File00004><File00005><Position>195 70 1022 532</Position><LineCol>288 0</LineCol></File00005><File00006><Position>117 18 972 504</Position><LineCol>0 0</LineCol></File00006><File00007><Position>43 -90 870 396</Position><LineCol>0 0</LineCol></File00007><File00008><Position>120 20 975 506</Position><LineCol>0 0</LineCol></File00008><File00009><Position>60 -51 747 278</Position><LineCol>0 0</LineCol></File00009><File00010><Position>103 -10 958 476</Position><LineCol>52 2</LineCol></File00010><File00011><Position>88 -60 915 426</Position><LineCol>0 0</LineCol></File00011><File00012><Position>103 -50 958 436</Position><LineCol>0 0</LineCol></File00012><File00013><Position>52 -84 879 402</Position><LineCol>0 0</LineCol></File00013><File00014><Position>59 -59 746 268</Position><LineCol>0 0</LineCol></File00014><File00015><Position>84 -35 771 292</Position><LineCol>0 0</LineCol></File00015><File00016><Position>171 54 1026 540</Position><LineCol>0 0</LineCol></File00016><File00017><Position>55 -26 910 462</Position><LineCol>0 0</LineCol></File00017><File00018><Position>180 51 867 378</Position><LineCol>0 0</LineCol></File00018><File00019><Position>117 -13 804 314</Position><LineCol>0 0</LineCol></File00019><File00020><Position>162 48 1017 536</Position><LineCol>0 0</LineCol></File00020><File00021><Position>169 73 884 400</Position><LineCol>0 0</LineCol></File00021><File00022><Position>180 60 1035 546</Position><LineCol>0 0</LineCol></File00022><File00023><Position>170 72 1025 558</Position><LineCol>34 2</LineCol><State>Maximized</State></File00023><File00024><Position>183 62 1038 548</Position><LineCol>23 33</LineCol></File00024></Workspace><Events><Bookmarks></Bookmarks></Events><Trace><Filters></Filters></Trace></AVRStudio> |
/apps/avr-webserver/enc28j60.h
0,0 → 1,297
//******************************************************************************************** |
// |
// File : enc28j60.h Microchip ENC28J60 Ethernet Interface Driver |
// |
//******************************************************************************************** |
// |
// Copyright (C) 2007 |
// |
// This program is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free Software |
// Foundation; either version 2 of the License, or (at your option) any later |
// version. |
// This program is distributed in the hope that it will be useful, but |
// |
// WITHOUT ANY WARRANTY; |
// |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License along with |
// this program; if not, write to the Free Software Foundation, Inc., 51 |
// Franklin St, Fifth Floor, Boston, MA 02110, USA |
// |
// http://www.gnu.de/gpl-ger.html |
// |
//******************************************************************************************** |
|
//#ifndef ENC28J60_H |
#define ENC28J60_H |
|
// ENC28J60 Control Registers |
// Control register definitions are a combination of address, |
// bank number, and Ethernet/MAC/PHY indicator bits. |
// - Register address (bits 0-4) |
// - Bank number (bits 5-6) |
// - MAC/PHY indicator (bit 7) |
#define ADDR_MASK 0x1F |
#define BANK_MASK 0x60 |
#define SPRD_MASK 0x80 |
// All-bank registers |
#define EIE 0x1B |
#define EIR 0x1C |
#define ESTAT 0x1D |
#define ECON2 0x1E |
#define ECON1 0x1F |
// Bank 0 registers |
#define ERDPTL (0x00|0x00) |
#define ERDPTH (0x01|0x00) |
#define EWRPTL (0x02|0x00) |
#define EWRPTH (0x03|0x00) |
#define ETXSTL (0x04|0x00) |
#define ETXSTH (0x05|0x00) |
#define ETXNDL (0x06|0x00) |
#define ETXNDH (0x07|0x00) |
#define ERXSTL (0x08|0x00) |
#define ERXSTH (0x09|0x00) |
#define ERXNDL (0x0A|0x00) |
#define ERXNDH (0x0B|0x00) |
#define ERXRDPTL (0x0C|0x00) |
#define ERXRDPTH (0x0D|0x00) |
#define ERXWRPTL (0x0E|0x00) |
#define ERXWRPTH (0x0F|0x00) |
#define EDMASTL (0x10|0x00) |
#define EDMASTH (0x11|0x00) |
#define EDMANDL (0x12|0x00) |
#define EDMANDH (0x13|0x00) |
#define EDMADSTL (0x14|0x00) |
#define EDMADSTH (0x15|0x00) |
#define EDMACSL (0x16|0x00) |
#define EDMACSH (0x17|0x00) |
// Bank 1 registers |
#define EHT0 (0x00|0x20) |
#define EHT1 (0x01|0x20) |
#define EHT2 (0x02|0x20) |
#define EHT3 (0x03|0x20) |
#define EHT4 (0x04|0x20) |
#define EHT5 (0x05|0x20) |
#define EHT6 (0x06|0x20) |
#define EHT7 (0x07|0x20) |
#define EPMM0 (0x08|0x20) |
#define EPMM1 (0x09|0x20) |
#define EPMM2 (0x0A|0x20) |
#define EPMM3 (0x0B|0x20) |
#define EPMM4 (0x0C|0x20) |
#define EPMM5 (0x0D|0x20) |
#define EPMM6 (0x0E|0x20) |
#define EPMM7 (0x0F|0x20) |
#define EPMCSL (0x10|0x20) |
#define EPMCSH (0x11|0x20) |
#define EPMOL (0x14|0x20) |
#define EPMOH (0x15|0x20) |
#define EWOLIE (0x16|0x20) |
#define EWOLIR (0x17|0x20) |
#define ERXFCON (0x18|0x20) |
#define EPKTCNT (0x19|0x20) |
// Bank 2 registers |
#define MACON1 (0x00|0x40|0x80) |
#define MACON2 (0x01|0x40|0x80) |
#define MACON3 (0x02|0x40|0x80) |
#define MACON4 (0x03|0x40|0x80) |
#define MABBIPG (0x04|0x40|0x80) |
#define MAIPGL (0x06|0x40|0x80) |
#define MAIPGH (0x07|0x40|0x80) |
#define MACLCON1 (0x08|0x40|0x80) |
#define MACLCON2 (0x09|0x40|0x80) |
#define MAMXFLL (0x0A|0x40|0x80) |
#define MAMXFLH (0x0B|0x40|0x80) |
#define MAPHSUP (0x0D|0x40|0x80) |
#define MICON (0x11|0x40|0x80) |
#define MICMD (0x12|0x40|0x80) |
#define MIREGADR (0x14|0x40|0x80) |
#define MIWRL (0x16|0x40|0x80) |
#define MIWRH (0x17|0x40|0x80) |
#define MIRDL (0x18|0x40|0x80) |
#define MIRDH (0x19|0x40|0x80) |
// Bank 3 registers |
#define MAADR1 (0x00|0x60|0x80) |
#define MAADR0 (0x01|0x60|0x80) |
#define MAADR3 (0x02|0x60|0x80) |
#define MAADR2 (0x03|0x60|0x80) |
#define MAADR5 (0x04|0x60|0x80) |
#define MAADR4 (0x05|0x60|0x80) |
#define EBSTSD (0x06|0x60) |
#define EBSTCON (0x07|0x60) |
#define EBSTCSL (0x08|0x60) |
#define EBSTCSH (0x09|0x60) |
#define MISTAT (0x0A|0x60|0x80) |
#define EREVID (0x12|0x60) |
#define ECOCON (0x15|0x60) |
#define EFLOCON (0x17|0x60) |
#define EPAUSL (0x18|0x60) |
#define EPAUSH (0x19|0x60) |
// PHY registers |
#define PHCON1 0x00 |
#define PHSTAT1 0x01 |
#define PHHID1 0x02 |
#define PHHID2 0x03 |
#define PHCON2 0x10 |
#define PHSTAT2 0x11 |
#define PHIE 0x12 |
#define PHIR 0x13 |
#define PHLCON 0x14 |
|
// ENC28J60 ERXFCON Register Bit Definitions |
#define ERXFCON_UCEN 0x80 |
#define ERXFCON_ANDOR 0x40 |
#define ERXFCON_CRCEN 0x20 |
#define ERXFCON_PMEN 0x10 |
#define ERXFCON_MPEN 0x08 |
#define ERXFCON_HTEN 0x04 |
#define ERXFCON_MCEN 0x02 |
#define ERXFCON_BCEN 0x01 |
// ENC28J60 EIE Register Bit Definitions |
#define EIE_INTIE 0x80 |
#define EIE_PKTIE 0x40 |
#define EIE_DMAIE 0x20 |
#define EIE_LINKIE 0x10 |
#define EIE_TXIE 0x08 |
#define EIE_WOLIE 0x04 |
#define EIE_TXERIE 0x02 |
#define EIE_RXERIE 0x01 |
// ENC28J60 EIR Register Bit Definitions |
#define EIR_PKTIF 0x40 |
#define EIR_DMAIF 0x20 |
#define EIR_LINKIF 0x10 |
#define EIR_TXIF 0x08 |
#define EIR_WOLIF 0x04 |
#define EIR_TXERIF 0x02 |
#define EIR_RXERIF 0x01 |
// ENC28J60 ESTAT Register Bit Definitions |
#define ESTAT_INT 0x80 |
#define ESTAT_LATECOL 0x10 |
#define ESTAT_RXBUSY 0x04 |
#define ESTAT_TXABRT 0x02 |
#define ESTAT_CLKRDY 0x01 |
// ENC28J60 ECON2 Register Bit Definitions |
#define ECON2_AUTOINC 0x80 |
#define ECON2_PKTDEC 0x40 |
#define ECON2_PWRSV 0x20 |
#define ECON2_VRPS 0x08 |
// ENC28J60 ECON1 Register Bit Definitions |
#define ECON1_TXRST 0x80 |
#define ECON1_RXRST 0x40 |
#define ECON1_DMAST 0x20 |
#define ECON1_CSUMEN 0x10 |
#define ECON1_TXRTS 0x08 |
#define ECON1_RXEN 0x04 |
#define ECON1_BSEL1 0x02 |
#define ECON1_BSEL0 0x01 |
// ENC28J60 MACON1 Register Bit Definitions |
#define MACON1_LOOPBK 0x10 |
#define MACON1_TXPAUS 0x08 |
#define MACON1_RXPAUS 0x04 |
#define MACON1_PASSALL 0x02 |
#define MACON1_MARXEN 0x01 |
// ENC28J60 MACON2 Register Bit Definitions |
#define MACON2_MARST 0x80 |
#define MACON2_RNDRST 0x40 |
#define MACON2_MARXRST 0x08 |
#define MACON2_RFUNRST 0x04 |
#define MACON2_MATXRST 0x02 |
#define MACON2_TFUNRST 0x01 |
// ENC28J60 MACON3 Register Bit Definitions |
#define MACON3_PADCFG2 0x80 |
#define MACON3_PADCFG1 0x40 |
#define MACON3_PADCFG0 0x20 |
#define MACON3_TXCRCEN 0x10 |
#define MACON3_PHDRLEN 0x08 |
#define MACON3_HFRMLEN 0x04 |
#define MACON3_FRMLNEN 0x02 |
#define MACON3_FULDPX 0x01 |
// ENC28J60 MACON4 Register Bit Definitions |
#define MACON4_DEFER (1<<6) |
#define MACON4_BPEN (1<<5) |
#define MACON4_NOBKOFF (1<<4) |
// ENC28J60 MICMD Register Bit Definitions |
#define MICMD_MIISCAN 0x02 |
#define MICMD_MIIRD 0x01 |
// ENC28J60 MISTAT Register Bit Definitions |
#define MISTAT_NVALID 0x04 |
#define MISTAT_SCAN 0x02 |
#define MISTAT_BUSY 0x01 |
// ENC28J60 PHY PHCON1 Register Bit Definitions |
#define PHCON1_PRST 0x8000 |
#define PHCON1_PLOOPBK 0x4000 |
#define PHCON1_PPWRSV 0x0800 |
#define PHCON1_PDPXMD 0x0100 |
// ENC28J60 PHY PHSTAT1 Register Bit Definitions |
#define PHSTAT1_PFDPX 0x1000 |
#define PHSTAT1_PHDPX 0x0800 |
#define PHSTAT1_LLSTAT 0x0004 |
#define PHSTAT1_JBSTAT 0x0002 |
// ENC28J60 PHY PHCON2 Register Bit Definitions |
#define PHCON2_FRCLINK 0x4000 |
#define PHCON2_TXDIS 0x2000 |
#define PHCON2_JABBER 0x0400 |
#define PHCON2_HDLDIS 0x0100 |
|
// ENC28J60 Packet Control Byte Bit Definitions |
#define PKTCTRL_PHUGEEN 0x08 |
#define PKTCTRL_PPADEN 0x04 |
#define PKTCTRL_PCRCEN 0x02 |
#define PKTCTRL_POVERRIDE 0x01 |
|
// SPI operation codes |
#define ENC28J60_READ_CTRL_REG 0x00 |
#define ENC28J60_READ_BUF_MEM 0x3A |
#define ENC28J60_WRITE_CTRL_REG 0x40 |
#define ENC28J60_WRITE_BUF_MEM 0x7A |
#define ENC28J60_BIT_FIELD_SET 0x80 |
#define ENC28J60_BIT_FIELD_CLR 0xA0 |
#define ENC28J60_SOFT_RESET 0xFF |
|
// set CS to 0 = active |
#define CSACTIVE PORTB &= ~_BV(PB4) |
// set CS to 1 = passive |
#define CSPASSIVE PORTB |= _BV(PB4) |
// |
#define waitspi() while(!(SPSR&(1<<SPIF))) |
|
// The RXSTART_INIT should be zero. See Rev. B4 Silicon Errata |
// buffer boundaries applied to internal 8K ram |
// the entire available packet buffer space is allocated |
// |
#define MAX_TX_BUFFER 1500 |
#define MAX_RX_BUFFER 1500 |
// start with recbuf at 0/ |
#define RXSTART_INIT 0x0000 |
#define RXSTOP_INIT (8192-1500-1) |
#define TXSTART_INIT (8192-1500) |
#define TXSTOP_INIT 8192 |
// |
// max frame length which the conroller will accept: |
#define MAX_FRAMELEN (1500+sizeof(ETH_HEADER)+4) // maximum ethernet frame length |
|
#define ENC28J60_RESET_PIN_DDR DDD3 |
#define ENC28J60_INT_PIN_DDR DDD2 |
#define ENC28J60_RESET_PIN PD3 |
#define ENC28J60_INT_PIN PD2 |
#define ENC28J60_PORT PORTD |
#define ENC28J60_DDR DDRD |
|
// functions |
extern BYTE enc28j60ReadOp(BYTE op, BYTE address); |
extern void enc28j60WriteOp(BYTE op, BYTE address, BYTE data); |
extern void enc28j60SetBank(BYTE address); |
extern BYTE enc28j60Read(BYTE address); |
extern void enc28j60Write(BYTE address, BYTE data); |
extern WORD enc28j60_read_phyreg(BYTE address); |
extern void enc28j60PhyWrite(BYTE address, WORD_BYTES data); |
extern void enc28j60_init( BYTE *avr_mac); |
extern BYTE enc28j60getrev(void); |
extern void enc28j60_packet_send ( BYTE *buffer, WORD length ); |
extern BYTE enc28j60_mac_is_linked(void); |
extern WORD enc28j60_tx_checksum( WORD offset, WORD len ); |
extern WORD enc28j60_packet_receive ( BYTE *rxtx_buffer, WORD max_length ); |
|
/apps/avr-webserver/ip.c
0,0 → 1,130
//******************************************************************************************** |
// |
// File : ip.c implement for Internet Protocol |
// |
//******************************************************************************************** |
// |
// Copyright (C) 2007 |
// |
// This program is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free Software |
// Foundation; either version 2 of the License, or (at your option) any later |
// version. |
// This program is distributed in the hope that it will be useful, but |
// |
// WITHOUT ANY WARRANTY; |
// |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License along with |
// this program; if not, write to the Free Software Foundation, Inc., 51 |
// Franklin St, Fifth Floor, Boston, MA 02110, USA |
// |
// http://www.gnu.de/gpl-ger.html |
// |
//******************************************************************************************** |
#include "includes.h" |
//******************************************************************************************** |
// |
// +------------+-----------+----------+ |
// + MAC header + IP header + Data ::: + |
// +------------+-----------+----------+ |
// |
// IP Header |
// |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// +00+01+02+03+04+05+06+07+08+09+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+ |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// + Version + IHL + TOS + Total length + |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// + Identification + Flags + Fragment offset + |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// + TTL + Protocol + Header checksum + |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// + Source IP address + |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// + Destination IP address + |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// + Options and padding ::: + |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// |
//******************************************************************************************** |
static WORD_BYTES ip_identfier=(WORD_BYTES){1}; |
//******************************************************************************************** |
// |
// Function : ip_generate_packet |
// Description : generate all ip header |
// |
//******************************************************************************************** |
void ip_generate_header ( BYTE *rxtx_buffer, WORD_BYTES total_length, BYTE protocol, BYTE *dest_ip ) |
{ |
BYTE i; |
WORD_BYTES ck; |
|
// set ipv4 and header length |
rxtx_buffer[ IP_P ] = IP_V4_V | IP_HEADER_LENGTH_V; |
|
// set TOS to default 0x00 |
rxtx_buffer[ IP_TOS_P ] = 0x00; |
|
// set total length |
rxtx_buffer [ IP_TOTLEN_H_P ] = total_length.byte.high; |
rxtx_buffer [ IP_TOTLEN_L_P ] = total_length.byte.low; |
|
// set packet identification |
rxtx_buffer [ IP_ID_H_P ] = ip_identfier.byte.high; |
rxtx_buffer [ IP_ID_L_P ] = ip_identfier.byte.low; |
ip_identfier.word++; |
|
// set fragment flags |
rxtx_buffer [ IP_FLAGS_H_P ] = 0x00; |
rxtx_buffer [ IP_FLAGS_L_P ] = 0x00; |
|
// set Time To Live |
rxtx_buffer [ IP_TTL_P ] = 128; |
|
// set ip packettype to tcp/udp/icmp... |
rxtx_buffer [ IP_PROTO_P ] = protocol; |
|
// set source and destination ip address |
for ( i=0; i<4; i++ ) |
{ |
rxtx_buffer[ IP_DST_IP_P + i ] = dest_ip[i]; |
rxtx_buffer[ IP_SRC_IP_P + i ] = avr_ip.byte[ i ]; |
} |
|
// clear the 2 byte checksum |
rxtx_buffer[ IP_CHECKSUM_H_P ] = 0; |
rxtx_buffer[ IP_CHECKSUM_L_P ] = 0; |
|
// fill checksum value |
// calculate the checksum: |
ck.word = software_checksum ( &rxtx_buffer[ IP_P ], sizeof(IP_HEADER), 0 ); |
rxtx_buffer[ IP_CHECKSUM_H_P ] = ck.byte.high; |
rxtx_buffer[ IP_CHECKSUM_L_P ] = ck.byte.low; |
} |
//******************************************************************************************** |
// |
// Function : ip_check_ip |
// Description : Check incoming packet |
// |
//******************************************************************************************** |
BYTE ip_packet_is_ip ( BYTE *rxtx_buffer ) |
{ |
unsigned char i; |
|
// if ethernet type is not ip |
if ( rxtx_buffer[ ETH_TYPE_H_P ] != ETH_TYPE_IP_H_V || rxtx_buffer[ ETH_TYPE_L_P ] != ETH_TYPE_IP_L_V) |
return 0; |
|
// if ip packet not send to avr |
for ( i=0; i<sizeof(IP_ADDR); i++ ) |
{ |
if ( rxtx_buffer[ IP_DST_IP_P + i ] != avr_ip.byte[i] ) |
return 0; |
} |
|
// destination ip address match with avr ip address |
return 1; |
} |
/apps/avr-webserver/ip.h
0,0 → 1,61
//******************************************************************************************** |
// |
// File : ip.h implement for Internet Protocol |
// |
//******************************************************************************************** |
// |
// Copyright (C) 2007 |
// |
// This program is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free Software |
// Foundation; either version 2 of the License, or (at your option) any later |
// version. |
// This program is distributed in the hope that it will be useful, but |
// |
// WITHOUT ANY WARRANTY; |
// |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License along with |
// this program; if not, write to the Free Software Foundation, Inc., 51 |
// Franklin St, Fifth Floor, Boston, MA 02110, USA |
// |
// http://www.gnu.de/gpl-ger.html |
// |
//******************************************************************************************** |
#define IP_HEADER_LEN 20 |
|
#define IP_PROTO_ICMP_V 0x01 |
#define IP_PROTO_TCP_V 0x06 |
#define IP_PROTO_UDP_V 0x11 |
#define IP_V4_V 0x40 |
#define IP_HEADER_LENGTH_V 0x05 |
|
#define IP_P 0x0E |
#define IP_HEADER_VER_LEN_P 0x0E |
#define IP_TOS_P 0x0F |
#define IP_TOTLEN_H_P 0x10 |
#define IP_TOTLEN_L_P 0x11 |
#define IP_ID_H_P 0x12 |
#define IP_ID_L_P 0x13 |
#define IP_FLAGS_H_P 0x14 |
#define IP_FLAGS_L_P 0x15 |
#define IP_TTL_P 0x16 |
#define IP_PROTO_P 0x17 |
#define IP_CHECKSUM_H_P 0x18 |
#define IP_CHECKSUM_L_P 0x19 |
#define IP_SRC_IP_P 0x1A |
#define IP_DST_IP_P 0x1E |
|
|
//******************************************************************************************** |
// |
// Prototype function |
// |
//******************************************************************************************** |
//void ip_fill_ip_address( unsigned char *buf, unsigned char *avr_ip, unsigned char *dest_ip ); |
//void ip_fill_hdr_checksum( unsigned char *buf ); |
|
extern BYTE ip_packet_is_ip ( BYTE *rxtx_buffer ); |
extern void ip_generate_header ( BYTE *rxtx_buffer, WORD_BYTES total_length, BYTE protocol, BYTE *dest_ip ); |
/apps/avr-webserver/http.c
0,0 → 1,499
//******************************************************************************************** |
// |
// File : http.c implement for Hyper Text transfer Protocol |
// |
//******************************************************************************************** |
// |
// Copyright (C) 2007 |
// |
// This program is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free Software |
// Foundation; either version 2 of the License, or (at your option) any later |
// version. |
// This program is distributed in the hope that it will be useful, but |
// |
// WITHOUT ANY WARRANTY; |
// |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License along with |
// this program; if not, write to the Free Software Foundation, Inc., 51 |
// Franklin St, Fifth Floor, Boston, MA 02110, USA |
// |
// http://www.gnu.de/gpl-ger.html |
// |
//******************************************************************************************** |
#include "includes.h" |
//******************************************************************************************** |
// |
// Global variable for http.c |
// |
//******************************************************************************************** |
prog_int8_t web_title[] = "AVRnet V0.9 by AVRportal.com"; |
prog_int8_t tag_br[] = "<br>"; |
prog_int8_t tag_hr[] = "<hr width=\"100%\" size=\"1\"><br>"; |
prog_int8_t tag_form[] = "<form action=\"./?\" method=\"get\">"; |
//******************************************************************************************** |
// |
// Function : http_webserver_process |
// Description : Initial connection to web server |
// |
//******************************************************************************************** |
void http_webserver_process ( BYTE *rxtx_buffer, BYTE *dest_mac, BYTE *dest_ip ) |
{ |
WORD dlength, dest_port; |
BYTE count_time_temp[3]; |
BYTE generic_buf[64]; |
|
dest_port = (rxtx_buffer[TCP_SRC_PORT_H_P]<<8)|rxtx_buffer[TCP_SRC_PORT_L_P]; |
// tcp port 80 start for web server |
if ( rxtx_buffer [ IP_PROTO_P ] == IP_PROTO_TCP_V && rxtx_buffer[ TCP_DST_PORT_H_P ] == 0 && rxtx_buffer[ TCP_DST_PORT_L_P ] == 80 ) |
{ |
// received packet with flags "SYN", let's send "SYNACK" |
if ( (rxtx_buffer[ TCP_FLAGS_P ] & TCP_FLAG_SYN_V) ) |
{ |
// tcp_send_synack ( rxtx_buffer, dest_mac, dest_ip ); |
tcp_send_packet ( |
rxtx_buffer, |
(WORD_BYTES){dest_port}, |
(WORD_BYTES){80}, // source port |
TCP_FLAG_SYN_V|TCP_FLAG_ACK_V, // flag |
1, // (bool)maximum segment size |
0, // (bool)clear sequence ack number |
1, // (bool)calculate new seq and seqack number |
0, // tcp data length |
dest_mac, // server mac address |
dest_ip ); // server ip address |
flag1.bits.syn_is_received = 1; |
return; |
} |
|
if ( (rxtx_buffer [ TCP_FLAGS_P ] & TCP_FLAG_ACK_V) ) |
{ |
// get tcp data length |
dlength = tcp_get_dlength( rxtx_buffer ); |
if ( dlength == 0 ) |
{ |
// finack, answer with ack |
if ( (rxtx_buffer[TCP_FLAGS_P] & TCP_FLAG_FIN_V) ) |
{ |
// tcp_send_ack ( rxtx_buffer, dest_mac, dest_ip ); |
tcp_send_packet ( |
rxtx_buffer, |
(WORD_BYTES){dest_port}, |
(WORD_BYTES){80}, // source port |
TCP_FLAG_ACK_V, // flag |
0, // (bool)maximum segment size |
0, // (bool)clear sequence ack number |
1, // (bool)calculate new seq and seqack number |
0, // tcp data length |
dest_mac, // server mac address |
dest_ip ); // server ip address |
} |
return; |
} |
// get avr ip address from request and set to new avr ip address |
if ( http_get_variable ( rxtx_buffer, dlength, PSTR( "aip" ), generic_buf ) ) |
{ |
if ( http_get_ip ( generic_buf, (BYTE*)&avr_ip ) == 4 ) |
eeprom_write_block ( &avr_ip, ee_avr_ip, 4 ); |
eeprom_read_block ( &avr_ip, ee_avr_ip, 4 ); |
} |
// get server ip address from request and set to new server ip address |
if ( http_get_variable ( rxtx_buffer, dlength, PSTR( "sip" ), generic_buf ) ) |
{ |
if ( http_get_ip ( generic_buf, (BYTE*)&server_ip ) == 4 ) |
eeprom_write_block ( &server_ip, ee_server_ip, 4 ); |
eeprom_read_block ( &server_ip, ee_server_ip, 4 ); |
} |
// get LED1 on/of command |
if ( http_get_variable ( rxtx_buffer, dlength, PSTR( "l1" ), generic_buf ) ) |
{ |
if ( generic_buf[0] == '0' ) |
LED_PORT |= _BV ( LED_PIN1 ); |
else |
LED_PORT &= ~_BV ( LED_PIN1 ); |
} |
// get LED1 on/of command |
if ( http_get_variable ( rxtx_buffer, dlength, PSTR( "l2" ), generic_buf ) ) |
{ |
if ( generic_buf[0] == '0' ) |
LED_PORT |= _BV ( LED_PIN2 ); |
else |
LED_PORT &= ~_BV ( LED_PIN2 ); |
} |
// get LCD string and show on first line |
if ( http_get_variable ( rxtx_buffer, dlength, PSTR( "lcd1" ), generic_buf ) ) |
{ |
urldecode ( generic_buf ); |
lcd_putc ( '\f' ); |
lcd_print ( generic_buf ); |
flag1.bits.lcd_busy = 1; |
} |
// get LCD string and show on second line |
if ( http_get_variable ( rxtx_buffer, dlength, PSTR( "lcd2" ), generic_buf ) ) |
{ |
urldecode ( generic_buf ); |
lcd_putc ( '\n' ); |
lcd_print ( generic_buf ); |
flag1.bits.lcd_busy = 1; |
} |
// get send temparature to server configuration |
if ( http_get_variable ( rxtx_buffer, dlength, PSTR( "tc" ), generic_buf ) ) |
{ |
// enable or disable send temparature |
if ( http_get_variable ( rxtx_buffer, dlength, PSTR( "en" ), generic_buf ) ) |
count_time_temp[0] = 1; |
else |
count_time_temp[0] = 0; |
// get hour |
if ( http_get_variable ( rxtx_buffer, dlength, PSTR( "h" ), generic_buf ) ) |
{ |
count_time_temp[1] = (generic_buf[0] - '0') * 10; |
count_time_temp[1] = count_time_temp[1] + (generic_buf[1] - '0'); |
} |
// get minute |
if ( http_get_variable ( rxtx_buffer, dlength, PSTR( "m" ), generic_buf ) ) |
{ |
count_time_temp[2] = (generic_buf[0] - '0') * 10; |
count_time_temp[2] = count_time_temp[2] + (generic_buf[1] - '0'); |
} |
// write config to eeprom |
eeprom_write_block ( count_time_temp, ee_count_time, 3 ); |
eeprom_read_block ( count_time, ee_count_time, 3 ); |
count_time[3] = 0; |
} |
|
// print webpage |
dlength = http_home( rxtx_buffer ); |
// send ack before send data |
// tcp_send_ack ( rxtx_buffer, dest_mac, dest_ip ); |
tcp_send_packet ( |
rxtx_buffer, |
(WORD_BYTES){dest_port}, |
(WORD_BYTES){80}, // source port |
TCP_FLAG_ACK_V, // flag |
0, // (bool)maximum segment size |
0, // (bool)clear sequence ack number |
1, // (bool)calculate new seq and seqack number |
0, // tcp data length |
dest_mac, // server mac address |
dest_ip ); // server ip address |
// send tcp data |
// tcp_send_data ( rxtx_buffer, dest_mac, dest_ip, dlength ); |
tcp_send_packet ( |
rxtx_buffer, |
(WORD_BYTES){dest_port}, |
(WORD_BYTES){80}, // source port |
TCP_FLAG_ACK_V | TCP_FLAG_PSH_V | TCP_FLAG_FIN_V, // flag |
0, // (bool)maximum segment size |
0, // (bool)clear sequence ack number |
0, // (bool)calculate new seq and seqack number |
dlength, // tcp data length |
dest_mac, // server mac address |
dest_ip ); // server ip address |
flag1.bits.syn_is_received = 0; |
} |
} |
} |
//******************************************************************************************** |
// |
// Function : http_get_ip |
// Description : Get IP address from buffer (stored after call http_get_variable function) |
// example after call http_get_variable function ip address (ascii) has been stored in buffer |
// 10.1.1.1 (ascii), http_get_ip function convert ip address in ascii to binary and stored |
// in BYTE *dest |
// |
//******************************************************************************************** |
unsigned char http_get_ip ( unsigned char *buf, BYTE *dest ) |
{ |
unsigned char i, ch, digit, temp; |
|
i = 0; |
digit = 1; |
temp = 0; |
|
while ( 1 ) |
{ |
ch = *buf++; |
|
if ( ch >= '0' && ch <= '9' ) |
{ |
ch = ch - '0'; |
temp = (temp * digit) + ch; |
digit *= 10; |
} |
else if ( ch == '.' || ch == '\0' ) |
{ |
dest[ i ] = temp; |
i++; |
digit = 1; |
temp = 0; |
} |
else |
{ |
return 0; |
} |
if ( i == 4 ) |
return i; |
} |
} |
//******************************************************************************************** |
// |
// Function : http_get_variable |
// Description : Get http variable from GET method, example http://10.1.1.1/?pwd=123456 |
// when you call http_get_variable with val_key="pwd", then function stored "123456" |
// to dest buffer. |
// |
//******************************************************************************************** |
BYTE http_get_variable ( BYTE *rxtx_buffer, WORD dlength, PGM_P val_key, BYTE *dest ) |
{ |
WORD data_p; |
PGM_P key; |
BYTE match=0, temp; |
|
key = val_key; |
|
// get data position |
data_p = tcp_get_hlength( rxtx_buffer ) + sizeof(ETH_HEADER) + sizeof(IP_HEADER); |
|
// Find '?' in rx buffer, if found '?' in rx buffer then let's find variable key (val_key) |
for ( ; data_p<dlength; data_p++ ) |
{ |
if ( rxtx_buffer [ data_p ] == '?' ) |
break; |
} |
// not found '?' in buffer |
if ( data_p == dlength ) |
return 0; |
|
// find variable key in buffer |
for ( ; data_p<dlength; data_p++ ) |
{ |
temp = pgm_read_byte ( key ); |
|
// end of variable keyword |
if ( rxtx_buffer [ data_p ] == '=' && match != 0 ) |
{ |
if ( temp == '\0' ) |
{ |
data_p++; |
break; |
} |
} |
// variable keyword match with rx buffer |
if ( rxtx_buffer [ data_p ] == temp ) |
{ |
key++; |
match++; |
} |
else |
{ |
// no match in rx buffer reset match and find again |
key = val_key; |
match = 0; |
} |
} |
|
// if found variable keyword, then store variable value in destination buffer ( dest ) |
if ( match != 0 ) |
{ |
match = 0; |
|
for ( ;; ) |
{ |
// end of variable value break from loop |
if ( rxtx_buffer [ data_p ] == '&' || rxtx_buffer [ data_p ] == ' ' ) |
{ |
dest [ match ] = '\0'; |
break; |
} |
dest [ match ] = rxtx_buffer [ data_p ]; |
match++; |
data_p++; |
} |
} |
|
// return with variable value length |
return match; |
} |
//******************************************************************************************** |
// |
// Function : hex2int |
// Description : convert a single hex digit character to its integer value |
// |
//******************************************************************************************** |
unsigned char hex2int(char c) |
{ |
if (c >= '0' && c <='9') |
return((unsigned char)c - '0'); |
|
if (c >= 'a' && c <='f') |
return((unsigned char)c - 'a' + 10); |
|
if (c >= 'A' && c <='F') |
return((unsigned char)c - 'A' + 10); |
|
return 0; |
} |
//******************************************************************************************** |
// |
// Function : urldecode |
// Description : decode a url string e.g "hello%20joe" or "hello+joe" becomes "hello joe" |
// |
//******************************************************************************************** |
void urldecode(unsigned char *urlbuf) |
{ |
unsigned char c; |
unsigned char *dst; |
|
dst=urlbuf; |
while ((c = *urlbuf)) |
{ |
if (c == '+') c = ' '; |
if (c == '%') |
{ |
urlbuf++; |
c = *urlbuf; |
urlbuf++; |
c = (hex2int(c) << 4) | hex2int(*urlbuf); |
} |
*dst = c; |
dst++; |
urlbuf++; |
} |
*dst = '\0'; |
} |
//***************************************************************************************** |
// |
// Function : http_put_request |
// Description : put http request to tx buffer contain 2-variables pwd and temp. |
// webserver receive pwd, temp and save to text file by PHP script on webserver. |
// |
//***************************************************************************************** |
WORD http_put_request ( BYTE *rxtx_buffer ) |
{ |
BYTE temp_value; |
WORD dlength; |
BYTE generic_buf[64]; |
|
temp_value = adc_read_temp(); |
print_decimal ( generic_buf, 2, temp_value ); |
generic_buf[ 2 ] = '\0'; |
|
dlength = tcp_puts_data_p ( rxtx_buffer, PSTR ( "GET /avrnet/save.php?pwd=secret&temp=" ), 0 ); |
dlength = tcp_puts_data ( rxtx_buffer, (BYTE *)generic_buf, dlength ); |
dlength = tcp_puts_data_p ( rxtx_buffer, PSTR ( " HTTP/1.0\r\n" ), dlength ); |
dlength = tcp_puts_data_p ( rxtx_buffer, PSTR ( "Host: 10.1.1.76\r\n" ), dlength ); |
dlength = tcp_puts_data_p ( rxtx_buffer, PSTR ( "User-Agent: AVR ethernet\r\n" ), dlength ); |
dlength = tcp_puts_data_p ( rxtx_buffer, PSTR ( "Accept: text/html\r\n" ), dlength ); |
dlength = tcp_puts_data_p ( rxtx_buffer, PSTR ( "Keep-Alive: 300\r\n" ), dlength ); |
dlength = tcp_puts_data_p ( rxtx_buffer, PSTR ( "Connection: keep-alive\r\n\r\n" ), dlength ); |
|
return dlength; |
} |
//***************************************************************************************** |
// |
// Function : http_home |
// Description : prepare the webpage by writing the data to the tcp send buffer |
// |
//***************************************************************************************** |
WORD http_home( BYTE *rxtx_buffer ) |
{ |
WORD dlen, adc0_value; |
BYTE temp_value; |
BYTE count_time_temp[3]; |
BYTE generic_buf[64]; |
|
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" ), 0 ); |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "<title>" ), dlen ); |
dlen = tcp_puts_data_p ( rxtx_buffer, (PGM_P)web_title, dlen ); |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "</title>" ), dlen ); |
|
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "<a href=\"http://www.avrportal.com/\" target=\"_blank\"><b><font color=\"#000099\" size=\"+1\">" ), dlen ); |
dlen = tcp_puts_data_p ( rxtx_buffer, (PGM_P)web_title, dlen ); |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "</font></b></a><br>" ), dlen ); |
|
dlen = tcp_puts_data_p ( rxtx_buffer, (PGM_P)tag_hr, dlen ); |
|
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "LED 1 : " ), dlen ); |
if ( (LED_PORT & _BV ( LED_PIN1 )) ) |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "<font color=red>OFF" ), dlen ); |
else |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "<font color=green>ON" ), dlen ); |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "</font> [ <a href=\"./?l1=" ), dlen ); |
if ( (LED_PORT & _BV ( LED_PIN1 )) ) |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "1\">ON" ), dlen ); |
else |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "0\">OFF" ), dlen ); |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "</a> ], LED 2 : " ), dlen ); |
if ( (LED_PORT & _BV ( LED_PIN2 )) ) |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "<font color=red>OFF" ), dlen ); |
else |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "<font color=green>ON" ), dlen ); |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "</font> [ <a href=\"./?l2=" ), dlen ); |
if ( (LED_PORT & _BV ( LED_PIN2 )) ) |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "1\">ON" ), dlen ); |
else |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "0\">OFF" ), dlen ); |
|
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "</a> ]<br><br>" ), dlen ); |
// read adc0 |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "ACD0 = " ), dlen ); |
adc0_value = adc_read ( 0 ); |
print_decimal ( generic_buf, 4, adc0_value ); |
generic_buf[ 4 ] = '\0'; |
dlen = tcp_puts_data ( rxtx_buffer, (BYTE *)generic_buf, dlen ); |
|
// read temp |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "<br><br>Temparature = " ), dlen ); |
temp_value = adc_read_temp(); |
print_decimal ( generic_buf, 2, temp_value ); |
generic_buf[ 2 ] = '\0'; |
dlen = tcp_puts_data ( rxtx_buffer, (BYTE *)generic_buf, dlen ); |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "°C<br>" ), dlen ); |
|
// send temp to server configuration |
dlen = tcp_puts_data_p ( rxtx_buffer, (PGM_P)tag_form, dlen ); |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "<INPUT TYPE=\"hidden\" NAME=\"tc\" VALUE=\"1\">Send Temparature in <INPUT TYPE=\"checkbox\" NAME=\"en\"" ), dlen ); |
eeprom_read_block ( count_time_temp, ee_count_time, 3 ); |
if ( count_time_temp[0] ) |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "CHECKED" ), dlen ); |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "> Enable " ), dlen ); |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "<INPUT TYPE=\"text\" NAME=\"h\" size=\"2\" maxlength=\"2\" VALUE=\"" ), dlen ); |
print_decimal ( generic_buf, 2, count_time_temp[1] ); |
generic_buf[ 2 ] = '\0'; |
dlen = tcp_puts_data ( rxtx_buffer, (BYTE *)generic_buf, dlen ); |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "\"> Hours <INPUT TYPE=\"text\" NAME=\"m\" size=\"2\" maxlength=\"2\" VALUE=\"" ), dlen ); |
print_decimal ( generic_buf, 2, count_time_temp[2] ); |
generic_buf[ 2 ] = '\0'; |
dlen = tcp_puts_data ( rxtx_buffer, (BYTE *)generic_buf, dlen ); |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "\"> Minutes<input type=\"submit\" value=\"OK\"></form>" ), dlen ); |
|
// AVR IP address |
dlen = tcp_puts_data_p ( rxtx_buffer, (PGM_P) tag_form, dlen ); |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "<input name=\"aip\" type=\"text\" size=\"15\" maxlength=\"15\" value=\"" ), dlen ); |
print_ip ( generic_buf, (BYTE*)&avr_ip, 0 ); |
dlen = tcp_puts_data ( rxtx_buffer, (BYTE *)generic_buf, dlen ); |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "\"> <input type=\"submit\" value=\"AVR IP\"></form>" ), dlen ); |
|
// Server IP address |
dlen = tcp_puts_data_p ( rxtx_buffer, (PGM_P)tag_form, dlen ); |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "<input name=\"sip\" type=\"text\" size=\"15\" maxlength=\"15\" value=\"" ), dlen ); |
print_ip ( generic_buf, (BYTE*)&server_ip, 0 ); |
dlen = tcp_puts_data ( rxtx_buffer, (BYTE *)generic_buf, dlen ); |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "\"> <input type=\"submit\" value=\"Server IP\"></form>" ), dlen ); |
|
// Write LCD form |
dlen = tcp_puts_data_p ( rxtx_buffer, (PGM_P) tag_form, dlen ); |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "<input name=\"lcd1\" type=\"text\" size=\"16\" maxlength=\"16\"> LCD Line 1<br>" ), dlen ); |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "<input name=\"lcd2\" type=\"text\" size=\"16\" maxlength=\"16\"> LCD Line 2<br>" ), dlen ); |
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "<input type=\"submit\" value=\"Write LCD\"></form>" ), dlen ); |
|
dlen = tcp_puts_data_p ( rxtx_buffer, (PGM_P)tag_hr, dlen ); |
|
dlen = tcp_puts_data_p ( rxtx_buffer, PSTR ( "<a href=\"./\"><b><font color=\"#000099\" size=\"+1\">Refresh</font></b></a>" ), dlen ); |
|
return(dlen); |
} |
/apps/avr-webserver/arp.c
0,0 → 1,215
//******************************************************************************************** |
// |
// File : arp.c implement for Address Resolution Protocol |
// |
//******************************************************************************************** |
// |
// Copyright (C) 2007 |
// |
// This program is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free Software |
// Foundation; either version 2 of the License, or (at your option) any later |
// version. |
// This program is distributed in the hope that it will be useful, but |
// |
// WITHOUT ANY WARRANTY; |
// |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License along with |
// this program; if not, write to the Free Software Foundation, Inc., 51 |
// Franklin St, Fifth Floor, Boston, MA 02110, USA |
// |
// http://www.gnu.de/gpl-ger.html |
// |
//******************************************************************************************** |
#include "includes.h" |
//******************************************************************************************** |
// |
// Address Resolution Protocol (ARP) is the method for finding a host's hardware address |
// when only its network layer address is known. |
// Due to the overwhelming prevalence of IPv4 and Ethernet, |
// ARP is primarily used to translate IP addresses to Ethernet MAC addresses. |
// It is also used for IP over other LAN technologies, |
// such as Token Ring, FDDI, or IEEE 802.11, and for IP over ATM. |
// |
// ARP is used in four cases of two hosts communicating: |
// |
// 1. When two hosts are on the same network and one desires to send a packet to the other |
// 2. When two hosts are on different networks and must use a gateway/router to reach the other host |
// 3. When a router needs to forward a packet for one host through another router |
// 4. When a router needs to forward a packet from one host to the destination host on the same network |
// |
// +------------+------------+-----------+ |
// + MAC header + ARP header + Data ::: + |
// +------------+------------+-----------+ |
// |
// ARP header |
// |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// +00+01+02+03+04+05+06+07+08+09+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+ |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// + Hardware type + Protocol type + |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// + HardwareAddressLength + ProtocolAddressLength + Opcode + |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// + Source hardware address ::: + |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// + Source protocol address ::: + |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// + Destination hardware address ::: + |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// + Destination protocol address ::: + |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// + Data ::: + |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// |
//******************************************************************************************** |
|
//******************************************************************************************** |
// |
// Function : arp_generate_packet |
// Description : generate arp packet |
// |
//******************************************************************************************** |
void arp_generate_packet ( BYTE *rxtx_buffer, BYTE *dest_mac, BYTE *dest_ip ) |
{ |
unsigned char i; |
|
// setup hardware type to ethernet 0x0001 |
rxtx_buffer[ ARP_HARDWARE_TYPE_H_P ] = ARP_HARDWARE_TYPE_H_V; |
rxtx_buffer[ ARP_HARDWARE_TYPE_L_P ] = ARP_HARDWARE_TYPE_L_V; |
|
// setup protocol type to ip 0x0800 |
rxtx_buffer[ ARP_PROTOCOL_H_P ] = ARP_PROTOCOL_H_V; |
rxtx_buffer[ ARP_PROTOCOL_L_P ] = ARP_PROTOCOL_L_V; |
|
// setup hardware length to 0x06 |
rxtx_buffer[ ARP_HARDWARE_SIZE_P ] = ARP_HARDWARE_SIZE_V; |
|
// setup protocol length to 0x04 |
rxtx_buffer[ ARP_PROTOCOL_SIZE_P ] = ARP_PROTOCOL_SIZE_V; |
|
// setup arp destination and source mac address |
for ( i=0; i<sizeof(MAC_ADDR); i++) |
{ |
rxtx_buffer[ ARP_DST_MAC_P + i ] = dest_mac[i]; |
rxtx_buffer[ ARP_SRC_MAC_P + i ] = avr_mac.byte[i]; |
} |
|
// setup arp destination and source ip address |
for ( i=0; i<sizeof(IP_ADDR); i++) |
{ |
rxtx_buffer[ ARP_DST_IP_P + i ] = dest_ip[i]; |
rxtx_buffer[ ARP_SRC_IP_P + i ] = avr_ip.byte[i]; |
} |
} |
//******************************************************************************************** |
// |
// Function : arp_send_request |
// Description : send arp request packet (who is?) to network. |
// |
//******************************************************************************************** |
void arp_send_request ( BYTE *rxtx_buffer, BYTE *dest_ip ) |
{ |
unsigned char i; |
MAC_ADDR dest_mac; |
|
// generate ethernet header |
for ( i=0; i<sizeof(MAC_ADDR); i++) |
dest_mac.byte[i] = 0xff; |
eth_generate_header ( rxtx_buffer, (WORD_BYTES){ETH_TYPE_ARP_V}, (BYTE*)&dest_mac ); |
|
// generate arp packet |
for ( i=0; i<sizeof(MAC_ADDR); i++) |
dest_mac.byte[i] = 0x00; |
|
// set arp opcode is request |
rxtx_buffer[ ARP_OPCODE_H_P ] = ARP_OPCODE_REQUEST_H_V; |
rxtx_buffer[ ARP_OPCODE_L_P ] = ARP_OPCODE_REQUEST_L_V; |
arp_generate_packet ( rxtx_buffer, (BYTE*)&dest_mac, dest_ip ); |
|
// send arp packet to network |
enc28j60_packet_send ( rxtx_buffer, sizeof(ETH_HEADER) + sizeof(ARP_PACKET) ); |
} |
//******************************************************************************************* |
// |
// Function : arp_packet_is_arp |
// Description : check received packet, that packet is match with arp and avr ip or not? |
// |
//******************************************************************************************* |
BYTE arp_packet_is_arp ( BYTE *rxtx_buffer, WORD_BYTES opcode ) |
{ |
BYTE i; |
|
// if packet type is not arp packet exit from function |
if( rxtx_buffer[ ETH_TYPE_H_P ] != ETH_TYPE_ARP_H_V || rxtx_buffer[ ETH_TYPE_L_P ] != ETH_TYPE_ARP_L_V) |
return 0; |
// check arp request opcode |
if ( rxtx_buffer[ ARP_OPCODE_H_P ] != opcode.byte.high || rxtx_buffer[ ARP_OPCODE_L_P ] != opcode.byte.low ) |
return 0; |
// if destination ip address in arp packet not match with avr ip address |
for ( i=0; i<sizeof(IP_ADDR); i++ ) |
{ |
if ( rxtx_buffer[ ARP_DST_IP_P + i] != avr_ip.byte[i] ) |
return 0; |
} |
return 1; |
} |
//******************************************************************************************* |
// |
// Function : arp_send_reply |
// Description : Send reply if recieved packet is ARP and IP address is match with avr_ip |
// |
//******************************************************************************************* |
void arp_send_reply ( BYTE *rxtx_buffer, BYTE *dest_mac ) |
{ |
// generate ethernet header |
eth_generate_header ( rxtx_buffer, (WORD_BYTES){ETH_TYPE_ARP_V}, dest_mac ); |
|
// change packet type to echo reply |
rxtx_buffer[ ARP_OPCODE_H_P ] = ARP_OPCODE_REPLY_H_V; |
rxtx_buffer[ ARP_OPCODE_L_P ] = ARP_OPCODE_REPLY_L_V; |
arp_generate_packet ( rxtx_buffer, dest_mac, &rxtx_buffer[ ARP_SRC_IP_P ] ); |
|
// send arp packet |
enc28j60_packet_send ( rxtx_buffer, sizeof(ETH_HEADER) + sizeof(ARP_PACKET) ); |
} |
//******************************************************************************************* |
// |
// Function : arp_who_is |
// Description : send arp request to destination ip, and save destination mac to dest_mac. |
// call this function to find the destination mac address before send other packet. |
// |
//******************************************************************************************* |
BYTE arp_who_is ( BYTE *rxtx_buffer, BYTE *dest_mac, BYTE *dest_ip ) |
{ |
BYTE i; |
WORD dlength; |
|
// send arp request packet to network |
arp_send_request ( rxtx_buffer, dest_ip ); |
|
for ( i=0; i<10; i++ ) |
{ |
// Time out 10x10ms = 100ms |
_delay_ms ( 10 ); |
dlength = enc28j60_packet_receive( rxtx_buffer, MAX_RXTX_BUFFER ); |
|
// destination ip address was found on network |
if ( dlength ) |
{ |
if ( arp_packet_is_arp ( rxtx_buffer, (WORD_BYTES){ARP_OPCODE_REPLY_V} ) ) |
{ |
// copy destination mac address from arp reply packet to destination mac address |
memcpy ( dest_mac, &rxtx_buffer[ ETH_SRC_MAC_P ], sizeof(MAC_ADDR) ); |
return 1; |
} |
} |
} |
|
// destination ip was not found on network |
return 0; |
} |
|
/apps/avr-webserver/http.h
0,0 → 1,38
//******************************************************************************************** |
// |
// File : http.h implement for Hyper Text transfer Protocol |
// |
//******************************************************************************************** |
// |
// Copyright (C) 2007 |
// |
// This program is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free Software |
// Foundation; either version 2 of the License, or (at your option) any later |
// version. |
// This program is distributed in the hope that it will be useful, but |
// |
// WITHOUT ANY WARRANTY; |
// |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License along with |
// this program; if not, write to the Free Software Foundation, Inc., 51 |
// Franklin St, Fifth Floor, Boston, MA 02110, USA |
// |
// http://www.gnu.de/gpl-ger.html |
// |
//******************************************************************************************** |
|
//******************************************************************************************** |
// |
// Prototype function |
// |
//******************************************************************************************** |
extern WORD http_home( BYTE *rxtx_buffer ); |
extern BYTE http_get_variable ( BYTE *rxtx_buffer, WORD dlength, PGM_P val_key, BYTE *dest ); |
extern BYTE http_get_ip ( BYTE *buf, BYTE *dest ); |
extern void urldecode( BYTE *urlbuf); |
extern void http_webserver_process ( BYTE *rxtx_buffer, BYTE *dest_mac, BYTE *dest_ip ); |
extern WORD http_put_request ( BYTE *rxtx_buffer ); |
/apps/avr-webserver/arp.h
0,0 → 1,65
//******************************************************************************************** |
// |
// File : arp.h implement for Address Resolution Protocol |
// |
//******************************************************************************************** |
// |
// Copyright (C) 2007 |
// |
// This program is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free Software |
// Foundation; either version 2 of the License, or (at your option) any later |
// version. |
// This program is distributed in the hope that it will be useful, but |
// |
// WITHOUT ANY WARRANTY; |
// |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License along with |
// this program; if not, write to the Free Software Foundation, Inc., 51 |
// Franklin St, Fifth Floor, Boston, MA 02110, USA |
// |
// http://www.gnu.de/gpl-ger.html |
// |
//******************************************************************************************** |
#define ARP_PACKET_LEN 28 |
|
#define ARP_OPCODE_REQUEST_V 0x0001 |
#define ARP_OPCODE_REQUEST_H_V 0x00 |
#define ARP_OPCODE_REQUEST_L_V 0x01 |
#define ARP_OPCODE_REPLY_V 0x0002 |
#define ARP_OPCODE_REPLY_H_V 0x00 |
#define ARP_OPCODE_REPLY_L_V 0x02 |
|
#define ARP_HARDWARE_TYPE_H_V 0x00 |
#define ARP_HARDWARE_TYPE_L_V 0x01 |
#define ARP_PROTOCOL_H_V 0x08 |
#define ARP_PROTOCOL_L_V 0x00 |
#define ARP_HARDWARE_SIZE_V 0x06 |
#define ARP_PROTOCOL_SIZE_V 0x04 |
|
#define ARP_HARDWARE_TYPE_H_P 0x0E |
#define ARP_HARDWARE_TYPE_L_P 0x0F |
#define ARP_PROTOCOL_H_P 0x10 |
#define ARP_PROTOCOL_L_P 0x11 |
#define ARP_HARDWARE_SIZE_P 0x12 |
#define ARP_PROTOCOL_SIZE_P 0x13 |
#define ARP_OPCODE_H_P 0x14 |
#define ARP_OPCODE_L_P 0x15 |
#define ARP_SRC_MAC_P 0x16 |
#define ARP_SRC_IP_P 0x1C |
#define ARP_DST_MAC_P 0x20 |
#define ARP_DST_IP_P 0x26 |
|
//******************************************************************************************** |
// |
// Prototype function |
// |
//******************************************************************************************** |
extern void arp_generate_packet ( BYTE *rxtx_buffer, BYTE *dest_mac, BYTE *dest_ip ); |
extern void arp_send_request ( BYTE *rxtx_buffer, BYTE *dest_ip ); |
extern void arp_send_reply ( BYTE *rxtx_buffer, BYTE *dest_mac ); |
extern BYTE arp_packet_is_arp ( BYTE *rxtx_buffer, WORD_BYTES opcode ); |
extern BYTE arp_who_is ( BYTE *rxtx_buffer, BYTE *dest_mac, BYTE *dest_ip ); |
/apps/avr-webserver/udp.c
0,0 → 1,350
//******************************************************************************************** |
// |
// File : udp.c implement for User Datagram Protocol |
// |
//******************************************************************************************** |
// |
// Copyright (C) 2007 |
// |
// This program is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free Software |
// Foundation; either version 2 of the License, or (at your option) any later |
// version. |
// This program is distributed in the hope that it will be useful, but |
// |
// WITHOUT ANY WARRANTY; |
// |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License along with |
// this program; if not, write to the Free Software Foundation, Inc., 51 |
// Franklin St, Fifth Floor, Boston, MA 02110, USA |
// |
// http://www.gnu.de/gpl-ger.html |
// |
//******************************************************************************************** |
#include "includes.h" |
//******************************************************************************************** |
// The User Datagram Protocol offers only a minimal transport service |
// -- non-guaranteed datagram delivery |
// -- and gives applications direct access to the datagram service of the IP layer. |
// UDP is used by applications that do not require the level of service of TCP or |
// that wish to use communications services (e.g., multicast or broadcast delivery) |
// not available from TCP. |
// |
// +------------+-----------+-------------+----------+ |
// + MAC header + IP header + UDP header + Data ::: + |
// +------------+-----------+-------------+----------+ |
// |
// UDP header |
// |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// +00+01+02+03+04+05+06+07+08+09+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+ |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// + Source port + Destination port + |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// + Length + Checksum + |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// + Data ::: + |
// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
// |
//******************************************************************************************** |
// |
// Function : udp_generate_header |
// Argument : BYTE *rxtx_buffer is a pointer point to UDP tx buffer |
// WORD_BYTES dest_port is a destiantion port |
// WORD_BYTES length is a UDP header and data length |
// Return value : None |
// |
// Description : generate udp header |
// |
//******************************************************************************************** |
void udp_generate_header ( BYTE *rxtx_buffer, WORD_BYTES dest_port, WORD_BYTES length ) |
{ |
WORD_BYTES ck; |
|
// setup source port, default value is 3000 |
rxtx_buffer[UDP_SRC_PORT_H_P] = UDP_AVR_PORT_H_V; |
rxtx_buffer[UDP_SRC_PORT_L_P] = UDP_AVR_PORT_L_V; |
|
// setup destination port |
rxtx_buffer[UDP_DST_PORT_H_P] = dest_port.byte.high; |
rxtx_buffer[UDP_DST_PORT_L_P] = dest_port.byte.low; |
|
// setup udp length |
rxtx_buffer[UDP_LENGTH_H_P] = length.byte.high; |
rxtx_buffer[UDP_LENGTH_L_P] = length.byte.low; |
|
// setup udp checksum |
rxtx_buffer[UDP_CHECKSUM_H_P] = 0; |
rxtx_buffer[UDP_CHECKSUM_L_P] = 0; |
// length+8 for source/destination IP address length (8-bytes) |
ck.word = software_checksum ( (BYTE*)&rxtx_buffer[IP_SRC_IP_P], length.word+8, length.word+IP_PROTO_UDP_V); |
rxtx_buffer[UDP_CHECKSUM_H_P] = ck.byte.high; |
rxtx_buffer[UDP_CHECKSUM_L_P] = ck.byte.low; |
} |
//******************************************************************************************** |
// |
// Function : udp_puts_data |
// Description : puts data from RAM to UDP tx buffer |
// |
//******************************************************************************************** |
WORD udp_puts_data ( BYTE *rxtx_buffer, BYTE *data, WORD offset ) |
{ |
while( *data ) |
{ |
rxtx_buffer[ UDP_DATA_P + offset ] = *data++; |
offset++; |
} |
|
return offset; |
} |
//******************************************************************************************** |
// |
// Function : udp_puts_data_p |
// Description : puts data from program memory to tx buffer |
// |
//******************************************************************************************** |
WORD udp_puts_data_p ( BYTE *rxtx_buffer, PGM_P data, WORD offset ) |
{ |
BYTE ch; |
|
while( (ch = pgm_read_byte(data++)) ) |
{ |
rxtx_buffer[ UDP_DATA_P + offset ] = ch; |
offset++; |
} |
|
return offset; |
} |
//******************************************************************************************** |
// |
// Function : udp_receive |
// Argument : BYTE *rxtx_buffer is a pointer, point to UDP tx buffer |
// BYTE *dest_mac is a pointer, point to destiantion MAC address |
// BYTE *dest_ip is a pointer, point to destiantion IP address |
// Return value : if received packet is UDP and destination port matching with AVR port, return true |
// other return false |
// |
// Description : check received packet and process UDP command. |
// |
//******************************************************************************************** |
BYTE udp_receive ( BYTE *rxtx_buffer, BYTE *dest_mac, BYTE *dest_ip ) |
{ |
WORD_BYTES dlength, adc0; |
BYTE generic_buf[64], temp, count_time_temp[3], tmp; |
|
// check UDP packet and check destination port |
if ( rxtx_buffer[IP_PROTO_P] != IP_PROTO_UDP_V || rxtx_buffer[UDP_DST_PORT_H_P] != UDP_AVR_PORT_H_V || rxtx_buffer[ UDP_DST_PORT_L_P ] != UDP_AVR_PORT_L_V ) |
return 0; |
|
// check UDP command, UDP command are first and second byte |
// "GA" command is Get All command, AVR will be send all data to AVRnet CPannel |
// Response format is OKLLADC0TTEHHMMAAA.AAA.AAA.AAA;SSS.SSS.SSS.SSS;\r\n |
// LL is LED1 and LED2 |
// ADC0 is ADC0 value |
// TT is temperature |
// E is send temp enable/disable |
// HH is hours for send temp |
// MM is minutes for send temp |
// AAA.AAA.AAA.AAA is an AVR IP address |
// SSS.SSS.SSS.SSS is a Server IP address |
// ';' is end of IP address |
// \r\n is end of command |
// for example : GA100512250010010.1.1.1;10.1.1.76\r\n = LED1 on, LED2 off, ADC0 0512, Temp 25, Disable send temp, Hour 01, Min 00 |
if ( rxtx_buffer[UDP_DATA_P] == 'G' && rxtx_buffer[UDP_DATA_P+1] == 'A' && rxtx_buffer[UDP_DATA_P+2] == '\r' && rxtx_buffer[UDP_DATA_P+3] == '\n') |
{ |
// command response |
dlength.word = udp_puts_data_p ( rxtx_buffer, PSTR("GAOK"), 0 ); |
// LED1 |
if ((LED_PORT&_BV(LED_PIN1))==0) |
dlength.word = udp_puts_data_p ( rxtx_buffer, PSTR("1"), dlength.word ); |
else |
dlength.word = udp_puts_data_p ( rxtx_buffer, PSTR("0"), dlength.word ); |
// LED2 |
if ((LED_PORT&_BV(LED_PIN2))==0) |
dlength.word = udp_puts_data_p ( rxtx_buffer, PSTR("1"), dlength.word ); |
else |
dlength.word = udp_puts_data_p ( rxtx_buffer, PSTR("0"), dlength.word ); |
// ADC0 |
adc0.word = adc_read ( 0 ); |
print_decimal ( generic_buf, 4, adc0.word ); |
generic_buf[ 4 ] = '\0'; |
dlength.word = udp_puts_data ( rxtx_buffer, (BYTE *)generic_buf, dlength.word ); |
// temperature |
temp = adc_read_temp(); |
print_decimal ( generic_buf, 2, temp ); |
generic_buf[ 2 ] = '\0'; |
dlength.word = udp_puts_data ( rxtx_buffer, (BYTE *)generic_buf, dlength.word ); |
// send temp config |
eeprom_read_block ( count_time_temp, ee_count_time, 3 ); |
if (count_time_temp[0]) |
dlength.word = udp_puts_data_p ( rxtx_buffer, PSTR("1"), dlength.word ); |
else |
dlength.word = udp_puts_data_p ( rxtx_buffer, PSTR("0"), dlength.word ); |
print_decimal ( generic_buf, 2, count_time_temp[1] ); |
generic_buf[ 2 ] = '\0'; |
dlength.word = udp_puts_data ( rxtx_buffer, (BYTE *)generic_buf, dlength.word ); |
print_decimal ( generic_buf, 2, count_time_temp[2] ); |
generic_buf[ 2 ] = '\0'; |
dlength.word = udp_puts_data ( rxtx_buffer, (BYTE *)generic_buf, dlength.word ); |
// AVR IP address |
print_ip ( generic_buf, (BYTE*)&avr_ip, 0 ); |
dlength.word = udp_puts_data ( rxtx_buffer, (BYTE *)generic_buf, dlength.word ); |
dlength.word = udp_puts_data_p ( rxtx_buffer, PSTR(";"), dlength.word ); |
// Server IP address |
print_ip ( generic_buf, (BYTE*)&server_ip, 0 ); |
dlength.word = udp_puts_data ( rxtx_buffer, (BYTE *)generic_buf, dlength.word ); |
dlength.word = udp_puts_data_p ( rxtx_buffer, PSTR(";\r\n"), dlength.word ); |
} |
// "ST" command is set send temperature configuration command |
// "ST" command format is STEHHMM\r\n |
// E is send temp enable/disable |
// HH is hours for send temp |
// MM is minutes for send temp |
// \r\n is end of command |
// for example : ST10115\r\n = Enable send temp, 1-Hour, 15-Minutes |
else if ( rxtx_buffer[UDP_DATA_P] == 'S' && rxtx_buffer[UDP_DATA_P+1] == 'T' && rxtx_buffer[UDP_DATA_P+7] == '\r' && rxtx_buffer[UDP_DATA_P+8] == '\n') |
{ |
// get enable/disable |
count_time_temp[0] = rxtx_buffer[UDP_DATA_P+2] - '0'; |
// get hour |
count_time_temp[1] = (rxtx_buffer[UDP_DATA_P+3] - '0') * 10; |
count_time_temp[1] = count_time_temp[1] + (rxtx_buffer[UDP_DATA_P+4] - '0'); |
// get minute |
count_time_temp[2] = (rxtx_buffer[UDP_DATA_P+5] - '0') * 10; |
count_time_temp[2] = count_time_temp[2] + (rxtx_buffer[UDP_DATA_P+6] - '0'); |
// write config to eeprom |
eeprom_write_block ( count_time_temp, ee_count_time, 3 ); |
eeprom_read_block ( count_time, ee_count_time, 3 ); |
count_time[3] = 0; |
// command response |
dlength.word = udp_puts_data_p ( rxtx_buffer, PSTR("STOK\r\n"), 0 ); |
} |
// "SI" command is set AVR IP address command |
// "SI" command format is SIAAA.AAA.AAA.AAA;SSS.SSS.SSS.SSS;\r\n |
// AAA.AAA.AAA.AAA is an AVR IP address (variable length) |
// SSS.SSS.SSS.SSS is a Server IP address (variable length) |
// ';' end of ip address |
// \r\n is end of command |
// for example : SI10.1.1.1;10.1.1.76;\r\n |
else if ( rxtx_buffer[UDP_DATA_P] == 'S' && rxtx_buffer[UDP_DATA_P+1] == 'I' ) |
{ |
// find \r\n |
for(tmp=UDP_DATA_P; tmp<UDP_DATA_P+128; tmp++) |
{ |
if(rxtx_buffer[UDP_DATA_P+tmp]=='\r' && rxtx_buffer[UDP_DATA_P+tmp+1]=='\n') |
{ |
temp = 0; |
break; |
} |
} |
if(temp==0) |
{ |
tmp = 0; |
// find ';' end of IP address and replace it with zero |
while ( rxtx_buffer[UDP_DATA_P+tmp] != ';') tmp++; |
rxtx_buffer[UDP_DATA_P+tmp] = 0; |
// use http_get_ip to convert ascii to hex |
if ( http_get_ip ( (BYTE*)&rxtx_buffer[UDP_DATA_P+2], (BYTE*)&avr_ip ) == 4 ) |
eeprom_write_block ( &avr_ip, ee_avr_ip, 4 ); |
eeprom_read_block ( &avr_ip, ee_avr_ip, 4 ); |
|
// Get server IP |
temp = tmp+1; |
while ( rxtx_buffer[UDP_DATA_P+tmp] != ';') tmp++; |
rxtx_buffer[UDP_DATA_P+tmp] = '\0'; |
// use http_get_ip to convert ascii to hex |
if ( http_get_ip ( (BYTE*)&rxtx_buffer[UDP_DATA_P+temp], (BYTE*)&server_ip ) == 4 ) |
eeprom_write_block ( &avr_ip, ee_server_ip, 4 ); |
eeprom_read_block ( &avr_ip, ee_server_ip, 4 ); |
|
// send command response to client |
dlength.word = udp_puts_data_p ( rxtx_buffer, PSTR("SIOK\r\n"), 0 ); |
} |
else |
{ |
dlength.word = udp_puts_data_p ( rxtx_buffer, PSTR("ERROR\r\n"), 0 ); |
} |
} |
// "WL" command is Write LCD command |
// "WL" command format is WL1111111111111111;2222222222222222;\r\n |
// 1111111111111111 is 1'st line character (variable length, max is 16) |
// 2222222222222222 is 2'nd line character (variable length, max is 16) |
// ';' end of character |
// \r\n is end of command |
// for example : WLHello World!;I'm AVRnet;\r\n |
else if ( rxtx_buffer[UDP_DATA_P] == 'W' && rxtx_buffer[UDP_DATA_P+1] == 'L') |
{ |
// find \r\n |
for(tmp=UDP_DATA_P; tmp<UDP_DATA_P+128; tmp++) |
{ |
if(rxtx_buffer[UDP_DATA_P+tmp]=='\r' && rxtx_buffer[UDP_DATA_P+tmp+1]=='\n') |
{ |
temp = 0; |
break; |
} |
} |
if(temp==0) |
{ |
tmp=0; |
// find end of 1'st line and replace it with '\n' |
while( rxtx_buffer[UDP_DATA_P+tmp] != ';' ) tmp++; |
rxtx_buffer[UDP_DATA_P+tmp] = '\n'; |
// find end of 1'st line and replace it with '\0' |
while( rxtx_buffer[UDP_DATA_P+tmp] != ';' ) tmp++; |
rxtx_buffer[UDP_DATA_P+tmp] = '\0'; |
// print string to LCD |
lcd_putc ( '\f' ); |
lcd_print ( (BYTE*)&rxtx_buffer[UDP_DATA_P+2] ); |
flag1.bits.lcd_busy = 1; |
|
// send command response to client |
dlength.word = udp_puts_data_p ( rxtx_buffer, PSTR("WLOK\r\n"), 0 ); |
} |
else |
{ |
dlength.word = udp_puts_data_p ( rxtx_buffer, PSTR("ERROR\r\n"), 0 ); |
} |
} |
// "SL" command, is set LED1, LED2 command |
// "SL" command format is SL12\r\n |
// 1 is on/off command for LED1 '1' = ON, '0' = OFF |
// 2 is on/off command for LED2 '1' = ON, '0' = OFF |
// \r\n is end of command |
else if(rxtx_buffer[UDP_DATA_P]=='S' && rxtx_buffer[UDP_DATA_P+1]=='L' && rxtx_buffer[UDP_DATA_P+4]=='\r' && rxtx_buffer[UDP_DATA_P+5]=='\n') |
{ |
// on/off LED1 |
if(rxtx_buffer[UDP_DATA_P+2]=='0') |
LED_PORT |= _BV ( LED_PIN1 ); |
else |
LED_PORT &= ~_BV ( LED_PIN1 ); |
// on/off LED2 |
if(rxtx_buffer[UDP_DATA_P+3]=='0') |
LED_PORT |= _BV ( LED_PIN2 ); |
else |
LED_PORT &= ~_BV ( LED_PIN2 ); |
// send command response |
dlength.word = udp_puts_data_p ( rxtx_buffer, PSTR("SLOK\r\n"), 0 ); |
} |
else |
{ |
// unknown command, send "ERROR" to client |
dlength.word = udp_puts_data_p ( rxtx_buffer, PSTR("ERROR\r\n"), 0 ); |
} |
|
// set ethernet header |
eth_generate_header (rxtx_buffer, (WORD_BYTES){ETH_TYPE_IP_V}, dest_mac ); |
|
// generate ip header and checksum |
ip_generate_header (rxtx_buffer, (WORD_BYTES){sizeof(IP_HEADER)+sizeof(UDP_HEADER)+dlength.word}, IP_PROTO_UDP_V, dest_ip ); |
|
// generate UDP header |
udp_generate_header (rxtx_buffer, (WORD_BYTES){(rxtx_buffer[UDP_SRC_PORT_H_P]<<8)|rxtx_buffer[UDP_SRC_PORT_L_P]}, (WORD_BYTES){sizeof(UDP_HEADER)+dlength.word}); |
|
// send packet to ethernet media |
enc28j60_packet_send ( rxtx_buffer, sizeof(ETH_HEADER)+sizeof(IP_HEADER)+sizeof(UDP_HEADER)+dlength.word ); |
|
return 1; |
} |
/apps/avr-webserver/read.me
0,0 → 1,6
These files are downloaded from |
|
http://tuxgraphics.org/common/src2/article06111/ |
|
Board Details: |
http://www.embeddedmarket.com/products/AVR-Embedded-Web-server/ |
/apps/avr-webserver/udp.h
0,0 → 1,44
//******************************************************************************************** |
// |
// File : udp.h implement for User Datagram Protocol |
// |
//******************************************************************************************** |
// |
// Copyright (C) 2007 |
// |
// This program is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free Software |
// Foundation; either version 2 of the License, or (at your option) any later |
// version. |
// This program is distributed in the hope that it will be useful, but |
// |
// WITHOUT ANY WARRANTY; |
// |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License along with |
// this program; if not, write to the Free Software Foundation, Inc., 51 |
// Franklin St, Fifth Floor, Boston, MA 02110, USA |
// |
// http://www.gnu.de/gpl-ger.html |
// |
//******************************************************************************************** |
#define UDP_AVR_PORT_V 3000 |
#define UDP_AVR_PORT_H_V (UDP_AVR_PORT_V>>8) |
#define UDP_AVR_PORT_L_V (UDP_AVR_PORT_V&0xff) |
|
#define UDP_SRC_PORT_H_P 0x22 |
#define UDP_SRC_PORT_L_P 0x23 |
#define UDP_DST_PORT_H_P 0x24 |
#define UDP_DST_PORT_L_P 0x25 |
#define UDP_LENGTH_H_P 0x26 |
#define UDP_LENGTH_L_P 0x27 |
#define UDP_CHECKSUM_H_P 0x28 |
#define UDP_CHECKSUM_L_P 0x29 |
#define UDP_DATA_P 0x2A |
|
extern void udp_generate_header ( BYTE *rxtx_buffer, WORD_BYTES dest_port, WORD_BYTES length ); |
extern WORD udp_puts_data ( BYTE *rxtx_buffer, BYTE *data, WORD offset ); |
extern WORD udp_puts_data_p ( BYTE *rxtx_buffer, PGM_P data, WORD offset ); |
extern BYTE udp_receive ( BYTE *rxtx_buffer, BYTE *dest_mac, BYTE *dest_ip ); |
/apps/avr-webserver/lcd.c
0,0 → 1,155
//******************************************************************************************** |
// |
// File : lcd.c implement for 16x2 LCD module |
// |
//******************************************************************************************** |
// |
// Copyright (C) 2007 |
// |
// This program is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free Software |
// Foundation; either version 2 of the License, or (at your option) any later |
// version. |
// This program is distributed in the hope that it will be useful, but |
// |
// WITHOUT ANY WARRANTY; |
// |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License along with |
// this program; if not, write to the Free Software Foundation, Inc., 51 |
// Franklin St, Fifth Floor, Boston, MA 02110, USA |
// |
// http://www.gnu.de/gpl-ger.html |
// |
//******************************************************************************************** |
#include "includes.h" |
//******************************************************************************************** |
// |
// Function : lcd_send_nibble |
// Description : Send data (nibble) to lcd module |
// |
//******************************************************************************************** |
void lcd_send_nibble(unsigned char data) |
{ |
data &= 0xF0; |
LCD_DATA_PORT &= 0x0F; |
LCD_DATA_PORT |= data; |
_delay_us(1); // 1us |
LCD_CONTROL_PORT |= _BV(LCD_EN_PIN); |
_delay_us(2); |
LCD_CONTROL_PORT &= ~_BV(LCD_EN_PIN); |
} |
//******************************************************************************************** |
// |
// Function : lcd_send_byte |
// Description : Send data (byte) to lcd module |
// |
//******************************************************************************************** |
void lcd_send_byte( char data_or_cmd, char data ) |
{ |
LCD_CONTROL_PORT &= ~_BV(LCD_RS_PIN); |
if(data_or_cmd) |
LCD_CONTROL_PORT |= _BV(LCD_RS_PIN); |
else |
LCD_CONTROL_PORT &= ~_BV(LCD_RS_PIN); |
_delay_us(50); // 1us |
LCD_CONTROL_PORT &= ~_BV(LCD_EN_PIN); |
lcd_send_nibble(data & 0xF0); |
lcd_send_nibble(data << 4); |
} |
//******************************************************************************************** |
// |
// Function : lcd_init |
// Description : Lcd module initiation.(4-bits mode) |
// |
//******************************************************************************************** |
void lcd_init(void) |
{ |
char i; |
LCD_DATA_DDR |= (_BV(LCD_D7) | _BV(LCD_D6) | _BV(LCD_D5) | _BV(LCD_D4)); |
LCD_CONTROL_DDR |= (_BV(LCD_RS_PIN) | _BV(LCD_RW_PIN) | _BV(LCD_EN_PIN)); |
|
LCD_DATA_PORT &= ~(_BV(LCD_D7) | _BV(LCD_D6) | _BV(LCD_D5) | _BV(LCD_D4)); |
LCD_CONTROL_PORT &= ~(_BV(LCD_RS_PIN) | _BV(LCD_RS_PIN) | _BV(LCD_RS_PIN)); |
|
_delay_ms(15); // 15 ms |
for(i=1;i<=3;++i) |
{ |
lcd_send_nibble(0x30); |
_delay_ms(5); // 5 ms |
} |
lcd_send_nibble(0x20); |
lcd_send_byte(WRITE_COMMAND, SET_FUNCTION); |
lcd_send_byte(WRITE_COMMAND, DISPLAY_ON); |
lcd_send_byte(WRITE_COMMAND, DISPLAY_CLR); |
lcd_send_byte(WRITE_COMMAND, ENTRY_MODE); |
} |
//******************************************************************************************** |
// |
// Function : lcd_gotoxy |
// Description : Send SET_DDRAM command to lcd module |
// |
//******************************************************************************************** |
void lcd_gotoxy( unsigned char x, unsigned char y) |
{ |
char address=0; |
|
if(y!=1) |
address = LCD_LINE_TWO; |
address += x-1; |
lcd_send_byte(WRITE_COMMAND, SET_DDRAM|address); |
} |
//******************************************************************************************** |
// |
// Function : lcd_putc |
// Description : Send data(byte) or command to lcd module |
// '\f' is clear display command |
// '\n' is new line (second line) command |
// '\b' is cursor back command |
// |
//******************************************************************************************** |
void lcd_putc( unsigned char c) |
{ |
if(c == '\f') |
{ |
lcd_send_byte(WRITE_COMMAND, DISPLAY_CLR); |
_delay_ms(2); // 2ms |
} |
else if(c == '\n') |
lcd_gotoxy(1, 2); |
else if(c == '\b') |
lcd_send_byte(WRITE_COMMAND, CURSOR_BACK); |
else |
lcd_send_byte(WRITE_DATA, c); |
} |
//******************************************************************************************** |
// |
// Function : lcd_print |
// Description : print string from ram to lcd module |
// |
//******************************************************************************************** |
void lcd_print( BYTE *ptr ) |
{ |
|
while( *ptr ) |
{ |
lcd_putc(*ptr++); |
} |
} |
//******************************************************************************************** |
// |
// Function : lcd_print_p |
// Description : print string from program memory to lcd module |
// |
//******************************************************************************************** |
void lcd_print_p( PGM_P ptr ) |
{ |
unsigned char c; |
|
while( (c = pgm_read_byte ( ptr++ )) ) |
{ |
lcd_putc(c); |
} |
} |
/apps/avr-webserver/ReadmeEN.html
0,0 → 1,76
<html> |
<head> |
<title>AVRnet V0.9 by avrportal.com</title> |
</head> |
<body> |
<font color=blue><b>AVRnet V1.0 by avrportal.com</b></font><br> |
Hardware is base on V0.9<br> |
What's new?<br> |
- UDP (User Datagram Protocol) has been added to V1.0<br> |
- New software <b>AVRnet CPannel</b> for UDP interfacing, written using CodeBlocks C++ IDE with wxWidgets GUI tool kits and MinGW GCC compiler.<br><br> |
|
<img src="AVRnetCPannel.gif"><br> |
<br><b><font color="#0000FF">Download</font></b><br> |
<a href="http://www.avrportal.com/avrnet/avrnet-v1.0-20070625.7z">AVRnet V1.0 source code</a><br> |
<a href="http://www.avrportal.com/avrnet/avrnet-cpannel-src.7z">AVRnet CPannel source code</a><br> |
<a href="http://www.avrportal.com/avrnet/avrnet-cpannel-bin.7z">AVRnet CPannel binary</a><br> |
<hr align="left" width="700" size="5"> |
<br> |
|
<font color=blue><b>AVRnet V0.9 by avrportal.com</b></font><br> |
<br> |
AVRnet Firmware Version 0.9<br> |
<br> |
AVRnet is an Ethernet development board, v0.9 first is pubblic release.<br> |
You can use AVRnet to build a small web-server and web-client for send data to webserver.<br> |
Before you can use web-client application, Apache and PHP must be installed on your pc.<br> |
More detail about Apache and PHP installation please visit <a href="http://www.avrportal.com">http://www.avrportal.com</a><br> |
<br> |
<hr align="left" width="600" size="1"> |
<br> |
<font color=blue><b>Hardware feature</b></font><br> |
<br> |
- MCU : ATMEGA32 @ 16MHz<br> |
- Ethernet controller : ENC28J60<br> |
- RJ11 for LAN<br> |
- LCD user interface menu<br> |
- JTAG interface for program and debug<br> |
- Temparature sensor using thermistor<br> |
- 1 potentiometer for ADC0<br> |
- I2C connector with pull-up resistor<br> |
- Built-in Voltage regulator<br> |
- LEDs display and switchs for LCD menu<br> |
<br> |
<hr align="left" width="600" size="1"><br> |
<font color=blue><b>Firmware feature</b></font><br> |
<br> |
- Firmware is GPL using AVR GCC compiler<br> |
- LCD user interface menu and borad status<br> |
- Webserver listen on port 80 ( example page "webpage.htm" )<br> |
- Webclient listen on port 1200 ( use for send temparature to webserver.)<br> |
<br> |
<hr align="left" width="600" size="1"><br> |
<font color=blue><b>LCD user interface menu</b></font><br><br> |
AVRnet use 4 tact switchs are menu, exit, up and dw for LCD menu.<br> |
You can setup AVR IP, Server IP, Countdown timer by enter to each menu.<br> |
<br> |
Main menu<br> |
<ul> |
<li>AVR IP config (setup AVRnet IP address)</li> |
<li>Server IP config (setup AVRnet IP address)</li> |
<li>Send temp config (setup countdown timer for send temparature to webserver)</li> |
<li>Ping server (check server online status)</li> |
</ul> |
|
You can see each status by press UP and Dw button board status are show below. |
<br><br> |
standby display mode<br> |
<ul> |
<li>AVR IP(show current AVR IP address)</li> |
<li>Server IP (show current server IP address)</li> |
<li>Send temp in (show countdown timer for send temp)</li> |
<li>ADC0 & Temp (show current ADC0 and temparature)</li> |
</ul> |
<hr align="left" width="600" size="1"> |
</body> |
</html> |
/apps/avr-webserver/default/Makefile
0,0 → 1,108
############################################################################### |
# Makefile for the project avrnet |
############################################################################### |
|
## General Flags |
PROJECT = avrnet |
MCU = atmega32 |
TARGET = avrnet.elf |
CC = avr-gcc.exe |
|
## Options common to compile, link and assembly rules |
COMMON = -mmcu=$(MCU) |
|
## Compile options common for all C compilation units. |
CFLAGS = $(COMMON) |
CFLAGS += -Wall -gdwarf-2 -DF_CPU=16000000UL -Os -fsigned-char |
CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d |
|
## Assembly specific flags |
ASMFLAGS = $(COMMON) |
ASMFLAGS += $(CFLAGS) |
ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 |
|
## Linker flags |
LDFLAGS = $(COMMON) |
LDFLAGS += -Wl,-Map=avrnet.map |
|
|
## Intel Hex file production flags |
HEX_FLASH_FLAGS = -R .eeprom |
|
HEX_EEPROM_FLAGS = -j .eeprom |
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" |
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings |
|
|
## Objects that must be built in order to link |
OBJECTS = enc28j60.o main.o http.o arp.o tcp.o ip.o ethernet.o icmp.o menu.o lcd.o adc.o udp.o |
|
## Objects explicitly added by the user |
LINKONLYOBJECTS = |
|
## Build |
all: $(TARGET) avrnet.hex avrnet.eep avrnet.lss size |
|
## Compile |
enc28j60.o: ../enc28j60.c |
$(CC) $(INCLUDES) $(CFLAGS) -c $< |
|
main.o: ../main.c |
$(CC) $(INCLUDES) $(CFLAGS) -c $< |
|
http.o: ../http.c |
$(CC) $(INCLUDES) $(CFLAGS) -c $< |
|
arp.o: ../arp.c |
$(CC) $(INCLUDES) $(CFLAGS) -c $< |
|
tcp.o: ../tcp.c |
$(CC) $(INCLUDES) $(CFLAGS) -c $< |
|
ip.o: ../ip.c |
$(CC) $(INCLUDES) $(CFLAGS) -c $< |
|
ethernet.o: ../ethernet.c |
$(CC) $(INCLUDES) $(CFLAGS) -c $< |
|
icmp.o: ../icmp.c |
$(CC) $(INCLUDES) $(CFLAGS) -c $< |
|
menu.o: ../menu.c |
$(CC) $(INCLUDES) $(CFLAGS) -c $< |
|
lcd.o: ../lcd.c |
$(CC) $(INCLUDES) $(CFLAGS) -c $< |
|
adc.o: ../adc.c |
$(CC) $(INCLUDES) $(CFLAGS) -c $< |
|
udp.o: ../udp.c |
$(CC) $(INCLUDES) $(CFLAGS) -c $< |
|
##Link |
$(TARGET): $(OBJECTS) |
$(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET) |
|
%.hex: $(TARGET) |
avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ |
|
%.eep: $(TARGET) |
-avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0 |
|
%.lss: $(TARGET) |
avr-objdump -h -S $< > $@ |
|
size: ${TARGET} |
@echo |
@avr-size -C --mcu=${MCU} ${TARGET} |
|
## Clean target |
.PHONY: clean |
clean: |
-rm -rf $(OBJECTS) avrnet.elf dep/* avrnet.hex avrnet.eep avrnet.lss avrnet.map |
|
|
## Other dependencies |
-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*) |
|
/apps/avr-webserver/menu.c
0,0 → 1,651
//******************************************************************************************** |
// |
// File : menu.c implement for User interface menu |
// |
//******************************************************************************************** |
// |
// Copyright (C) 2007 |
// |
// This program is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free Software |
// Foundation; either version 2 of the License, or (at your option) any later |
// version. |
// This program is distributed in the hope that it will be useful, but |
// |
// WITHOUT ANY WARRANTY; |
// |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License along with |
// this program; if not, write to the Free Software Foundation, Inc., 51 |
// Franklin St, Fifth Floor, Boston, MA 02110, USA |
// |
// http://www.gnu.de/gpl-ger.html |
// |
//******************************************************************************************** |
#include "includes.h" |
//******************************************************************************************* |
// |
// Global variable |
// |
//******************************************************************************************* |
BYTE menu_index, submenu_index; |
BYTE menu_stack, submenu_stack; |
BYTE setting_cursor; |
BYTE standby_cursor; |
BYTE sec_count; |
// max index for cursor setting |
prog_uint8_t setting_cursor_max[3] = { 4, 4, 4 }; |
// count down timer for send temp. H:M:S |
prog_uint8_t count_time_max[4] = { 2, 60, 60, 24 }; |
// countdown timer 4-bytes, [0]=en/dis, [1]=hour, [2]=min, [3]=sec |
BYTE count_time[4]; |
// count down time initial value stored in eeprom. Enable/Disable, Hour, Minute |
BYTE ee_count_time[3] EEMEM = { 0, 0, 1 }; |
prog_uint8_t str_enable[] = "Enable"; |
prog_uint8_t str_disable[] = "Disable"; |
|
// menu and standby display string |
PGM_P menu_list[5] = |
{ |
"Main menu", |
"AVR IP config", |
"Server IP config", |
"Send temp config", |
"Ping server" |
}; |
|
PGM_P standby_list[4] = |
{ |
"AVR IP", |
"Server IP", |
"Send temp in", |
"ADC0 & Temp" |
}; |
|
//***************************************************************************************** |
// |
// Function : my_memcpy |
// Description : copy string (end '\0') from program memory to ram and return pointer |
// to end of string |
// |
//***************************************************************************************** |
BYTE *my_strcpy ( BYTE *dest, PGM_P src ) |
{ |
BYTE ch; |
|
while ( (ch = pgm_read_byte( src++ )) ) |
{ |
*dest++ = ch; |
} |
return dest; |
} |
|
//***************************************************************************************** |
// |
// Function : print_decimal |
// Description : Print decimal to buffer, up to 5 digits |
// |
//***************************************************************************************** |
BYTE * print_decimal ( BYTE *ptr, BYTE digit, WORD dec ) |
{ |
if ( digit >= 5 ) |
*ptr++ = ( (dec/10000) + '0' ); |
if ( digit >= 4 ) |
*ptr++ = ( ((dec%10000)/1000) + '0' ); |
if ( digit >= 3 ) |
*ptr++ = ( ((dec%1000)/100) + '0' ); |
if ( digit >= 2 ) |
*ptr++ = ( ((dec%100)/10) + '0' ); |
*ptr++ = ( ((dec%10)) + '0' ); |
|
return ptr; |
} |
//***************************************************************************************** |
// |
// Function : print_temp |
// Description : Print ADC0 and temparature to buffer |
// |
//***************************************************************************************** |
void print_temp ( BYTE *dest ) |
{ |
WORD adc0_value; |
BYTE temp_value; |
|
adc0_value = adc_read ( 0 ); |
temp_value = adc_read_temp ( ); |
|
dest = print_decimal ( dest, 4, adc0_value ); |
*dest++ = ','; |
dest = print_decimal ( dest, 2, temp_value ); |
*dest++ = ASCII_DEGREE; |
*dest++ = 'C'; |
*dest = '\0'; |
} |
//***************************************************************************************** |
// |
// Function : print_ip |
// Description : Print ip address format to buffer e.g. 10.1.1.1 |
// |
//***************************************************************************************** |
void print_ip ( BYTE *ptr, BYTE *ip, BYTE cursor ) |
{ |
BYTE i, digit, temp; |
|
for ( i=0; i<4; i++ ) |
{ |
temp = ip [ i ]; |
if ( temp > 99 ) |
digit = 3; |
else if ( temp > 9 ) |
digit = 2; |
else |
digit = 1; |
|
if ( (i+1) == cursor ) |
{ |
*ptr = ASCII_CURSOR; |
ptr++; |
} |
else if ( i > 0 ) |
{ |
*ptr = '.'; |
ptr++; |
} |
ptr = print_decimal ( ptr, digit, temp ); |
|
} |
*ptr = '\0'; |
} |
//***************************************************************************************** |
// |
// Function : print_time |
// Description : Print time format to buffer e.g. 01:23:45 |
// |
//***************************************************************************************** |
void print_time ( BYTE *ptr, BYTE *time, BYTE cursor ) |
{ |
BYTE i; |
|
// show setting cursor when enter to setting mode |
if ( cursor == 0 ) |
{ |
if ( time [ 0 ] ) |
{ |
time++; |
for ( i=0; i<3; i++ ) |
{ |
if ( (i+2) == cursor ) |
{ |
*ptr++ = ASCII_CURSOR; |
} |
else if ( i > 0 ) |
{ |
*ptr++ = ':'; |
} |
ptr = print_decimal ( ptr, 2, *time++ ); |
} |
} |
else |
{ |
ptr = my_strcpy ( ptr, (PGM_P)str_disable ); |
} |
} |
else |
{ |
if ( cursor == 1 ) |
{ |
*ptr++ = ASCII_CURSOR; |
// show Enable/Disable send temparature to server |
if ( time [ 0 ] ) |
ptr = my_strcpy ( ptr, (PGM_P)str_enable ); |
else |
ptr = my_strcpy ( ptr, (PGM_P)str_disable ); |
} |
else |
{ |
time++; |
for ( i=0; i<3; i++ ) |
{ |
if ( (i+2) == cursor ) |
{ |
*ptr++ = ASCII_CURSOR; |
} |
else if ( i > 0 ) |
{ |
*ptr++ = ':'; |
} |
ptr = print_decimal ( ptr, 2, *time++ ); |
} |
} |
} |
|
*ptr = '\0'; |
} |
//***************************************************************************************** |
// |
// Function : time_base |
// Description : count-down timer for send temparature to server. you can enable/disable and |
// adjust timer by "Send temp config" menu. |
// |
//***************************************************************************************** |
void time_base ( void ) |
{ |
static BYTE send_temp_timeout=0; |
|
if ( ++sec_count == 250 ) |
{ |
sec_count = 0; |
|
// update lcd display |
flag1.bits.update_display = 1; |
|
// timeout for send temparature to webserver |
if ( flag1.bits.syn_is_sent ) |
{ |
// 5 seconds |
if ( ++send_temp_timeout == 5 ) |
{ |
send_temp_timeout = 0; |
flag1.bits.send_temp_timeout = 1; |
} |
} |
// send temparature to server countdown |
if ( count_time[ 0 ] && menu_index!=4 ) |
{ |
if ( --count_time[ 3 ] > 59 ) |
{ |
//count_time[ 3 ] = 59; |
count_time[ 3 ] = 20; // debug |
if ( --count_time[ 2 ] > 59 ) |
{ |
count_time[ 2 ] = 59; |
if ( --count_time[ 1 ] > 23 ) |
{ |
// read hour |
count_time[ 1 ] = eeprom_read_byte( ee_count_time + 1 ); |
// read minute |
count_time[ 2 ] = eeprom_read_byte( ee_count_time + 2 ); |
// clear second |
count_time[ 3 ] = 0; |
flag1.bits.send_temp = 1; |
} |
} |
} |
} |
} |
} |
//******************************************************************************************* |
// |
// Function : standby_display |
// Description : display board status such as AVR ip, server ip, countdown time, temparature |
// |
//******************************************************************************************* |
void standby_display ( void ) |
{ |
BYTE generic_buf[64]; |
|
// update lcd display flag not set, exit from function |
if ( flag1.bits.update_display == 0 ) |
return; |
flag1.bits.update_display = 0; |
// lcd display is displaying other information, wait until busy flag clear |
if ( flag1.bits.lcd_busy ) |
return; |
// now displaying menu information, wait until exit from menu |
if ( menu_index ) |
return; |
|
// display status on lcd line 1 |
lcd_putc ( '\f' ); |
lcd_print ( (BYTE*)standby_list[ standby_cursor - 1 ] ); |
|
// display status on lcd line 2 |
lcd_putc ( '\n' ); |
// display avr ip |
if ( standby_cursor == 1 ) |
{ |
print_ip ( generic_buf, (BYTE*)&avr_ip, 0 ); |
} |
// display server ip |
else if ( standby_cursor == 2 ) |
{ |
print_ip ( generic_buf, (BYTE*)&server_ip, 0 ); |
} |
// display countdown timer |
else if ( standby_cursor == 3 ) |
{ |
print_time ( generic_buf, count_time, 0 ); |
} |
// display current temparature |
else if ( standby_cursor == 4 ) |
{ |
print_temp ( generic_buf ); |
} |
lcd_print ( generic_buf ); |
} |
//******************************************************************************************* |
// |
// Function : display_menu |
// Description : display LCD user interface menu on LCD |
// |
//******************************************************************************************* |
void display_menu(void) |
{ |
BYTE generic_buf[64]; |
|
if( menu_index == 0) |
return; |
|
// display menu title on lcd first line |
lcd_putc( '\f' ); |
lcd_print ( (BYTE *)menu_list[ menu_index - 1 ] ); |
|
// display menu detail on lcd second line |
lcd_putc( '\n' ); |
if( menu_index == 1 )//MENU_MAIN) |
{ |
lcd_print( (BYTE *)menu_list[ submenu_index ] ); |
} |
// setup avr ip address |
else if( menu_index == 2 ) |
{ |
print_ip ( generic_buf, (BYTE*)&avr_ip, setting_cursor+1 ); |
lcd_print ( generic_buf ); |
} |
// setup server ip address |
else if(menu_index == 3 ) |
{ |
print_ip ( generic_buf, (BYTE*)&server_ip, setting_cursor+1 ); |
lcd_print ( generic_buf ); |
} |
// setup countdown timer for send temparature |
else if ( menu_index == 4 ) |
{ |
print_time ( generic_buf, count_time, setting_cursor+1 ); |
lcd_print ( generic_buf ); |
} |
// ping server |
else if ( menu_index == 5 ) |
{ |
print_ip ( generic_buf, (BYTE*)&server_ip, 1 ); |
lcd_print ( generic_buf ); |
} |
// send temparature now |
//else if ( menu_index == 6 ) |
//{ |
// lcd_put ( ASCII_CURSOR ); |
// lcd_print_p ( PSTR ( "OK" ) ); |
//} |
} |
//******************************************************************************************* |
// |
// Function : key_up_process |
// Description : |
// |
//******************************************************************************************* |
void key_up_process ( void ) |
{ |
BYTE temp; |
|
// standby display, display board status |
if(menu_index == 0) |
{ |
if ( ++ standby_cursor == ((sizeof(standby_list)/2)+1) ) |
standby_cursor = 1; |
flag1.bits.update_display = 1; |
} |
// main menu |
else if(menu_index == 1) |
{ |
if( ++submenu_index == (sizeof(menu_list)/2) ) |
{ |
submenu_index = 1; |
} |
} |
// setup avr ip |
else if( menu_index == 2 ) |
{ |
avr_ip.byte [ setting_cursor ]++; |
eeprom_write_block ( &avr_ip, ee_avr_ip, 4 ); |
} |
// setup server ip |
else if( menu_index == 3 ) |
{ |
server_ip.byte [ setting_cursor ]++; |
eeprom_write_block ( &server_ip, ee_server_ip, 4 ); |
} |
// setup countdown timer |
else if( menu_index == 4 ) |
{ |
temp = pgm_read_byte ( (PGM_P)(count_time_max + setting_cursor) ); |
if ( ++count_time [ setting_cursor ] == temp ) |
count_time [ setting_cursor ] = 0; |
eeprom_write_block ( count_time, ee_count_time, 4 ); |
} |
} |
//******************************************************************************************* |
// |
// Function : key_dw_process |
// Description : |
// |
//******************************************************************************************* |
void key_dw_process ( void ) |
{ |
BYTE temp; |
|
// standby display, display board status |
if(menu_index == 0) |
{ |
if ( -- standby_cursor == 0 ) |
standby_cursor = sizeof(standby_list)/2; |
flag1.bits.update_display = 1; |
} |
// main menu |
else if(menu_index == 1) |
{ |
if( --submenu_index == 0 ) |
{ |
submenu_index = (sizeof(menu_list)/2)-1; |
} |
} |
// setup avr ip |
else if( menu_index == 2 ) |
{ |
avr_ip.byte [ setting_cursor ]--; |
eeprom_write_block ( &avr_ip, ee_avr_ip, 4 ); |
} |
// setup server ip |
else if( menu_index == 3 ) |
{ |
server_ip.byte [ setting_cursor ]--; |
eeprom_write_block ( &server_ip, ee_server_ip, 4 ); |
} |
// setup countdown timer |
else if( menu_index == 4 ) |
{ |
temp = pgm_read_byte ( (PGM_P)(count_time_max + setting_cursor) ); |
if ( --count_time [ setting_cursor ] == 0xff ) |
count_time [ setting_cursor ] = temp; |
eeprom_write_block ( count_time, ee_count_time, 4 ); |
} |
} |
//******************************************************************************************* |
// |
// Function : key_process |
// Description : Process all key code from get_key_code function |
// |
//******************************************************************************************* |
void menu_process ( void ) |
{ |
static BYTE key_hold_count=0, key_hold_step_delay=0; |
BYTE rxtx_buffer[MAX_RXTX_BUFFER]; |
BYTE key_code, temp; |
static BYTE backlight_sec=31, backlight_seccount=250; |
|
// get switch value from port |
key_code = SW_PIN & ( _BV( SW_DW ) | _BV( SW_UP ) | _BV( SW_EXIT ) | _BV( SW_MENU ) ); |
|
// Check key press? |
if ( key_code == ( _BV( SW_DW ) | _BV( SW_UP ) | _BV( SW_EXIT ) | _BV( SW_MENU ) ) ) |
{ |
flag1.bits.key_is_executed = 0; |
flag2.bits.key_hold = 0; |
key_hold_count = 0; |
key_hold_step_delay = 0; |
|
// lcd backlight control |
// lcd backlight off after key is unpress ( 30 seconds) |
if ( backlight_sec ) |
{ |
if ( --backlight_seccount > 250 ) |
{ |
backlight_seccount = 250; |
if ( --backlight_sec == 1 ) |
{ |
backlight_sec = 0; |
// lcd backlight off |
LCD_BL_PORT &= ~_BV( LCD_BL_PIN ); |
} |
} |
} |
return; |
} |
|
// lcd backlight on |
// and hold-on 30 seconds |
backlight_sec = 31; |
LCD_BL_PORT |= _BV( LCD_BL_PIN ); |
|
// check hold key |
if ( ++key_hold_count == 200 ) |
{ |
key_hold_count = 0; |
flag2.bits.key_hold = 1; |
} |
|
if ( flag2.bits.key_hold ) |
{ |
if ( ++key_hold_step_delay == 30 ) |
{ |
key_hold_step_delay = 0; |
if ( key_code == ((~_BV ( SW_UP ) ) & 0xf0) ) |
{ |
key_up_process (); |
} |
// if down key is pressed |
else if ( key_code == ((~_BV ( SW_DW ) ) & 0xf0) ) |
{ |
key_dw_process (); |
} |
display_menu(); |
} |
} |
// key code already executed |
if ( flag1.bits.key_is_executed ) |
return; |
// check key code, what is key pressed? |
// if menu key is pressed |
if ( key_code == ((~_BV ( SW_MENU ) ) & 0xf0) ) |
{ |
// enter to main menu |
if( menu_index == 0 ) |
{ |
setting_cursor = 0; |
menu_index = 1; |
submenu_index = 1; |
} |
// enter to submenu |
else if( menu_index == 1 ) |
{ |
menu_stack = menu_index; |
submenu_stack = submenu_index; |
menu_index = submenu_index + menu_index; |
submenu_index = 1; |
} |
// ping server |
else if ( menu_index == 5 ) |
{ |
// Show on lcd first line |
lcd_putc( '\f' ); |
lcd_print ( (BYTE *)menu_list[ 4 ] ); |
lcd_putc( '\n' ); |
if ( icmp_ping ( (BYTE*)rxtx_buffer, (BYTE*)&server_mac, (BYTE*)&server_ip ) ) |
{ |
lcd_print_p ( PSTR ( "Ping OK." ) ); |
} |
else |
{ |
lcd_print_p ( PSTR ( "Not found." ) ); |
} |
flag1.bits.lcd_busy = 1; |
menu_index = 0; |
submenu_index = 0; |
flag1.bits.key_is_executed = 1; |
return; |
} |
// change cursor setting on each menu |
else |
{ |
temp = pgm_read_byte ( (PGM_P)(setting_cursor_max + menu_index - 2) ); |
|
if ( ++setting_cursor == temp ) |
setting_cursor = 0; |
} |
} |
// if exit key is pressed |
else if ( key_code == ((~_BV ( SW_EXIT ) ) & 0xf0) ) |
{ |
setting_cursor = 0; |
if(menu_index > 1) |
{ |
menu_index = menu_stack; |
submenu_index = submenu_stack; |
} |
else |
{ |
menu_index = 0; |
submenu_index = 0; |
|
} |
} |
// if up key is pressed |
else if ( key_code == ((~_BV ( SW_UP ) ) & 0xf0) ) |
{ |
key_up_process (); |
} |
// if down key is pressed |
else if ( key_code == ((~_BV ( SW_DW ) ) & 0xf0) ) |
{ |
key_dw_process (); |
} |
// display menu information on LCD |
display_menu(); |
flag1.bits.key_is_executed = 1; |
flag1.bits.lcd_busy = 0; |
} |
//******************************************************************************************* |
// |
// Function : menu_init |
// Description : initial I/O direction for all key, |
// initial timer1 for countdown timer |
// |
//******************************************************************************************* |
void menu_init ( void ) |
{ |
// setup countdown initial value |
sec_count = 0; |
eeprom_read_block ( count_time, ee_count_time, 3 ); |
count_time[3] = 0; |
|
// setup menu and standby display |
flag1.byte = 0; |
flag2.byte = 0; |
menu_index = 0; |
submenu_index = 0; |
menu_stack = 0; |
submenu_stack = 0; |
setting_cursor = 0; |
standby_cursor = 1; |
} |
/apps/avr-webserver/avrnet.aws
0,0 → 1,651
<AVRWorkspace><IOSettings><CurrentRegisters/></IOSettings><part name="ATMEGA32"/><Files><File00000 Name="D:\Work\AVR\avrnet-v1.0\enc28j60.c" Position="198 91 1053 577" LineCol="0 0" State="Maximized"/><File00001 Name="D:\Work\AVR\avrnet-v1.0\http.c" Position="186 64 1041 550" LineCol="0 0" State="Maximized"/><File00002 Name="D:\Work\AVR\avrnet-v1.0\tcp.c" Position="123 22 978 508" LineCol="0 0" State="Maximized"/><File00003 Name="D:\Work\AVR\avrnet-v1.0\menu.c" Position="159 46 1014 532" LineCol="0 0" State="Maximized"/><File00004 Name="D:\Work\AVR\avrnet-v1.0\lcd.c" Position="38 -73 725 256" LineCol="0 0" State="Maximized"/><File00005 Name="D:\Work\AVR\avrnet-v1.0\main.c" Position="195 70 1022 532" LineCol="288 0" State="Maximized"/><File00006 Name="D:\Work\AVR\avrnet-v1.0\arp.c" Position="117 18 972 504" LineCol="0 0" State="Maximized"/><File00007 Name="D:\Work\AVR\avrnet-v1.0\includes.h" Position="43 -90 870 396" LineCol="0 0" State="Maximized"/><File00008 Name="D:\Work\AVR\avrnet-v1.0\adc.c" Position="120 20 975 506" LineCol="0 0" State="Maximized"/><File00009 Name="D:\Work\AVR\avrnet-v1.0\ethernet.c" Position="60 -51 747 278" LineCol="0 0" State="Maximized"/><File00010 Name="D:\Work\AVR\avrnet-v1.0\icmp.c" Position="103 -10 958 476" LineCol="52 2" State="Maximized"/><File00011 Name="D:\Work\AVR\avrnet-v1.0\ip.c" Position="88 -60 915 426" LineCol="0 0" State="Maximized"/><File00012 Name="D:\Work\AVR\avrnet-v1.0\ip.h" Position="103 -50 958 436" LineCol="0 0" State="Maximized"/><File00013 Name="D:\Work\AVR\avrnet-v1.0\enc28j60.h" Position="52 -84 879 402" LineCol="0 0" State="Maximized"/><File00014 Name="D:\Work\AVR\avrnet-v1.0\ethernet.h" Position="59 -59 746 268" LineCol="0 0" State="Maximized"/><File00015 Name="D:\Work\AVR\avrnet-v1.0\arp.h" Position="84 -35 771 292" LineCol="0 0" State="Maximized"/><File00016 Name="D:\Work\AVR\avrnet-v1.0\menu.h" Position="171 54 1026 540" LineCol="0 0" State="Maximized"/><File00017 Name="D:\Work\AVR\avrnet-v1.0\adc.h" Position="55 -26 910 462" LineCol="0 0" State="Maximized"/><File00018 Name="D:\Work\AVR\avrnet-v1.0\icmp.h" Position="180 51 867 378" LineCol="0 0" State="Maximized"/><File00019 Name="D:\Work\AVR\avrnet-v1.0\http.h" Position="117 -13 804 314" LineCol="0 0" State="Maximized"/><File00020 Name="D:\Work\AVR\avrnet-v1.0\lcd.h" Position="162 48 1017 536" LineCol="0 0" State="Maximized"/><File00021 Name="D:\Work\AVR\avrnet-v1.0\struct.h" Position="169 73 884 400" LineCol="0 0" State="Maximized"/><File00022 Name="D:\Work\AVR\avrnet-v1.0\tcp.h" Position="180 60 1035 546" LineCol="0 0" State="Maximized"/><File00023 Name="D:\Work\AVR\avrnet-v1.0\udp.c" Position="170 72 1025 558" LineCol="34 2" State="Maximized"/><File00024 Name="D:\Work\AVR\avrnet-v1.0\udp.h" Position="183 62 1038 548" LineCol="23 33" State="Maximized"/></Files></AVRWorkspace> |
/apps/avr-webserver/lcd.h
0,0 → 1,59
//******************************************************************************************** |
// |
// File : lcd.h implement for 16x2 LCD module |
// |
//******************************************************************************************** |
// |
// Copyright (C) 2007 |
// |
// This program is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free Software |
// Foundation; either version 2 of the License, or (at your option) any later |
// version. |
// This program is distributed in the hope that it will be useful, but |
// |
// WITHOUT ANY WARRANTY; |
// |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License along with |
// this program; if not, write to the Free Software Foundation, Inc., 51 |
// Franklin St, Fifth Floor, Boston, MA 02110, USA |
// |
// http://www.gnu.de/gpl-ger.html |
// |
//******************************************************************************************** |
#define LCD_DATA_PORT PORTD |
#define LCD_DATA_DDR DDRD |
#define LCD_D7 PD7 |
#define LCD_D6 PD6 |
#define LCD_D5 PD5 |
#define LCD_D4 PD4 |
#define LCD_CONTROL_PORT PORTB |
#define LCD_CONTROL_DDR DDRB |
#define LCD_RS_PIN PB0 |
#define LCD_RW_PIN PB1 |
#define LCD_EN_PIN PB2 |
|
#define SET_FUNCTION 0x28 // 8bits, 2lines |
#define DISPLAY_ON 0x0C |
#define DISPLAY_CLR 0x01 |
#define ENTRY_MODE 0x06 // Entry = increase |
#define RETURN_HOME 0x02 |
#define CURSOR_BACK 0x10 |
#define SET_DDRAM 0x80 |
#define WRITE_DATA 1 |
#define WRITE_COMMAND 0 |
#define LCD_EN 0x80 |
#define LCD_LINE_TWO 0x40 |
//******************************************************************************************** |
// |
// Prototype function |
// |
//******************************************************************************************** |
extern void lcd_init(void); |
extern void lcd_gotoxy(unsigned char x,unsigned char y); |
extern void lcd_putc(unsigned char c); |
extern void lcd_print( unsigned char * ptr ); |
extern void lcd_print_p( PGM_P ptr ); |
/apps/avr-webserver/menu.h
0,0 → 1,92
//******************************************************************************************** |
// |
// File : menu.h implement for User interface menu |
// |
//******************************************************************************************** |
// |
// Copyright (C) 2007 |
// |
// This program is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free Software |
// Foundation; either version 2 of the License, or (at your option) any later |
// version. |
// This program is distributed in the hope that it will be useful, but |
// |
// WITHOUT ANY WARRANTY; |
// |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License along with |
// this program; if not, write to the Free Software Foundation, Inc., 51 |
// Franklin St, Fifth Floor, Boston, MA 02110, USA |
// |
// http://www.gnu.de/gpl-ger.html |
// |
//******************************************************************************************** |
#define SW_DW 7 |
#define SW_UP 6 |
#define SW_EXIT 5 |
#define SW_MENU 4 |
#define SW_DDR DDRA |
#define SW_PORT PORTA |
#define SW_PIN PINA |
#define LCD_BL_PIN PB3 |
#define LCD_BL_PORT PORTB |
#define LCD_BL_DDR DDRB |
|
//#define MENU_MAIN 1 |
//#define MENU_SET_AVR_IP 2 |
//#define MENU_SET_SERVER_IP 3 |
//#define MENU_SET_COUNT_TIME 4 |
//#define MENU_PING_SERVER 5 |
//#define MENU_SEND_TEMP 6 |
|
#define SUBMENU_SET_AVR_IP 1 |
#define SUBMENU_SET_SERVER_IP 2 |
#define SUBMENU_SET_COUNT_TIME 3 |
#define SUBMENU_PING_SERVER 4 |
#define SUBMENU_SEND_TEMP 6 |
|
#define CURSOR_SET_AVR_IP1 0 |
#define CURSOR_SET_AVR_IP2 1 |
#define CURSOR_SET_AVR_IP3 2 |
#define CURSOR_SET_AVR_IP4 3 |
|
#define CURSOR_SET_SERVER_IP1 0 |
#define CURSOR_SET_SERVER_IP2 1 |
#define CURSOR_SET_SERVER_IP3 2 |
#define CURSOR_SET_SERVER_IP4 3 |
|
#define CURSOR_SET_COUNT_TIME1 0 |
#define CURSOR_SET_COUNT_TIME2 1 |
#define CURSOR_SET_COUNT_TIME3 2 |
#define CURSOR_SET_COUNT_TIME4 3 |
|
//#define STANDBY_CURSOR_AVR_IP 1 |
//#define STANDBY_CURSOR_SERVER_IP 2 |
//#define STANDBY_CURSOR_COUNT_DOWN 3 |
//#define STANDBY_CURSOR_TEMP 4 |
|
#define ASCII_CURSOR 0x7E |
|
#include <avr/eeprom.h> |
|
extern BYTE standby_cursor; |
extern BYTE ee_count_time[] EEMEM; |
extern BYTE count_time[]; |
|
//******************************************************************************************** |
// |
// Prototype function |
// |
//******************************************************************************************** |
extern void menu_process ( void ); |
extern void menu_init ( void ); |
extern void standby_display ( void ); |
extern void time_base ( void ); |
extern void print_ip ( BYTE *ptr, BYTE *ip, BYTE cursor ); |
extern void print_time ( BYTE *ptr, BYTE *time, BYTE cursor ); |
extern BYTE *print_decimal ( BYTE *ptr, BYTE digit, WORD dec ); |
extern void key_up_process ( void ); |
extern void key_dw_process ( void ); |
/apps/avr-webserver/ReadmeTH.html
0,0 → 1,88
<html> |
<head> |
<title>AVRnet V0.9 by avrportal.com</title> |
<meta http-equiv="Content-Type" content="text/html; charset=tis-620" /> |
</head> |
<body> |
<font color=blue><b>AVRnet V1.0 by <a href="http://www.avrportal.com/">avrportal.com</a></b></font><br> |
|
|
|
|
|
|
<br> |
|
<img src="AVRnetCPannel.gif"><br> |
<br> |
|
<a href="http://www.avrportal.com/avrnet/avrnet-v1.0-20070625.7z">AVRnet V1.0 source code</a><br> |
<a href="http://www.avrportal.com/avrnet/avrnet-cpannel-src.7z">AVRnet CPannel source code</a><br> |
<a href="http://www.avrportal.com/avrnet/avrnet-cpannel-bin.7z">AVRnet CPannel binary</a><br> |
|
<hr align="left" width="700" size="5"> |
<br> |
<font color=blue><b>AVRnet V0.9 by <a href="http://www.avrportal.com/">avrportal.com</a></b></font><br> |
<br> |
AVRnet Firmware Version 0.9<br> |
<br> |
|
|
|
|
|
|
|
|
<br> |
<hr align="left" width="600" size="1"> |
<br> |
<font color=blue><b>Hardware feature</b></font><br> |
<br> |
- MCU : ATMEGA32 @ 16MHz<br> |
- Ethernet controller : ENC28J60<br> |
- RJ11 for LAN<br> |
- LCD user interface menu<br> |
- JTAG interface for program and debug<br> |
- Temparature sensor using thermistor<br> |
- 1 potentiometer for ADC0<br> |
- I2C connector with pull-up resistor<br> |
- Built-in Voltage regulator<br> |
- LEDs display and switchs for LCD menu<br> |
<br> |
<hr align="left" width="600" size="1"><br> |
<font color=blue><b>Firmware feature</b></font><br> |
<br> |
- Firmware is GPL using AVR GCC compiler<br> |
- LCD user interface menu and borad status<br> |
- Webserver listen on port 80 ( example page "webpage.htm" )<br> |
- Webclient listen on port 1200 ( use for send temparature to webserver.)<br> |
<br> |
<hr align="left" width="600" size="1"><br> |
<font color=blue><b>LCD user interface menu</b></font><br><br> |
|
|
<br> |
Main menu<br> |
<ul> |
<li>AVR IP config (setup AVRnet IP address)</li> |
<li>Server IP config (setup AVRnet IP address)</li> |
<li>Send temp config (setup countdown timer for send temparature to webserver)</li> |
<li>Ping server (check server status)</li> |
</ul> |
|
|
|
|
|
|
standby display mode<br> |
<ul> |
<li>AVR IP(show current AVR IP address)</li> |
<li>Server IP (show current server IP address)</li> |
<li>Send temp in (show countdown timer for send temp)</li> |
<li>ADC0 & Temp (show current ADC0 and temparature)</li> |
</ul> |
<hr align="left" width="600" size="1"> |
</body> |
</html> |
/apps/avr-webserver/includes.h
0,0 → 1,82
//******************************************************************************************** |
// |
// File : include.h includes all header file for AVRethernet development board. |
// |
//******************************************************************************************** |
// |
// Copyright (C) 2007 |
// |
// This program is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free Software |
// Foundation; either version 2 of the License, or (at your option) any later |
// version. |
// This program is distributed in the hope that it will be useful, but |
// |
// WITHOUT ANY WARRANTY; |
// |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License along with |
// this program; if not, write to the Free Software Foundation, Inc., 51 |
// Franklin St, Fifth Floor, Boston, MA 02110, USA |
// |
// http://www.gnu.de/gpl-ger.html |
// |
//******************************************************************************************** |
#include <avr/io.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <util/delay.h> |
#include <avr/pgmspace.h> |
#include <avr/eeprom.h> |
|
// struct.h MUST be include first |
#include "struct.h" |
#include "enc28j60.h" |
#include "ethernet.h" |
#include "ip.h" |
#include "tcp.h" |
#include "icmp.h" |
#include "arp.h" |
#include "udp.h" |
#include "http.h" |
#include "lcd.h" |
#include "menu.h" |
#include "adc.h" |
|
// define I/O interface |
|
#define LED_PIN1_DDR DDC6 |
#define LED_PIN1 PC6 |
#define LED_PIN2_DDR DDC7 |
#define LED_PIN2 PC7 |
#define LED_PORT PORTC |
#define LED_DDR DDRC |
|
#define LOW(uint) (uint&0xFF) |
#define HIGH(uint) ((uint>>8)&0xFF) |
|
#define MAX_RXTX_BUFFER 1518 |
|
// global variables |
extern MAC_ADDR avr_mac; |
extern IP_ADDR avr_ip; |
|
//extern MAC_ADDR client_mac; |
//extern IP_ADDR client_ip; |
|
extern MAC_ADDR server_mac; |
extern IP_ADDR server_ip; |
|
extern BYTE generic_buf[]; |
extern BYTE ee_avr_ip[]; |
extern BYTE ee_server_ip[]; |
//******************************************************************************************** |
// |
// Prototype function from main.c |
// |
//******************************************************************************************** |
extern void initial_system( void ); |
|
/apps/avr-webserver/ethernet.c
0,0 → 1,119
//******************************************************************************************** |
// |
// File : ethernet.c implement for Ethernet Protocol |
// |
//******************************************************************************************** |
// |
// Copyright (C) 2007 |
// |
// This program is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free Software |
// Foundation; either version 2 of the License, or (at your option) any later |
// version. |
// This program is distributed in the hope that it will be useful, but |
// |
// WITHOUT ANY WARRANTY; |
// |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License along with |
// this program; if not, write to the Free Software Foundation, Inc., 51 |
// Franklin St, Fifth Floor, Boston, MA 02110, USA |
// |
// http://www.gnu.de/gpl-ger.html |
// |
//******************************************************************************************** |
#include "includes.h" |
//******************************************************************************************** |
// |
// Ethernet is a large, diverse family of frame-based computer networking technologies |
// that operates at many speeds for local area networks (LANs). |
// The name comes from the physical concept of the ether. |
// It defines a number of wiring and signaling standards for the physical layer, |
// through means of network access at the Media Access Control (MAC)/Data Link Layer, |
// and a common addressing format. |
// |
// Ethernet has been standardized as IEEE 802.3. |
// The combination of the twisted pair versions of ethernet for connecting end systems to |
// the network with the fiber optic versions for site backbones |
// become the most widespread wired LAN technology in use from the 1990s to the present, |
// largely replacing competing LAN standards such as coaxial cable Ethernet, |
// token ring, FDDI, and ARCNET. In recent years, Wi-Fi, |
// the wireless LAN standardized by IEEE 802.11, |
// has been used instead of Ethernet for many home and small office networks |
// and in addition to Ethernet in larger installations. |
// |
// |
//******************************************************************************************** |
|
//******************************************************************************************** |
// |
// Function : eth_generate_header |
// Description : generarete ethernet header, contain destination and source MAC address, |
// ethernet type. |
// |
//******************************************************************************************** |
void eth_generate_header ( BYTE *rxtx_buffer, WORD_BYTES type, BYTE *dest_mac ) |
{ |
BYTE i; |
//copy the destination mac from the source and fill my mac into src |
for ( i=0; i<sizeof(MAC_ADDR); i++) |
{ |
rxtx_buffer[ ETH_DST_MAC_P + i ] = dest_mac[i]; |
rxtx_buffer[ ETH_SRC_MAC_P + i ] = avr_mac.byte[i]; |
} |
rxtx_buffer[ ETH_TYPE_H_P ] = type.byte.high;//HIGH(type); |
rxtx_buffer[ ETH_TYPE_L_P ] = type.byte.low;//LOW(type); |
} |
//******************************************************************************************** |
// |
// Function : software_checksum |
// Description : |
// The Ip checksum is calculated over the ip header only starting |
// with the header length field and a total length of 20 bytes |
// unitl ip.dst |
// You must set the IP checksum field to zero before you start |
// the calculation. |
// len for ip is 20. |
// |
// For UDP/TCP we do not make up the required pseudo header. Instead we |
// use the ip.src and ip.dst fields of the real packet: |
// The udp checksum calculation starts with the ip.src field |
// Ip.src=4bytes,Ip.dst=4 bytes,Udp header=8bytes + data length=16+len |
// In other words the len here is 8 + length over which you actually |
// want to calculate the checksum. |
// You must set the checksum field to zero before you start |
// the calculation. |
// len for udp is: 8 + 8 + data length |
// len for tcp is: 4+4 + 20 + option len + data length |
// |
// For more information on how this algorithm works see: |
// http://www.netfor2.com/checksum.html |
// http://www.msc.uky.edu/ken/cs471/notes/chap3.htm |
// The RFC has also a C code example: http://www.faqs.org/rfcs/rfc1071.html |
// |
//******************************************************************************************** |
WORD software_checksum(BYTE *rxtx_buffer, WORD len, DWORD sum) |
{ |
// build the sum of 16bit words |
while(len>1) |
{ |
sum += 0xFFFF & (*rxtx_buffer<<8|*(rxtx_buffer+1)); |
rxtx_buffer+=2; |
len-=2; |
} |
// if there is a byte left then add it (padded with zero) |
if (len) |
{ |
sum += (0xFF & *rxtx_buffer)<<8; |
} |
// now calculate the sum over the bytes in the sum |
// until the result is only 16bit long |
while (sum>>16) |
{ |
sum = (sum & 0xFFFF)+(sum >> 16); |
} |
// build 1's complement: |
return( (WORD) sum ^ 0xFFFF); |
} |
/apps/avr-webserver/ethernet.h
0,0 → 1,47
//******************************************************************************************** |
// |
// File : ethernet.h implement for Ethernet Protocol |
// |
//******************************************************************************************** |
// |
// Copyright (C) 2007 |
// |
// This program is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free Software |
// Foundation; either version 2 of the License, or (at your option) any later |
// version. |
// This program is distributed in the hope that it will be useful, but |
// |
// WITHOUT ANY WARRANTY; |
// |
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
// PURPOSE. See the GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License along with |
// this program; if not, write to the Free Software Foundation, Inc., 51 |
// Franklin St, Fifth Floor, Boston, MA 02110, USA |
// |
// http://www.gnu.de/gpl-ger.html |
// |
//******************************************************************************************** |
#define ETH_TYPE_ARP_V 0x0806 |
#define ETH_TYPE_ARP_H_V 0x08 |
#define ETH_TYPE_ARP_L_V 0x06 |
#define ETH_TYPE_IP_V 0x0800 |
#define ETH_TYPE_IP_H_V 0x08 |
#define ETH_TYPE_IP_L_V 0x00 |
|
#define ETH_HEADER_LEN 14 |
|
#define ETH_DST_MAC_P 0 |
#define ETH_SRC_MAC_P 6 |
#define ETH_TYPE_H_P 12 |
#define ETH_TYPE_L_P 13 |
//******************************************************************************************** |
// |
// Prototype function |
// |
//******************************************************************************************** |
//void eth_generate_packet ( ETH_HEADER eth_header ); |
extern WORD software_checksum( BYTE *rxtx_buffer, WORD len, DWORD sum); |
extern void eth_generate_header ( BYTE *rxtx_buffer, WORD_BYTES type, BYTE *dest_mac ); |
/apps/avr-webserver/AVRnetCPannel.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
apps/avr-webserver/AVRnetCPannel.gif
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: apps/avr-webserver/main.c
===================================================================
--- apps/avr-webserver/main.c (nonexistent)
+++ apps/avr-webserver/main.c (revision 42)
@@ -0,0 +1,360 @@
+//********************************************************************************************
+//
+// AVRnet firmware Version 1.0
+//
+// MCU : ATMEGA32 @ 16MHz
+// Ethernet controller : ENC28J60
+// IDE & Compiler : AVR Studio version 4.13.528 & WINAVR version 20070122
+// Author : Jirawat Kongkaen
+// Website : http://www.avrportal.com/
+//
+//********************************************************************************************
+//
+// File : main.c main program for AVRnet development board.
+//
+//********************************************************************************************
+//
+// Copyright (C) 2007
+//
+// This program is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free Software
+// Foundation; either version 2 of the License, or (at your option) any later
+// version.
+// This program is distributed in the hope that it will be useful, but
+//
+// WITHOUT ANY WARRANTY;
+//
+// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program; if not, write to the Free Software Foundation, Inc., 51
+// Franklin St, Fifth Floor, Boston, MA 02110, USA
+//
+// http://www.gnu.de/gpl-ger.html
+//
+//********************************************************************************************
+#include "includes.h"
+
+// Global variables
+MAC_ADDR avr_mac;
+IP_ADDR avr_ip;
+
+MAC_ADDR server_mac;
+IP_ADDR server_ip;
+
+//BYTE generic_buf[128];
+
+// Change your avr and server ip address here
+// avr and server ip address are stored in eeprom
+BYTE ee_avr_ip[4] EEMEM = { 10, 1, 1, 1 };
+BYTE ee_server_ip[4] EEMEM = { 10, 1, 1, 76 };
+//*****************************************************************************************
+//
+// Function : server_process
+// Description : Run web server and listen on port 80
+//
+//*****************************************************************************************
+void server_process ( void )
+{
+ MAC_ADDR client_mac;
+ IP_ADDR client_ip;
+ // you can change rx,tx buffer size in includes.h
+ BYTE rxtx_buffer[MAX_RXTX_BUFFER];
+ WORD plen;
+
+ if ( flag1.bits.syn_is_sent )
+ return;
+ // get new packet
+ plen = enc28j60_packet_receive( (BYTE*)&rxtx_buffer, MAX_RXTX_BUFFER );
+
+ //plen will ne unequal to zero if there is a valid packet (without crc error)
+ if(plen==0)
+ return;
+
+ // copy client mac address from buffer to client mac variable
+ memcpy ( (BYTE*)&client_mac, &rxtx_buffer[ ETH_SRC_MAC_P ], sizeof(MAC_ADDR) );
+
+ // check arp packet if match with avr ip let's send reply
+ if ( arp_packet_is_arp( rxtx_buffer, (WORD_BYTES){ARP_OPCODE_REQUEST_V} ) )
+ {
+ arp_send_reply ( (BYTE*)&rxtx_buffer, (BYTE*)&client_mac );
+ return;
+ }
+
+ // get client ip address
+ memcpy ( (BYTE*)&client_ip, &rxtx_buffer[ IP_SRC_IP_P ], sizeof(IP_ADDR) );
+ // check ip packet send to avr or not?
+ if ( ip_packet_is_ip ( (BYTE*)&rxtx_buffer ) == 0 )
+ {
+ return;
+ }
+
+ // check ICMP packet, if packet is icmp packet let's send icmp echo reply
+ if ( icmp_send_reply ( (BYTE*)&rxtx_buffer, (BYTE*)&client_mac, (BYTE*)&client_ip ) )
+ {
+ return;
+ }
+
+ // check UDP packet
+ if (udp_receive ( (BYTE *)&rxtx_buffer, (BYTE *)&client_mac, (BYTE *)&client_ip ))
+ {
+ return;
+ }
+
+ // tcp start here
+ // start web server at port 80, see http.c
+ http_webserver_process ( (BYTE*)rxtx_buffer, (BYTE*)&client_mac, (BYTE*)&client_ip );
+}
+//*****************************************************************************************
+//
+// Function : client_process
+// Description : send temparature to web server, this option is disabled by default.
+// YOU MUST install webserver and server script before enable this option,
+// I recommented Apache webserver and PHP script.
+// More detail about Apache and PHP installation please visit http://www.avrportal.com/
+//
+//*****************************************************************************************
+void client_process ( void )
+{
+ WORD dlength;
+ // you can change rx,tx buffer size in includes.h
+ BYTE rxtx_buffer[MAX_RXTX_BUFFER];
+
+ // wait for send temparature flag is set, this flag set by time_base function (menu.c)
+ if ( flag1.bits.send_temp == 0 )
+ return;
+ // AVR busy now and wait untill transfer data to web browser completed.
+ if ( flag1.bits.syn_is_received )
+ return;
+ // AVR sent temparature to web server but not found web server on port 80
+ //if ( flag1.bits.not_found_server )
+ // return;
+ // send SYN to initial connection
+ if ( flag1.bits.syn_is_sent == 0 )
+ {
+ // start arp
+ // server ip was not found on network
+ if ( arp_who_is ( rxtx_buffer, (BYTE*)&server_mac, (BYTE*)&server_ip ) == 0 )
+ {
+ flag1.bits.send_temp = 0;
+ return;
+ }
+
+ // send SYN packet to initial connection
+ tcp_send_packet (
+ rxtx_buffer,
+ (WORD_BYTES){80}, // destination port
+ (WORD_BYTES){1200}, // source port
+ TCP_FLAG_SYN_V, // flag
+ 1, // (bool)maximum segment size
+ 1, // (bool)clear sequence ack number
+ 0, // 0=use old seq, seqack : 1=new seq,seqack no data : new seq,seqack with data
+ 0, // tcp data length
+ (BYTE*)&server_mac, // server mac address
+ (BYTE*)&server_ip ); // server ip address
+ flag1.bits.syn_is_sent = 1;
+ }
+ // get new packet
+ dlength = enc28j60_packet_receive( (BYTE*)&rxtx_buffer, MAX_RXTX_BUFFER );
+
+ // no new packet incoming
+ if ( dlength == 0 )
+ {
+ // timeout occured, when SYN has been sent but no response from web server
+ // reset send_temp and syn_is_sent flags
+ if ( flag1.bits.send_temp_timeout )
+ {
+ flag1.bits.send_temp_timeout = 0;
+ flag1.bits.send_temp = 0;
+ flag1.bits.syn_is_sent = 0;
+ }
+ return;
+ }
+
+ // check ip packet send to avr or not?
+ // accept ip packet only
+ if ( ip_packet_is_ip ( (BYTE*)&rxtx_buffer ) == 0 )
+ {
+ return;
+ }
+
+ // check SYNACK flag, after AVR send SYN server response by send SYNACK to AVR
+ if ( rxtx_buffer [ TCP_FLAGS_P ] == ( TCP_FLAG_SYN_V | TCP_FLAG_ACK_V ) )
+ {
+ // send ACK to answer SYNACK
+ tcp_send_packet (
+ (BYTE*)&rxtx_buffer,
+ (WORD_BYTES){80}, // destination port
+ (WORD_BYTES){1200}, // source port
+ TCP_FLAG_ACK_V, // flag
+ 0, // (bool)maximum segment size
+ 0, // (bool)clear sequence ack number
+ 1, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data
+ 0, // tcp data length
+ (BYTE*)&server_mac, // server mac address
+ (BYTE*)&server_ip ); // server ip address
+ // setup http request to server
+ dlength = http_put_request( (BYTE*)&rxtx_buffer );
+ // send http request packet
+ // send packet with PSHACK
+ tcp_send_packet (
+ (BYTE*)&rxtx_buffer,
+ (WORD_BYTES){80}, // destination port
+ (WORD_BYTES){1200}, // source port
+ TCP_FLAG_ACK_V | TCP_FLAG_PSH_V, // flag
+ 0, // (bool)maximum segment size
+ 0, // (bool)clear sequence ack number
+ 0, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data
+ dlength, // tcp data length
+ (BYTE*)&server_mac, // server mac address
+ (BYTE*)&server_ip ); // server ip address
+ return;
+ }
+ // after AVR send http request to server, server response by send data with PSHACK to AVR
+ // AVR answer by send ACK and FINACK to server
+ if ( rxtx_buffer [ TCP_FLAGS_P ] == (TCP_FLAG_ACK_V|TCP_FLAG_PSH_V) )
+ {
+ dlength = tcp_get_dlength( (BYTE*)&rxtx_buffer );
+
+ // send ACK to answer PSHACK from server
+ tcp_send_packet (
+ (BYTE*)&rxtx_buffer,
+ (WORD_BYTES){80}, // destination port
+ (WORD_BYTES){1200}, // source port
+ TCP_FLAG_ACK_V, // flag
+ 0, // (bool)maximum segment size
+ 0, // (bool)clear sequence ack number
+ dlength, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data
+ 0, // tcp data length
+ (BYTE*)&server_mac, // server mac address
+ (BYTE*)&server_ip ); // server ip address
+ // send finack to disconnect from web server
+
+ tcp_send_packet (
+ (BYTE*)&rxtx_buffer,
+ (WORD_BYTES){80}, // destination port
+ (WORD_BYTES){1200}, // source port
+ TCP_FLAG_FIN_V|TCP_FLAG_ACK_V, // flag
+ 0, // (bool)maximum segment size
+ 0, // (bool)clear sequence ack number
+ 0, // (bool)calculate new seq and seqack number
+ 0, // tcp data length
+ (BYTE*)&server_mac, // server mac address
+ (BYTE*)&server_ip ); // server ip address
+ return;
+ //menu_flag.bits.send_temp = 0;
+ //send_syn = 0;
+ }
+ // answer FINACK from web server by send ACK to web server
+ if ( rxtx_buffer [ TCP_FLAGS_P ] == (TCP_FLAG_FIN_V|TCP_FLAG_ACK_V) )
+ {
+ // send ACK with seqack = 1
+ tcp_send_packet (
+ (BYTE*)&rxtx_buffer,
+ (WORD_BYTES){80}, // destination port
+ (WORD_BYTES){1200}, // source port
+ TCP_FLAG_ACK_V, // flag
+ 0, // (bool)maximum segment size
+ 0, // (bool)clear sequence ack number
+ 1, // 0=use old seq, seqack : 1=new seq,seqack no data : >1 new seq,seqack with data
+ 0, // tcp data length
+ (BYTE*)&server_mac, // server mac address
+ (BYTE*)&server_ip ); // server ip address
+ // temparature has been sent
+ // and wait for next schedule to send temparature
+ flag1.bits.send_temp = 0;
+ flag1.bits.syn_is_sent = 0;
+ }
+}
+//*****************************************************************************************
+//
+// Function : main
+// Description : main program,
+//
+//*****************************************************************************************
+void lcd_backlight( void )
+{
+
+
+
+}
+//*****************************************************************************************
+//
+// Function : main
+// Description : main program,
+//
+//*****************************************************************************************
+int main (void)
+{
+ // change your mac address here
+ avr_mac.byte[0] = 'A';
+ avr_mac.byte[1] = 'V';
+ avr_mac.byte[2] = 'R';
+ avr_mac.byte[3] = 'P';
+ avr_mac.byte[4] = 'O';
+ avr_mac.byte[5] = 'R';
+
+ // read avr and server ip from eeprom
+ eeprom_read_block ( &avr_ip, ee_avr_ip, 4 );
+ eeprom_read_block ( &server_ip, ee_server_ip, 4 );
+
+ // setup port as input and enable pull-up
+ SW_DDR &= ~ ( _BV( SW_MENU ) | _BV( SW_EXIT ) | _BV( SW_UP ) | _BV( SW_DW ) );
+ SW_PORT |= _BV( SW_MENU ) | _BV( SW_EXIT ) | _BV( SW_UP ) | _BV( SW_DW );
+ SFIOR &= ~_BV( PUD );
+
+ // setup lcd backlight as output
+ LCD_BL_DDR |= _BV( LCD_BL_PIN );
+ // lcd backlight on
+ LCD_BL_PORT |= _BV( LCD_BL_PIN );
+
+ // setup clock for timer1
+ TCCR1B = 0x01; // clk/1 no prescaling
+
+ // initial adc, lcd, and menu
+ adc_init();
+ lcd_init ();
+ menu_init ();
+
+ // set LED1, LED2 as output */
+ LED_DDR |= _BV( LED_PIN1_DDR ) | _BV( LED_PIN2_DDR );
+ // set LED pin to "1" ( LED1,LED2 off)
+ LED_PORT |= _BV( LED_PIN1 ) | _BV( LED_PIN2 );
+
+ // initial enc28j60
+ enc28j60_init( (BYTE*)&avr_mac );
+
+ // loop forever
+ for(;;)
+ {
+ // wait until timer1 overflow
+ while ( (TIFR & _BV ( TOV1 )) == 0 );
+ TIFR |= _BV(TOV1);
+ TCNT1 = 1536; // Timer1 overflow every 1/16MHz * ( 65536 - 1536 ) = 4ms, 250Hz
+
+ // general time base, generate by timer1
+ // overflow every 1/250 seconds
+ time_base ();
+
+ // read temparature
+ adc_read_temp();
+
+ // server process response for arp, icmp, http
+ server_process ();
+
+ // send temparature to web server unsing http protocol
+ // disable by default.
+ client_process ();
+
+ // lcd user interface menu
+ // setup IP address, countdown timer
+ menu_process ();
+
+ // display AVR ethernet status
+ // temparature, AVR ip, server ip, countdown time
+ standby_display ();
+ }
+
+ return 0;
+}
Index: apps/avr-webserver/avrnet.pnproj
===================================================================
--- apps/avr-webserver/avrnet.pnproj (nonexistent)
+++ apps/avr-webserver/avrnet.pnproj (revision 42)
@@ -0,0 +1 @@
+
\ No newline at end of file
Index: apps/avr-webserver/tcp.c
===================================================================
--- apps/avr-webserver/tcp.c (nonexistent)
+++ apps/avr-webserver/tcp.c (revision 42)
@@ -0,0 +1,246 @@
+//********************************************************************************************
+//
+// File : tcp.c implement for Transmission Control Protocol
+//
+//********************************************************************************************
+//
+// Copyright (C) 2007
+//
+// This program is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free Software
+// Foundation; either version 2 of the License, or (at your option) any later
+// version.
+// This program is distributed in the hope that it will be useful, but
+//
+// WITHOUT ANY WARRANTY;
+//
+// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program; if not, write to the Free Software Foundation, Inc., 51
+// Franklin St, Fifth Floor, Boston, MA 02110, USA
+//
+// http://www.gnu.de/gpl-ger.html
+//
+//********************************************************************************************
+#include "includes.h"
+//********************************************************************************************
+//
+// +------------+-----------+------------+----------+
+// + MAC header + IP header + TCP header + Data ::: +
+// +------------+-----------+------------+----------+
+//
+// TCP Header
+//
+// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+// +00+01+02+03+04+05+06+07+08+09+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+
+// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+// + Source Port + Destination Port +
+// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+// + Sequence Number +
+// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+// + Acknowledgment Number +
+// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+// +Data Offset+reserved+ ECN + Control Bits + Window size +
+// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+// + Checksum + Urgent Pointer +
+// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+// + Options and padding ::: +
+// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+// + Data ::: +
+// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+//
+//********************************************************************************************
+
+// global variables ***********************************************************************
+static BYTE seqnum=0xa; // my initial tcp sequence number
+//static DWORD_BYTES tcp_sequence_number;
+
+//*****************************************************************************************
+//
+// Function : tcp_get_dlength
+// Description : claculate tcp received data length
+//
+//*****************************************************************************************
+WORD tcp_get_dlength ( BYTE *rxtx_buffer )
+{
+ int dlength, hlength;
+
+ dlength = ( rxtx_buffer[ IP_TOTLEN_H_P ] <<8 ) | ( rxtx_buffer[ IP_TOTLEN_L_P ] );
+ dlength -= sizeof(IP_HEADER);
+ hlength = (rxtx_buffer[ TCP_HEADER_LEN_P ]>>4) * 4; // generate len in bytes;
+ dlength -= hlength;
+ if ( dlength <= 0 )
+ dlength=0;
+
+ return ((WORD)dlength);
+}
+//*****************************************************************************************
+//
+// Function : tcp_get_hlength
+// Description : claculate tcp received header length
+//
+//*****************************************************************************************
+BYTE tcp_get_hlength ( BYTE *rxtx_buffer )
+{
+ return ((rxtx_buffer[ TCP_HEADER_LEN_P ]>>4) * 4); // generate len in bytes;
+}
+//********************************************************************************************
+//
+// Function : tcp_puts_data_p
+// Description : puts data from program memory to tx buffer
+//
+//********************************************************************************************
+WORD tcp_puts_data_p ( BYTE *rxtx_buffer, PGM_P data, WORD offset )
+{
+ BYTE ch;
+
+ while( (ch = pgm_read_byte(data++)) )
+ {
+ rxtx_buffer[ TCP_DATA_P + offset ] = ch;
+ offset++;
+ }
+
+ return offset;
+}
+//********************************************************************************************
+//
+// Function : tcp_puts_data
+// Description : puts data from RAM to tx buffer
+//
+//********************************************************************************************
+WORD tcp_puts_data ( BYTE *rxtx_buffer, BYTE *data, WORD offset )
+{
+ while( *data )
+ {
+ rxtx_buffer[ TCP_DATA_P + offset ] = *data++;
+ offset++;
+ }
+
+ return offset;
+}
+//********************************************************************************************
+//
+// Function : tcp_send_packet
+// Description : send tcp packet to network.
+//
+//********************************************************************************************
+void tcp_send_packet (
+ BYTE *rxtx_buffer,
+ WORD_BYTES dest_port,
+ WORD_BYTES src_port,
+ BYTE flags,
+ BYTE max_segment_size,
+ BYTE clear_seqack,
+ WORD next_ack_num,
+ WORD dlength,
+ BYTE *dest_mac,
+ BYTE *dest_ip )
+{
+ BYTE i, tseq;
+ WORD_BYTES ck;
+
+ // generate ethernet header
+ eth_generate_header ( rxtx_buffer, (WORD_BYTES){ETH_TYPE_IP_V}, dest_mac );
+
+ // sequence numbers:
+ // add the rel ack num to SEQACK
+ if ( next_ack_num )
+ {
+ for( i=4; i>0; i-- )
+ {
+ next_ack_num = rxtx_buffer [ TCP_SEQ_P + i - 1] + next_ack_num;
+ tseq = rxtx_buffer [ TCP_SEQACK_P + i - 1];
+ rxtx_buffer [ TCP_SEQACK_P + i - 1] = 0xff & next_ack_num;
+
+ // copy the acknum sent to us into the sequence number
+ rxtx_buffer[ TCP_SEQ_P + i - 1 ] = tseq;
+
+ next_ack_num >>= 8;
+ }
+ }
+
+ // initial tcp sequence number
+ // setup maximum segment size
+ // require to setup first packet is receive or transmit only
+ if ( max_segment_size )
+ {
+ // initial sequence number
+ rxtx_buffer[ TCP_SEQ_P + 0 ] = 0;
+ rxtx_buffer[ TCP_SEQ_P + 1 ] = 0;
+ rxtx_buffer[ TCP_SEQ_P + 2 ] = seqnum;
+ rxtx_buffer[ TCP_SEQ_P + 3 ] = 0;
+ seqnum += 2;
+
+ // setup maximum segment size
+ rxtx_buffer[ TCP_OPTIONS_P + 0 ] = 2;
+ rxtx_buffer[ TCP_OPTIONS_P + 1 ] = 4;
+ rxtx_buffer[ TCP_OPTIONS_P + 2 ] = HIGH(1408);
+ rxtx_buffer[ TCP_OPTIONS_P + 3 ] = LOW(1408);
+ // setup tcp header length 24 bytes: 6*32/8 = 24
+ rxtx_buffer[ TCP_HEADER_LEN_P ] = 0x60;
+ dlength += 4;
+ }
+ else
+ {
+ // no options: 20 bytes: 5*32/8 = 20
+ rxtx_buffer[ TCP_HEADER_LEN_P ] = 0x50;
+ }
+
+ // generate ip header and checksum
+ ip_generate_header ( rxtx_buffer, (WORD_BYTES){(sizeof(IP_HEADER) + sizeof(TCP_HEADER) + dlength)}, IP_PROTO_TCP_V, dest_ip );
+
+ // clear sequence ack number before send tcp SYN packet
+ if ( clear_seqack )
+ {
+ rxtx_buffer[ TCP_SEQACK_P + 0 ] = 0;
+ rxtx_buffer[ TCP_SEQACK_P + 1 ] = 0;
+ rxtx_buffer[ TCP_SEQACK_P + 2 ] = 0;
+ rxtx_buffer[ TCP_SEQACK_P + 3 ] = 0;
+ }
+
+ // setup tcp flags
+ rxtx_buffer [ TCP_FLAGS_P ] = flags;
+
+ // setup destination port
+ rxtx_buffer [ TCP_DST_PORT_H_P ] = dest_port.byte.high;
+ rxtx_buffer [ TCP_DST_PORT_L_P ] = dest_port.byte.low;
+
+ // setup source port
+ rxtx_buffer [ TCP_SRC_PORT_H_P ] = src_port.byte.high;
+ rxtx_buffer [ TCP_SRC_PORT_L_P ] = src_port.byte.low;
+
+ // setup maximum windows size
+ rxtx_buffer [ TCP_WINDOWSIZE_H_P ] = HIGH((MAX_RX_BUFFER-sizeof(IP_HEADER)-sizeof(ETH_HEADER)));
+ rxtx_buffer [ TCP_WINDOWSIZE_L_P ] = LOW((MAX_RX_BUFFER-sizeof(IP_HEADER)-sizeof(ETH_HEADER)));
+
+ // setup urgend pointer (not used -> 0)
+ rxtx_buffer[ TCP_URGENT_PTR_H_P ] = 0;
+ rxtx_buffer[ TCP_URGENT_PTR_L_P ] = 0;
+
+ // clear old checksum and calculate new checksum
+ rxtx_buffer[ TCP_CHECKSUM_H_P ] = 0;
+ rxtx_buffer[ TCP_CHECKSUM_L_P ] = 0;
+ // This is computed as the 16-bit one's complement of the one's complement
+ // sum of a pseudo header of information from the
+ // IP header, the TCP header, and the data, padded
+ // as needed with zero bytes at the end to make a multiple of two bytes.
+ // The pseudo header contains the following fields:
+ //
+ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ // +00+01+02+03+04+05+06+07+08+09+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+
+ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ // + Source IP address +
+ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ // + Destination IP address +
+ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ // + 0 + IP Protocol + Total length +
+ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ ck.word = software_checksum( &rxtx_buffer[IP_SRC_IP_P], sizeof(TCP_HEADER)+dlength+8, IP_PROTO_TCP_V + sizeof(TCP_HEADER) + dlength );
+ rxtx_buffer[ TCP_CHECKSUM_H_P ] = ck.byte.high;
+ rxtx_buffer[ TCP_CHECKSUM_L_P ] = ck.byte.low;
+
+ // send packet to ethernet media
+ enc28j60_packet_send ( rxtx_buffer, sizeof(ETH_HEADER)+sizeof(IP_HEADER)+sizeof(TCP_HEADER)+dlength );
+}
Index: apps/avr-webserver/adc.c
===================================================================
--- apps/avr-webserver/adc.c (nonexistent)
+++ apps/avr-webserver/adc.c (revision 42)
@@ -0,0 +1,143 @@
+//********************************************************************************************
+//
+// File : adc.c implement for on-board temparature sensor and ADC0
+//
+//********************************************************************************************
+//
+// Copyright (C) 2007
+//
+// This program is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free Software
+// Foundation; either version 2 of the License, or (at your option) any later
+// version.
+// This program is distributed in the hope that it will be useful, but
+//
+// WITHOUT ANY WARRANTY;
+//
+// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+// PURPOSE. See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program; if not, write to the Free Software Foundation, Inc., 51
+// Franklin St, Fifth Floor, Boston, MA 02110, USA
+//
+// http://www.gnu.de/gpl-ger.html
+//
+//********************************************************************************************
+#include "includes.h"
+// Thermistor resistance and ADC calculation.
+//
+// Rntc = R0 * exp B(1/T - 1/T0)
+//
+// R0 : Zero resistance @ 25 degree celsius.
+// B : constant value (see datasheet)
+// T0 : Zero temparature in Kevin
+//
+// constant from TTC05's datasheet : R0 = 10kOhm, B = 4050K, T0 = 25+273.15
+//
+// Rntc
+// Vref o-----/\/\/-------
+// |------o Vout
+// 0V o-----/\/\/-------
+// Rout
+// Rout = 10k
+// Vout = (2.56 * 10000.0) / (10000.0 + Rntc)
+// ADC = (Vout / 2.56) * 1024.0
+//
+// 2.56 is Internal Vref
+//
+// below table are ADC values, calculate from T=0 to T=99
+prog_uint16_t temp_list[100] =
+{
+229, 239, 249, 259, 270, 280, 291, 302, 313, 324,
+335, 347, 358, 370, 382, 394, 405, 417, 429, 441,
+453, 465, 477, 489, 500, 512, 524, 535, 547, 558,
+569, 580, 591, 602, 613, 623, 633, 644, 654, 663,
+673, 682, 692, 701, 710, 718, 727, 735, 743, 751,
+759, 766, 774, 781, 788, 795, 801, 808, 814, 820,
+826, 832, 837, 843, 848, 853, 858, 863, 867, 872,
+876, 881, 885, 889, 893, 897, 900, 904, 907, 911,
+914, 917, 920, 923, 926, 929, 931, 934, 936, 939,
+941, 944, 946, 948, 950, 952, 954, 956, 958, 960,
+};
+//********************************************************************************************
+//
+// Function : adc_read
+// Description : read ADC value, select ADC channel to read by channel argument
+//
+//********************************************************************************************
+WORD adc_read ( BYTE channel )
+{
+ // Analog channel selection
+ ADMUX = ((ADMUX) & ~0x1f) | (channel & 0x1f);
+
+ // Start conversion
+ ADCSRA |= _BV(ADSC);
+
+ // Wait until conversion complete
+ while( bit_is_set(ADCSRA, ADSC) );
+
+ // CAUTION: READ ADCL BEFORE ADCH!!!
+ return ((ADCL) | ((ADCH)<<8));
+}
+//********************************************************************************************
+//
+// Function : adc_init
+// Description : Initial analog to digital convertion
+//
+//********************************************************************************************
+//void adc_init ( void ) __attribute__ ((naked));
+void adc_init ( void )
+{
+ //BYTE i;
+
+ // ADC enable, Prescaler divide by 128, ADC clock = 16MHz/128 = 125kHz
+ ADCSRA = _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0);
+
+ // Select Vref, internal Vref 2.56V and external capacitor
+ ADMUX = _BV(REFS1) | _BV(REFS0);
+
+ // reading temparature
+ //for ( i=0; i<32; i++ )
+ // adc_read_temp ();
+}
+//********************************************************************************************
+//
+// Function : adc_read_temp
+// Description : read temparature from ADC1 and convert to real temparature
+//
+//********************************************************************************************
+BYTE adc_read_temp ( void )
+{
+ static WORD temp_buf[ ADC_TEMP_BUFFER ];
+ static BYTE buf_index=0;
+ WORD result=0,data;
+ BYTE loop;
+
+ // Store each sample to buffer
+ temp_buf[ buf_index ] = adc_read ( ADC_TEMP_CHANNEL );
+
+ // Low pass filter 8 samples by default.
+ for ( loop=0; loopAVRnet V0.9 by AVRportal.com AVRnet V0.9 by AVRportal.com
LED 1 : OFF [ ON ], LED 2 : OFF [ ON ]
ACD0 = 0516
Temparature = 29°C
Refresh
LED 1 : OFF [ ON ], LED 2 : OFF [ ON ]
ACD0 = 0516
Temparature = 29°C
Refresh