/****************************************************************/
/*     Obsluha HW prepinaca videosignalu z kamier riadeneho     */
/*                  vystupmi z PIR snimacov                     */
/*                                                              */
/*  posledna uprava 31.05.2008                Matus T.Kovacs    */
/****************************************************************/

#include "iom128.h"
#include "stdio.h"
#include "stdlib.h"

#define ClearWatchDog     PORTE &= 0xFB, PORTE |= 0x04;

typedef unsigned char byte;
typedef unsigned int word;

unsigned int Counter = 0;
unsigned char ActDataRefreshEn = 0;
unsigned int ADResult;
unsigned char Loop1Status, Loop2Status, Loop3Status, Loop4Status; // hodnota LoopXStaus je 1 - otvoreny tamper, 2 - otvorena slucka, 3 - slucka OK, 4 - skrat na slucke

unsigned int ReadADC(unsigned char channel, unsigned char count)
  {	
    //reads ADC channel(channel) count times and makes average,
    // count must NOT exceed 50 due to INT overflow
    unsigned int result;
    unsigned char n;	
    if(count > 50)
    return(0);
    if(channel > 7)
    return(0);
    ADMUX = channel;			        //select ADC channel 0 - 7
    result = 0;
    for(n = 0; n < count; n ++)   //repeats measurement count times
      {
	ADCSR = ADCSR | 64;	      //starts ADC conversion
	while(ADCSR & 64);
	result =result + (ADCL + (ADCH << 8));
      }
    result = result / count;
    return(result);
  }

 
#pragma vector=TIMER1_OVF_vect      // prerusenie kazdych 20ms
__interrupt void timer1(void)
  {
    TIMSK &= 0xFB;  // zakazujem prerusenie od Timer1
    
    if(Counter < 15) Counter ++;     // casovac na 300ms - kazdych 300ms sa odsleduje stav vystupov PIR
    if(Counter == 15)
      {
        Counter = 0;
        ActDataRefreshEn = 1;
      }
   
    TCNT1H = 0xB7;  // prerusenie Timer1 kazdych 20ms
    TCNT1L = 0xFD;  
    TIMSK |= 0x04;  // povolujem prerusenie od Timer1
  }
  
void LoopResult(unsigned char LoopNo)
  {
    // aby sa zabranilo kmitaniu z dovodu sumu na sluckach, zavadzame tzv. pasma necitlivosti
    // jednotlive stavy na sluckach sa budu detekovat v nasledovnych pasmach
    // skrat na slucke                908 a viac urovni z A/D prevodnika
    // slucka OK                      445 az 485 urovni z A/D prevodnika
    // slucka otvorena - narusenie    289 az 329 urovni z A/D prevodnika
    // skrat na slucke                0 a menej urovni z A/D prevodnika
    switch (LoopNo)
      {
        case 1:
          {
            if(ADResult < 20)                         Loop1Status = 1;    // otvoreny tamper
            if((ADResult > 289) && (ADResult < 329))  Loop1Status = 2;    // otvorena slucka
            if((ADResult > 445) && (ADResult < 485))  Loop1Status = 3;    // slucka OK
            if(ADResult > 908)                        Loop1Status = 4;    // skrat na slucke
          }
        break;
        
        case 2:
          {
            if(ADResult < 20)                         Loop2Status = 1;    // otvoreny tamper
            if((ADResult > 289) && (ADResult < 329))  Loop2Status = 2;    // otvorena slucka
            if((ADResult > 445) && (ADResult < 485))  Loop2Status = 3;    // slucka OK
            if(ADResult > 908)                        Loop2Status = 4;    // skrat na slucke
          }
        break;
        
        case 3:
          {
            if(ADResult < 20)                         Loop3Status = 1;    // otvoreny tamper
            if((ADResult > 289) && (ADResult < 329))  Loop3Status = 2;    // otvorena slucka
            if((ADResult > 445) && (ADResult < 485))  Loop3Status = 3;    // slucka OK
            if(ADResult > 908)                        Loop3Status = 4;    // skrat na slucke
          }
        break;
        
        case 4:
          {
            if(ADResult < 20)                         Loop4Status = 1;    // otvoreny tamper
            if((ADResult > 289) && (ADResult < 329))  Loop4Status = 2;    // otvorena slucka
            if((ADResult > 445) && (ADResult < 485))  Loop4Status = 3;    // slucka OK
            if(ADResult > 908)                        Loop4Status = 4;    // skrat na slucke
          }
        break;
      }
  }

void main(void)
  {
    SREG = 0x80;        // bit 7 - globalne povolenie preruseni - teraz povolujem   
    
    TIMSK = 0x04;       // povolujem Timer1
    
    TCCR1B |= 0x02;     // Clk/8 -> Q = 7.3728MHz
    TCNT1H = 0xB8;      // prerusenie kazdych 20ms
    TCNT1L = 0x00;
    
          
    // nastavenie smeru jednotlivych vstupov portov
    DDRA = 0x00;        // 1 - vystup, 0 - vstup
    DDRB = 0x01;        // PB1 moze sluzit ako poplachovy vystup v pripade porusenia temper kontaktov, alebo skratov na sluckach
    DDRC = 0xFF;        // vystupy - riadenie prepinaca videosignalu
    DDRD = 0x00;
    DDRE = 0x00;        
    DDRG = 0x00;
    
    ADCSR = 0x84;       // povoli ADC, taktovanie = Clk / 16
    
    WDTCR = 0x1E;
    WDTCR = 0x0E;       // prescaler pri 5V na 1s
    asm("wdr"); ClearWatchDog; 
    
    EIMSK = 0x00;       
    
    // inicializacia A/D prevodnika
    ADCSR = ADCSR | 64;	  // starts dummy conversion to warm up ADC
    while(ADCSR & 64);    //waits until ADC conversion finished
    ADResult = 9;
    
    
		
    while(1)
      {
        asm("wdr"); ClearWatchDog;
                        
        if(ActDataRefreshEn)
          {
            ActDataRefreshEn = 0;
            // obsluha slucky #1
            ADResult = ReadADC(0, 10);
            LoopResult(1);
            // obsluha slucky #2
            ADResult = ReadADC(1, 10);
            LoopResult(2);
            // obsluha slucky #3
            ADResult = ReadADC(2, 10);
            LoopResult(3);
            // obsluha slucky #4
            ADResult = ReadADC(3, 10);
            LoopResult(4);
          }
      }    
  }