#include "DHT_22.h"
#include <avr/io.h>

//volatile unsigned char interrupt_flag;
int dht_save_time_id;
// Флаг прерывания  
volatile unsigned char interrupt_flag = 1;  
bool dht_done = false;
int  dht_check_icp;

uint8_t dht_state, dht_last_state;
int T1time, dPos, dNum;
float temperature, humidity;  
float last_temperature, last_humidity;

unsigned char data[5];  
uint8_t  dt[48];
uint8_t  dtcnt;
bool dht_check_act = false;

// Таймер для задержки
volatile unsigned int timer_counter = 0;
int dht_en_timer = 0;

//----------------------------------------------------------------------------------------------------
bool dht_check( void )
{
  bool valid_data = false;
  
  if (dht_check_act) {
    dht_check_act = false;
//-----[ 01. Старт, выжидание 18мс ]-----
    if ( interrupt_flag == 1)
    {
  //  Запускаем таймер на 18 мс посылка start на dht
//      Serial.print("Start DHT -> ");

      DHT_DDR |= (1 << DHT_BIT);    //  Пин как выход
      DHT_PORT &= ~(1 << DHT_BIT);  //  Выход ноль
      TCNT1 = 0;
      OCR1A = 288;  
      TCCR1A = 0b00000000;
      TIMSK1 = 0b00000010;
      TCCR1B = 0b00000101;
    }

    if ( interrupt_flag == 2)
    {
      DHT_PORT |= (1 << DHT_BIT);
      DHT_DDR  &= ~(1 << DHT_BIT);
      dht_save_time_id = 0;
      TCNT1 = 0;
      OCR1A = 10000;  
      TCCR1A = 0b00000000;
      TCCR1B = 0b10000001;
      TIFR1  = 0b00000000;
      TIMSK1 = 0b00100010;
      dPos   = 7;
      dNum   = 0;
      dht_last_state = false;
    }
      // Вычисляем температуру и влажность  
    if ( dht_done )
    {
      dht_done = false;
      temperature = (data[3] * 0.1) + ((data[2] & 0b01111111) * 25.6)/6;  
      if (data[2] & 0b10000000) temperature *= -1;  
      humidity = (data[1] * 0.1) + (data[0] * 25.6)/50;
      valid_data = true;

    }  
  }
  return valid_data;
}

float  dht_humidity(){
  return humidity;
}

float  dht_temperature(){
  return temperature;
}

void  T1_CAPT(){
  TCNT1 = 0;
  dht_save_time_id++;

  if ( dht_save_time_id  > 3 )
  {
    dt[dtcnt] = ICR1<<8;
    dtcnt++;
    if ( ICR1<1500 )  
    { 
      data[dNum] &= ~(1<<dPos); 
    } // 0
    else            
    {
       data[dNum] |=  (1<<dPos); 
    } // 1
    dPos--;
    if ( dPos < 0)   
    {
       dPos=7; dNum++; 
    }
  }
  if ( dht_save_time_id  == 42 )
  {
    interrupt_flag++;
    dht_check_act = true;
    dht_done = true;

    DHT_DDR  |= (1 << DHT_BIT);    //  Пин как выход
    DHT_PORT |= (1 << DHT_BIT);   //  Выход HIGH
  }
}

void  T0_CA(){
  TCNT0 = 0;
  dht_en_timer++;
  if ( dht_en_timer >= 65)
  {
    dht_en_timer =0;
    dht_done = false;
    dtcnt=0;
    interrupt_flag = 1;
    dht_check_act = true;
    DHT_DDR  |= (1 << DHT_BIT);    //  Пин как выход
    DHT_PORT |= (1 << DHT_BIT);   //  Выход HIGH
    dht_save_time_id = 0;
  }
}

void  T1_CA(){
  TCNT1 = 0;
  dht_check_act = true;
  TCCR1B = 0b00000000;
  if ( interrupt_flag < 3 )
  {
    interrupt_flag++;
  }
}