/*************************************************************
* Attiny25 S0 Filter
*
* Das S0 Signal (70 msek Impuls) vom Stromzähler soll sicher erkannt werden.
* Die reine Flankentriggerung bringt leider Fehler 
*
* Interupt Belegung                             wo              warum
* -------------------------------------------------------------------------------------------
* INT0        External Interrupt Request 0
* PCINT0      Pin Change Interrupt Request 0
* PCINT1      Pin Change Interrupt Request 1
* WDT         Watchdog Time-out
* TIM1_CAPT   Timer/Counter1 Capture Event
* TIM1_COMPA  Timer/Counter1 Compare Match A
* TIM1_COMPB  Timer/Counter1 Compare Match B
* TIM1_OVF    Timer/Counter1 Overflow
* TIM0_COMPA  Timer/Counter0 Compare Match A    main.c   5msec Timer
* TIM0_COMPB  Timer/Counter0 Compare Match B
* TIM0_OVF    Timer/Counter0 Overflow
* ANA_COMP    Analog Comparator
* ADC ADC     Conversion Complete
* EE_RDY      EEPROM Ready
* USI_STR     USI START
* USI_OVF     USI Overflow
*
* Prozessor:  ATtiny25
* Frequenz:   8,000 MHz (interner Clock)
*
* -------------------------------------------------------------------------------------------
* Pin Belegung Attiny25
*                                            +----------------+
* Reset ISP      (PCINT5/RESET/ADC0/dW) PB5 -|1     XXX      8|- VCC
*                                            |                |
*         (PCINT3/XTAL1/CLKI/OC1B/ADC3) PB3 -|2              7|- PB2 (SCK/USCK/SCL/ADC1/T0/INT0/PCINT2)   INPUT1
*                                            |                |
*         (PCINT4/XTAL2/CLKO/OC1B/ADC2) PB4 -|3              6|- PB1 (MISO/DO/AIN1/OC0B/OC1A/PCINT1)      Output
*                                            |                |
*                                       GND -|4              5|- PB0 (MOSI/DI/SDA/AIN0/OC0A/OC1A/AREF/PCINT0)
*                                            +----------------+
*--------------------------------------------------------------------------------------------
* FUSE: Attiny25    FF DF E2
*       mit CLKOUT  FF DF A2

* -------------------------------------------------------------------------------------------
* AVR GCC Compiler
* counter von 10 auf 8 reduziert
* -------------------------------------------------------------------------------------------
*/

#include <avr/io.h>
#include <avr/interrupt.h>
// #include <math.h>
#include "../../abc/basis.h"


unsigned char volatile tim1_event_flag=0;        // 5 msec Trigger


  // ----------------------------------------------
  // INDEX test_switch_x()    0 
  // ----------------------------------------------
unsigned char al_cc[2]  = {    0  };       // counters
unsigned char al_bit[2] = { BIT2 };        // Bits


static void timer1_init(void);                      // timer 120 Hz
static unsigned char test_switch_B( unsigned char i );
#undef _COUNTR

/*###########################################################################
 * Main
 */
int main(void)
{ 
   unsigned char ts1 = 0;  
    
 
   timer1_init();                      // 5 msek timer
   DDRB  |= BIT1;                      // Output  
   PORTB |= BIT0+BIT1+BIT2+BIT3+BIT4;  // Input mit internem Pullup Widerstand
   sei();                              // enable int
   
	
   // ++++++++++++++++++++++++++++++++ Main LOOP ++++++++++++++++++++++++++++
   // ++++++++++++++++++++++++++++++++ Main LOOP ++++++++++++++++++++++++++++
   // ++++++++++++++++++++++++++++++++ Main LOOP ++++++++++++++++++++++++++++
	for(;;)
	{
	   if ( tim1_event_flag )            // 5 msek vorbei ?
	   {	      
         tim1_event_flag = 0;           // reset flag
         
         if ( (ts1 = test_switch_B(0)) ) // Input Test +++
         {
            if ( ts1 == 1 )              // 1 wenn laenger als 50 msek
            {               
               PORTB |= BIT1;           // Output S0 auf 1            
            }
            else if ( ts1 == 2)
            {
               PORTB &= ~BIT1;          // Output S0 auf 0
            }
         }        
	   }
   }
   return 0;           // dummy
}



/*****************************************************************************
** Abfrage PORTB
** Filtern von Prellungen
** Hier Aufruf alle 5 msek
*/
static unsigned char test_switch_B( unsigned char i )
{
   unsigned char bit;

   bit = al_bit[i];                 // Bit holen

   if ( PINB & bit )                // Signal = 1 ??
   {
      if ( PINB & bit && al_cc[i] < 128 )
      {
         if ( al_cc[i]++ > 8 )     // > 50 msek ?
         {
            al_cc[i] = 128;         // pressed
            return 1;
         }
      }
   }
   else                             // Signal = 0
   {
      if ( al_cc[i] >= 128 )
      {
         if ( !(PINB & bit) )
         {
            if ( al_cc[i]++ > 136 ) // > 50 msek ?
            {
               al_cc[i] = 0;        // no pressed
               return 2;
            }
         }
      }
      else
         al_cc[i] = 0;             // no pressed
   }
   return 0;
}


/*****************************************************************************
**  set Timer1  compareA
*/
static void timer1_init( void )
{
   TCCR1 |= (1<<CTC1) ;                         // CTC1 mode compare mit OCR1C
   GTCCR |= (1<<PSR1) ;                         // Reset Timer
   TCCR1 |= (1<<CS13) + (1<<CS10);              // prescaler   
   OCR1C  = 128;                                // compare match bei 128 + 1 
   TCNT1 = 0;
   TIMSK |= (1<<OCIE1A);
}



/*****************************************************************************
*  8 Bit TIMER0 Compare Match
*  alle ca. 5 msek
*/
ISR ( TIM1_COMPA_vect )
{
   tim1_event_flag++;         // set flag 
}

