/*
------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------- MODUL = Teil C ----------------------------------------------------
************************************************* application.c ** V1.1 ************************************************
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
 Header...............: application.h
 Version..............: 1.1
 Compiler.............: CodeVisionAVR
 Chip.................: ATmega88
 Datum................: Juni 2009
 Autor................: Alwin Lenck (ALE23) basierend auf dem Modul application von Udo Juerss
------------------------------------------------------------------------------------------------------------------------
*/

//----------------------------------------------------------------------------------------------------------------------
// Header-Datei einfuegen:
//----------------------------------------------------------------------------------------------------------------------
#include "application.h"                         // Initialisierung der Anwendung
//----------------------------------------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------------------------------------
// Globale Variablen:
//----------------------------------------------------------------------------------------------------------------------
volatile U08 app_reset_source;
//----------------------------------------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------------------------------------
//--Haupt-Funktion------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
void app_init(void)
{
  app_reset_source = MCUSR;                      // Sichern des Mikrocontroller(MCU)-Status-Registers
                                                 // Bit7=0        => Reserviertes Bit stets 0 (nicht belegt) 
                                                 // Bit6=0        => Reserviertes Bit stets 0 (nicht belegt) 
                                                 // Bit5=0        => Reserviertes Bit stets 0 (nicht belegt) 
                                                 // Bit4=0        => Reserviertes Bit stets 0 (nicht belegt) 
                                                 // Bit3 WDRF     => Watchdog Reset Flag
                                                 // Bit2 BORF     => Brown-out Reset Flag
                                                 // Bit1 EXTRF    => External Reset Flag
                                                 // Bit0 PORF     => Power-on Reset Flag
  MCUSR = 0x00;                                  // Loeschen aller Reset Flags fuer naechsten RESET-Zyklus

//----------------------------------------------------------------------------------------------------------------------
// Durch Voreinstellung ("startup.asm") ist der Watchdog Timer ausgeschaltet
//----------------------------------------------------------------------------------------------------------------------
#ifdef USE_WATCHDOG
  WDTCSR = WDCE | WDE;                           // Enable Watchdog Reset (Watchdog Timer Control Register; ~16ms)
#endif

//----------------------------------------------------------------------------------------------------------------------
// Setzen des voreingestellten System-Taktes nur wenn ein Quarz als Taktgeber gewaehlt wurde
#ifdef USE_CRYSTAL_CLOCK                         // Abfrage, ob ein Quarz als Taktgeber gewaehlt wurde
//----------------------------------------------------------------------------------------------------------------------
#if (_MCU_CLOCK_FREQUENCY_   == 16000000)
  CLKPR = CLKPCE;                                // Enable Clock Prescaler mit CLKPR = 0x80 (CLKPCE ist Bit7 = 0x80)
  CLKPR = 0;                                     // Setze Clock Prescaler, Division durch 1 (=16MHz bei 16MHz-Quarz)
#elif (_MCU_CLOCK_FREQUENCY_ ==  8000000)        // 
  CLKPR = CLKPCE;                                // Enable Clock Prescaler mit CLKPR = 0x80 (CLKPCE ist Bit7 = 0x80)
  CLKPR = 1;                                     // Setze clock Prescaler, Division durch 2 (= 8MHz bei 16MHz-Quarz)
#elif (_MCU_CLOCK_FREQUENCY_ ==  4000000)        // 
  CLKPR = CLKPCE;                                // Enable Clock Prescaler mit CLKPR = 0x80 (CLKPCE ist Bit7 = 0x80)
  CLKPR = 2;                                     // Setze clock Prescaler, Division durch 4 (= 4MHz bei 16MHz-Quarz)
#elif (_MCU_CLOCK_FREQUENCY_ ==  2000000)        // 
  CLKPR = CLKPCE;                                // Enable Clock Prescaler mit CLKPR = 0x80 (CLKPCE ist Bit7 = 0x80)
  CLKPR = 3;                                     // Setze clock Prescaler, Division durch 8 (= 2MHz bei 16MHz-Quarz)
#elif (_MCU_CLOCK_FREQUENCY_ ==  1000000)        // 
  CLKPR = CLKPCE;                                // Enable Clock Prescaler mit CLKPR = 0x80 (CLKPCE ist Bit7 = 0x80)
  CLKPR = 4;                                     // Setze clock Prescaler, Division durch 16 (=1MHz bei 16MHz-Quarz)
#else                                            // Andernfalls Fehleranzeige
  #error *** Invalid Clock Selected! ***
#endif

  // Zeige dem Benutzer die verwendete Arbeitsfrequenz an
#warning *** Compiling for _MCU_CLOCK_FREQUENCY_ Hz

#endif // USE_CRYSTAL_CLOCK

//----------------------------------------------------------------------------------------------------------------------
// Schaltet die Power Reduction nur fuer die in der Applikation verwendeten Ressourcen ein (gesetzt in application.h)
//----------------------------------------------------------------------------------------------------------------------
  PRR =                                          // Das ist das Power Reduction Register PRR 
                                                 // Ein Bit gesetzt bedeutet Shut Down - Modul abgeschaltet
                                                 // Ein Bit auf 0 gesetzt ermoeglicht die Nutzung der Ressource
                                                 // Bit7 PRTWI    => Power Reduction TWI
                                                 // Bit6 PRTIM2   => Power Reduction Timer/Counter 2
                                                 // Bit5 PRTIM1   => Power Reduction Timer/Counter 1
                                                 // Bit4=0        => Reserviertes Bit stets 0 (nicht belegt) 
                                                 // Bit3 PRTIM0   => Power Reduction Timer/Counter 0
                                                 // Bit2 PRSPI    => Power Reduction SPI
                                                 // Bit1 PRUSART0 => Power Reduction USART0
                                                 // Bit0 PRADC    => Power Reduction ADC

  (0
#ifndef USE_TWI
    | PRTWI                                      // I2C module
  #warning *** Module "TWI" not enabled!
#endif

#ifndef USE_TIMER2
    | PRTIM2                                     // Timer2
  #warning *** Module "TIMER2" not enabled!
#endif

#ifndef USE_TIMER1
    | PRTIM1                                     // Timer1
  #warning *** Module "TIMER1" not enabled!
#endif

#ifndef USE_TIMER0
    | PRTIM0                                     // Timer0
  #warning *** Module "TIMER0" not enabled!
#endif

#ifndef USE_SPI
    | PRSPI                                      // SPI
  #warning *** Module "SPI" not enabled!
#endif

#ifndef USE_USART0
    | PRUSART0                                   // USART0
  #warning *** Module "USART0" not enabled!
#endif

#ifndef USE_ADC
    | PRADC                                      // ADC
  #warning *** Module "ADC" not enabled!
#endif
  );

#ifndef USE_ACO                                  // Analog comparator
  ACSR = ACD;                                    // Das ist das Register-Bit 7 (ACD = 10000000)
  #warning *** Module "ACO" not enabled!
#endif

  PORTC |= PC6;                                  // Enable Pullup fuer RESET an Pin PC6

}

//----------------------------------------------------------------------------------------------------------------------
// Setze Watchdog Prescaler
//----------------------------------------------------------------------------------------------------------------------
void app_set_watchdog_prescaler(tWDT_PRESCALE wdt_prescale) 
{
  U08 sreg_backup = SREG;                        // Rette Status-Register
  U08 wdtcsr_value = WDE + wdt_prescale;         // Setze neuen Prescale-Wert (WDE = Bit3 = 0x08)

  CLI();                                         // Assembler-Befehl #asm("cli"): Disable Interrups (Clear I-Bit)
  WDR();                                         // Assembler-Befehl #asm("wdr"): Reset Watchdog

  WDTCSR |= WDCE | WDE;                          // Unlock register access; 4 Zyklen um neuen Wert zu speichern
                                                 // WDTCSR =  00011000 (WDCE = Bit4; WDE = Bit3) => 
                                                 // WDIF=0 => Watchdog Interrupt Flag
                                                 // WDIE=0 => System Reset bei Timeout
                                                 // WDP3=0 => Watchdog Timer Prescale Select
                                                 // WDCE=1 => Watchdog Change Enable
                                                 // WDE =1 => System Reset Mode durch Watchdog System Reset Enable
                                                 // WDP2=0 => Watchdog Timer Prescale Select
                                                 // WDP1=0 => Watchdog Timer Prescale Select
                                                 // WDP0=0 => Watchdog Timer Prescale Select

  WDTCSR = wdtcsr_value;                         // Setze neuen Watchdog-Prescaler
  SREG = sreg_backup;                            // Wiederherstellen des Status-Registers
}
//----------------------------------------------------------------------------------------------------------------------

