#include <util/delay.h>
#include "i2c.h"
#include "pwm.h"

#define I2C_ADDRESS 0x20

void send_data(void)
{
    // read state of PWM from master and send to slave
    i2c_start();
    i2c_write_byte(I2C_ADDRESS | I2C_WRITE);
    i2c_write_byte(0x00);
    i2c_start();
    i2c_write_byte(I2C_ADDRESS | I2C_READ);
    uint8_t state = i2c_read_byte(0);
    i2c_stop();
    // set PWM state
    if (state) {
        TCCR1B |= (1<<CS11);
    } else {
        TCCR1B &= ~(1<<CS11);
    }
}

void set_frequency(float frequency)
{
    // set PWM frequency
    pwm_set_frequency(frequency);
}

void increase_frequency(void)
{
    // increase PWM frequency by 25%
    float frequency = ICR1 * 1.25 / PWM_MAX_FREQ;
    frequency = (frequency > 1.0) ? 1.0 : frequency;
    set_frequency(frequency);
}

void decrease_frequency(void)
{
    // decrease PWM frequency by 20%
    float frequency = ICR1 * 0.8 / PWM_MAX_FREQ;
    set_frequency(frequency);
}

void set_duty_cycle(float duty_cycle)
{
    // set PWM duty cycle
    pwm_set_duty_cycle(duty_cycle);
}

void increase_duty_cycle(void)
{
    // increase PWM duty cycle by 10%
    float duty_cycle = OCR1A * 1.1 / ICR1;
    duty_cycle = (duty_cycle > 1.0) ? 1.0 : duty_cycle;
    set_duty_cycle(duty_cycle);
}

void decrease_duty_cycle(void)
{
    // decrease PWM duty cycle by 10%
    float duty_cycle = OCR1A * 0.9 / ICR1;
    set_duty_cycle(duty_cycle);
}

int main(void)
{
    // initialize I2C and PWM
    i2c_init();
    pwm_init();
    // set default PWM frequency and duty cycle
    set_frequency(1000);
    set_duty_cycle(0.5);
    // main loop
    while (1) {
        send_data();
        // read buttons and execute actions
        if (!(PIND & (1<<PD1))) { // increase frequency
            increase_frequency();
        }
        if (!(PIND & (1<<PD2))) { // decrease frequency
            decrease_frequency();
        }
        if (!(PIND & (1<<PD3))) { // increase duty cycle
            increase_duty_cycle();
        }
        if (!(PIND & (1<<PD4))) { // decrease duty cycle
            decrease_duty_cycle();
        }
        if (!(PIND & (1<<PD5))) { // turn on PWM
            TCCR1B |= (1<<CS11);
        }
        if (!(PIND & (1<<PD6))) { // turn off PWM
            TCCR1B &= ~(1<<CS11);
        }
        _delay_ms(50);
    }
}