/*****************************************************
Chip type           : ATtiny13
Clock frequency     : 1,200000 MHz
Memory model        : Tiny
External SRAM size  : 0
Data Stack size     : 16

// PORTB0 - вход - нога 5 
// PORTB1 - вход - нога 6 INT0 
// PORTB2 - выход - нога 7
// PORTB3 - выход - нога 2
// PORTB4 - выход - нога 3

*****************************************************/

#include <tiny13.h>

#define INPUT_PULSE_NUMBER 2 // число вх. имп.
#define OUTPUT_PULSE_NUMBER 3 // число вых. имп.

volatile unsigned int delay_time = 0; // счётчик задержки в тиках
volatile unsigned int input_pulse_time = 0; // длительность вершины вх. импульса в тиках
volatile unsigned int input_pause_time = 0; // длительность паузы между вх. импульсами в тиках
volatile unsigned int output_pulse_time = 0; // текущее значение длительности вершины вых. импульса в тиках
volatile unsigned int output_pause_time = 0; // текущее значение длительности паузы между вых. импульсами в тиках
volatile unsigned int output_pulse_time_new = 0; // уточнённое значение длительности вершины вых. импульса в тиках
volatile unsigned int output_pause_time_new = 0; // уточнённое значение длительности паузы между вых. импульсами в тиках
volatile unsigned int input_pulse_number = 0; // счётчик вх. импульсов
volatile unsigned int output_pulse_number = 0; // счётчик вых. импульсов

volatile unsigned char output_pulse_flag = 0; // 1 - выводится 1, 0 - выводится 0
volatile unsigned char output_enable_flag = 0; // 1 - можно выводить вых. импульсы, 0 - нельзя.


// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
// сюда попадаем с началом каждого вх. импульса
// формируем  контрольный импульс на ноге 2 (для отладки)
PORTB.3 = 1;

// возможен  дребезг. поэтому проверяем наличие вх. импульса
if(input_pulse_time)
{
    // что-то насчитал. проверяем, не дофига ли? 
    if((input_pulse_time < 0xFFFF)&(input_pause_time < 0xFFFF))
    {
        // ни один из счётчиков не переполнен 
        //Вычисляем параметры вых. импульса
        output_pulse_time_new = (input_pulse_time/OUTPUT_PULSE_NUMBER)*INPUT_PULSE_NUMBER;
        output_pause_time_new = (input_pause_time/OUTPUT_PULSE_NUMBER)*INPUT_PULSE_NUMBER;
        // переполнения не боимся, т.к. сначала делим, и в итоге, умножаем на величину, меньше единицы
    
        // проверяем, все ли входные импульсы пришли ?
        if(input_pulse_number<(INPUT_PULSE_NUMBER-1))
        {
            // не все импульсы пришли
            input_pulse_number++; //увеличиваем счётчик
        }
        else
        {
            // все импульсы пришли. 
            input_pulse_number = 0; //сбрасываем счётчик вх. импульсов
            output_pulse_number = 0; //сбрасываем счётчик вых. импульсов
            // синхронизируем выходной импульс
            output_pulse_flag = 1;
            output_enable_flag = 1; // разрешаем вывод.
        }
    }
    else
    {
        // один из счётчиков переполнен! Запрещаем вывод.
        output_enable_flag = 0;
        input_pulse_number = 0; //сбрасываем счётчик входных импульсов.
    }
}

// сбрасываем счётчики длительности вх. импульса
        input_pulse_time = 0;
        input_pause_time = 0;

  
// заканчиваем формирование контрольного импульса на ноге 2 (для отладки)
PORTB.3 = 0;
}

// Timer 0 output compare A interrupt service routine
interrupt [TIM0_COMPA] void timer0_compa_isr(void)
{
// сюда попадаем через каждый тик ( 100 мкс )
// формируем  контрольный импульс на ноге 3 (для отладки)
PORTB.4 = 1;
if(delay_time)
{
    delay_time--; // счётчик задержки
}
// проверяем, разрешено ли выводить вых. импульсы
if(output_enable_flag)
{
    // разрешено
    // проверяем, все ли выходные импульсы выведены
    if(output_pulse_number < OUTPUT_PULSE_NUMBER)
    {
        // нет не все выведены. выводим.
        // проверяем, что выводили 1 или 0 ?
        if(output_pulse_flag)
        {
            // выводили 1
            // Проверяем вышло ли время длительности импульса
            if(output_pulse_time)
            {
                // нет, не вышло. продолжаем выводить 1
                PORTB.2 = 1;
                output_pulse_time--; // уменьшаем счётчик на 1
            }
            else
            {
                // время вышло. прошла вершина импульса    
                PORTB.2 = 0;
                output_pulse_flag = 0; // сбрасываем флаг
                output_pulse_number++; // увеличиваем счётчик вых. импульсов       
                // уточняем значение длительности для следующего импульса
                output_pulse_time = output_pulse_time_new;
            }
        }
        else
        {
            // выводили 0
            // Проверяем вышло ли время паузы между импульсами
            if(output_pause_time)
            {
                // нет, не вышло. продолжаем выводить 0
                PORTB.2 = 0;
                output_pause_time--; // уменьшаем счётчик на 1
            }
            else
            {
                // время вышло.    
                PORTB.2 = 1;
                output_pulse_flag = 1; // устанавливаем флаг
                // уточняем значение паузы для следующего импульса
                output_pause_time = output_pause_time_new;
            }
        }
    }
    else
    {
        // все выходные импульсы выведены. Сохраняем 0 значение на выходе
        PORTB.2 = 0;
    }
}


// измеряем параметры входного импульса
if(PINB.1)
{
    // на входе 1. увеличиваем счетчик
    if(input_pulse_time < 0xFFFF)
    {
        input_pulse_time++; //  увеличиваем счётчик
    }
    else
    {
        // счётчик достиг максимума. запрещаем вывод импульсов
        output_enable_flag = 0; 
    }
}
else
{
    // на входе 0. увеличиваем счетчик
    if(input_pause_time < 0xFFFF)
    {
        input_pause_time++; //  увеличиваем счётчик
    }
    else
    {
        // счётчик достиг максимума. запрещаем вывод импульсов
        output_enable_flag = 0; 
    }
}
// заканчиваем формирование контрольного импульса на ноге 3 (для отладки)
PORTB.4 = 0;
}// конец прерывания interrupt [TIM0_COMPA] void timer0_compa_isr(void)


void main(void)
{

// PORTB0 - вход - нога 5 
// PORTB1 - вход - нога 6 INT0 
// PORTB2 - выход - нога 7
// PORTB3 - выход - нога 2
// PORTB4 - выход - нога 3

DDRB=0b00011100;
PORTB=0b00000011; // включаем подтяжки на входах

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 1200 kHz
// Mode: CTC top=OCR0A
TCCR0A=0x02;
TCCR0B=0x02;
TCNT0=0x00;
OCR0A=120;
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x04;

// INT0: On
// INT0 Mode: Rising Edge
// Interrupt on any change on pins PCINT0-5: Off

MCUCR=3; // Задействуем прерывание INT0
GIMSK=0; // пока что запретим его


// Global enable interrupts
#asm("sei")

// Подождём, пока всё устаканится
delay_time = 10000; // 1 сек
while(delay_time)
{
}

GIMSK=0x40; // разрешаем прерывание INT0

while (1)
{
    
    if(PINB.0==0)
    {
        output_enable_flag = 0;
        GIMSK=0; // запрещаем прерывание INT0
        PORTB.2 = PINB.1;
        
    }
    else
    {
        GIMSK=0x40; // разрешаем прерывание INT0
    }
    
}
}

