/*----------------------------------------------------------------------------
 Copyright:      Radig Ulrich  mailto: mail@ulrichradig.de
 Author:         Radig Ulrich
 Remarks:
 known Problems: none
 Version:        24.10.2007
 Description:    Webserver uvm.

 Dieses Programm ist freie Software. Sie können es unter den Bedingungen der
 GNU General Public License, wie von der Free Software Foundation veröffentlicht,
 weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder
 (nach Ihrer Option) jeder späteren Version.

 Die Veröffentlichung dieses Programms erfolgt in der Hoffnung,
 daß es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE,
 sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT
 FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License.

 Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
 Programm erhalten haben.
 Falls nicht, schreiben Sie an die Free Software Foundation,
 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
----------------------------------------------------------------------------*/

#include <avr/io.h>
#include "config.h"
#include "usart.h"
#include "networkcard/enc28j60.h"
#include "networkcard/rtl8019.h"
#include "stack.h"
#include "timer.h"
#include "wol.h"
#include "httpd.h"
#include "cmd.h"
#include "telnetd.h"
#include "ntp.h"
#include "base64.h"
#include "http_get.h"
#include "lcd.h"
#include "udp_lcd.h"
#include "analog.h"
//#include "camera/cam.h"
//#include "camera/servo.h"
#include "sendmail.h"
#include "artnet.h"
#include <avr/eeprom.h>

#include "dhcpc.h"
#include "dnsc.h"
#include "sram_util.h"                    // SRAM und sofware UART
#include "../abc/sram.h"                  // SRAM
#include "../abc/basis.h"                 // Basis Routinen

S_SRAM s_sram;

extern volatile unsigned char tim1_event;
/************************************************* ATmega644 PIN Beleung
**
**
           +----------------------xxx--------------------+
           1 -PB0 (PCINT8/XCK0/T0)    (ADC0/PCINT0) PA0-40
           2 -PB1 (PCINT9/CLKO/T1)    (ADC1/PCINT1) PA1-39
           3 -PB2 (PCINT10/INT2/AIN0) (ADC2/PCINT2) PA2-38
           4 -PB3 (PCINT11/OC0A/AIN1) (ADC3/PCINT3) PA3-37
           5 -PB4 (PCINT12/OC0B/SS)   (ADC4/PCINT4) PA4-36
           6 -PB5 (PCINT13/MOSI)      (ADC5/PCINT5) PA5-35
           7 -PB6 (PCINT14/MISO)      (ADC6/PCINT6) PA6-34
           8 -PB7 (PCINT15/SCK)       (ADC7/PCINT7) PA7-33
           9 -RESET                                AREF-32
           10-VCC                                   GND-31
           11-GND                                  AVCC-30
           12-XTAL2                 (TOSC2/PCINT23) PC7-29
           13-XTAL1                 (TOSC1/PCINT22) PC6-28
           14-PD0 (PCINT24/RXD0)      (TDI/PCINT21) PC5-27
           15-PD1 (PCINT25/TXD0)      (TDO/PCINT20) PC4-26
           16-PD2 (PCINT26/INT0)      (TMS/PCINT19) PC3-25
           17-PD3 (PCINT27/INT1)      (TCK/PCINT18) PC2-24
           18-PD4 (PCINT28/OC1B)      (SDA/PCINT17) PC1-23
           19-PD5 (PCINT29/OC1A)      (SCL/PCINT16) PC0-22
           20-PD6 (PCINT30/OC2B/ICP) (OC2A/PCINT31) PD7-21
           +-------------------ATMEGA644------------------+
*/

/************************************************* ATmega644 Interrupt Belegung
**
**                                                 WO
 0 RESET
 1 INT0         External Interrupt Request 0
 2 INT1         External Interrupt Request 1
 3 INT2         External Interrupt Request 2       DA
 4 PCINT0       Pin Change Interrupt Request 0     sram_util.c  PA7
 5 PCINT1       Pin Change Interrupt Request 1
 6 PCINT2       Pin Change Interrupt Request 2
 7 PCINT3       Pin Change Interrupt Request 3
 8 WDT Watchdog Time-out Interrupt
 9 TIMER2_COMPA Timer/Counter2 Compare Match A     sram_util.c 1,666 msek
10 TIMER2_COMPB Timer/Counter2 Compare Match B
11 TIMER2_OVF   Timer/Counter2 Overflow
12 TIMER1_CAPT  Timer/Counter1 Capture Event
13 TIMER1_COMPA Timer/Counter1 Compare Match A     timer.c
14 TIMER1_COMPB Timer/Counter1 Compare Match B
15 TIMER1_OVF   Timer/Counter1 Overflow
16 TIMER0_COMPA Timer/Counter0 Compare Match A
17 TIMER0_COMPB Timer/Counter0 Compare match B
18 TIMER0_OVF   Timer/Counter0 Overflow
19 SPI_STC      SPI Serial Transfer Complete
20 USART0_RX    USART0 Rx Complete                 da
21 USART0_UDRE  USART0 Data Register Empty
22 USART0_TX    USART0 Tx Complete
23 ANALOG_COMP  Analog Comparator
24 ADC ADC      Conversion Complete
25 EE_READY     EEPROM Ready
26 TWI 2-wire   Serial Interface
27 SPM_READY    Store Program Memory Ready
*/

#define UBUFSIZE 16
extern volatile unsigned char sram_trace;      // trace sram Software UART usw.
extern volatile unsigned char srx_rflag;       // Software UART Flag
extern unsigned char volatile srx_rbyte;       // received Byte
unsigned char rxd_ind = 0;                     // receive Index
char srx_buffer[UBUFSIZE];

//----------------------------------------------------------------------------
//Hier startet das Hauptprogramm
int main(void)
{
                              //Konfiguration der Ausgänge bzw. Eingänge
                              //definition erfolgt in der config.h
   DDRA = OUTA;
   DDRC = OUTC;
   DDRD = OUTD;
   unsigned char c;


    unsigned long a;
#if USE_SERVO
   servo_init();
#endif //USE_SERVO

   usart_init(BAUDRATE);      // setup the UART

#if USE_ADC
   ADC_Init();
#endif

   usart_write("System Ready\r");
   usart_write("Compiliert am "__DATE__" um "__TIME__"\r");
   usart_write("Compiliert mit GCC Version "__VERSION__"\r");

   sram_init();               // aktiviere Ports
#ifdef SRAM_CLEAR
   sram_testmem( &s_sram );   // check funktionsfähigkeit
#else
   s_sram.flag = 1;           // ist ok
#endif

                              // Applikationen starten
   stack_init();
   httpd_init( s_sram.flag ); // 29.8.2011 wird var8
   telnetd_init();

#if USE_ARTNET
	artnet_init();
#endif
                              //Spielerrei mit einem LCD
#if USE_SER_LCD
   udp_lcd_init();
   lcd_init();
   lcd_clear();
   back_light = 0;
   lcd_print(0,0,"System Ready");
#endif
                              //Ethernetcard Interrupt enable
   ETH_INT_ENABLE;
                              //Globale Interrupts einschalten
   sram_soft_uart_read_init( );    // software UART
   sei();

#if USE_CAM
#if USE_SER_LCD
   lcd_print(1,0,"CAMERA INIT");
#endif //USE_SER_LCD
   for(a=0;a<2000000;a++){asm("nop");};
   cam_init();
   max_bytes = cam_picture_store(CAM_RESOLUTION);
#if USE_SER_LCD
   back_light = 0;
   lcd_print(1,0,"CAMERA READY");
#endif //USE_SER_LCD
#endif //USE_CAM

#if USE_DHCP
   dhcp_init();
   if ( dhcp() == 0)
   {
      save_ip_addresses();
   }
   else
   {
      usart_write("DHCP fail\r");
      read_ip_addresses(); //get from EEPROM
   }
#endif //USE_DHCP

   usart_write("IP   %1i.%1i.%1i.%1i\r", myip[0]     , myip[1]     , myip[2]     , myip[3]);
   usart_write("MASK %1i.%1i.%1i.%1i\r", netmask[0]  , netmask[1]  , netmask[2]  , netmask[3]);
   usart_write("GW   %1i.%1i.%1i.%1i\r", router_ip[0], router_ip[1], router_ip[2], router_ip[3]);

#if USE_DNS
    usart_write("DNS  %1i.%1i.%1i.%1i\r", dns_server_ip[0], dns_server_ip[1], dns_server_ip[2], dns_server_ip[3]);
#endif //USE_DNS

#if USE_NTP
#if USE_DNS
   dns_init();
   if ( dns_resolve("1.de.pool.ntp.org") == 0) //resolve NTP server
   {
      for (unsigned char count = 0; count<4; count++)
      {
         eeprom_busy_wait ();
         eeprom_write_byte((unsigned char *)(NTP_IP_EEPROM_STORE + count),dns_resolved_ip[count]);
      }
   }
   else
   {
      usart_write("DNS Err.\r");
   }
#endif //USE_DNS

   ntp_init();

   for( a=0; a<1000000; a++)
   {
      asm("nop");
   }

   ntp_request();

   if ( ntp() != 0 )
   {
      usart_write("NTP Err.\r");
   }
   else
   {
      command_time();
   }
#endif //USE_NTP

#if USE_WOL
   wol_init();
#endif //USE_WOL

#if USE_MAIL
   mail_client_init();
#endif //USE_MAIL

                                    //****************** loop ********************
                                    //****************** loop ********************
                                    //****************** loop ********************
   while(1)
   {
      // ++++++++++++++++ Software UART Abfrage auf Zeichen empfangen ++++++
      if ( srx_rflag )
      {
         c =  srx_rbyte;                    // save Byte
         srx_rflag = 0;                     // clear

         if ( c == 0x02 )                   // start of txt
            rxd_ind = 0;                    // receive Index auf 0
                                            // zeichen im empfangsbuffer eintragen
         rxd_ind &= 0x0F;                   // index von 0-15 zulassen
         srx_buffer[ rxd_ind++ ] = c;

         if ( c == 0x03 )                   // end of text ??
         {
            if ( sram_trace & SRAM_TRACE_MESS2 )
            {
               srx_buffer[ --rxd_ind ] = '\0';   // 0x03 overwrite
               usart_write("%s\r", srx_buffer+1 );  // skip start of text
            }
            sram_decode_message( srx_buffer );
         }
      }
      // ++++++++++++++++ Software UART Abfrage ende ++++++++++++++++++++++++++


#if USE_ADC
      ANALOG_ON;
#endif
      eth_get_data();               // stack.c

      if ( tim1_event)              // 1 Sekunde
      {
                                    // update Zeit wenn DCF77 Zeit nicht aktiv
         sram_check_time(tim1_event);
         tim1_event = 0;

         if ( sram_read( SRAM_CLEAR_FLAG ) )      // SRAM clear flag
            sram_clear_loop();
      }

                                    //Terminalcommandos auswerten
      if (usart_status.usart_ready)
      {
         if( extract_cmd( &usart_rx_buffer[0] ))
         {
            usart_write("Ready\r");
         }
         else
         {
            usart_write("ERROR\r");
         }
         usart_status.usart_ready =0;
      }

                                     //Wetterdaten empfangen (Testphase)
#if GET_WEATHER
      http_request ();
#endif

                                     //Empfang von Zeitinformationen
#if USE_NTP
      if( !ntp_timer )
      {
         ntp_timer = NTP_REFRESH;
         ntp_request();
      }
#endif //USE_NTP

                                     //Versand von E-Mails
#if USE_MAIL
      if (mail_enable == 1)
      {
         mail_enable = 0;
         mail_send();
      }
#endif //USE_MAIL

                                    //Rechner im Netzwerk aufwecken
#if USE_WOL
      if (wol_enable == 1)
      {
         wol_enable = 0;
         wol_request();
      }
#endif //USE_WOL

#if USE_DHCP
      if ( dhcp() != 0) //check for lease timeout
      {
         usart_write("dhcp lease renewal failed\r");
         RESET();
      }
#endif //USE_DHCP

      //USART Daten für Telnetanwendung?
      telnetd_send_data();

      if( ping.result )
      {
         usart_write("Get PONG: %i.%i.%i.%i\r",ping.ip1[0],ping.ip1[1],ping.ip1[2],ping.ip1[3]);
         ping.result = 0;
      }
   } //while (1)

return(0);
}

