#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>

//globalni promenne:
volatile bool novyudaj = false;
volatile bool preteklo = false;
volatile uint16_t interval = 0;

void inicializace()
{
  //PC3 = 1, PB1 = 1:
  DDRC = DDRC | (1 << 3);
  DDRB = DDRB | (1 << 1);
  PORTB = PORTB | (1 << 1);
  PORTC = PORTC | (1 << 3);
  
  //konfigurace analog. komparatoru:
  ADCSRB = 0;
  ACSR = (1 << ACIC);  //zachyt pres AK
  
  //povoleni preruseni pri zachytu + nulovani priznaku:
  TIMSK1 = (1 << ICIE1);
  TIFR1 = (1 << TOV1) | (1 << ICF1);
}

//obsluha zachytneho registru 1:
ISR(TIMER1_CAPT_vect)
{
  interval = ICR1;
  preteklo = TIFR1 & (1 << TOV1);
  novyudaj = true;
}

//spusti nove mereni:
void start()
{
  TCCR1B = (1 << ICES1);  //zastaveni citace
  TCNT1 = 0;
  TIFR1 = (1 << TOV1) | (1 << ICF1);  //nulovani priznaku
  
  //vybijeni CK:
  DDRD = DDRD | (1 << 6);    //PD6 je vystup
  PORTD = PORTD & ~(1 << 6); //v log. 0
  _delay_ms(100);
  DDRD = DDRD & ~(1 << 6);  //PD6 je vstup
  
  TCCR1B = (1 << ICES1) | (1 << CS10);  //spusteni citace
}

//konstanty pro vypocet odporu:
const float k = 0.01 / (0.693 * 16e6 * 100e-9);
const uint16_t Rk3 = 100;

int main(void)
{
  uint16_t Rx;
  
  inicializace();
  sei();
  
  printf("Mereni odporu:\n");
  
  start();  //spusti prvni mereni
  
  while (1) 
  {
    if(novyudaj)
    {
      Rx = interval * k - Rk3;  //vypocet Rx
      
      if(preteklo)
        printf("prilis velky odpor\n");
      else
        printf("%u,%u kOhm\n", Rx / 10, Rx % 10);
      
      novyudaj = false;
      _delay_ms(500);
      start();  //spusti nove mereni
    }
  }
}

