#include <Wire.h>
#define I2C_FREQ 100000UL

// Адрес устройства из задания 7
const int deviceAddress = 8;

// Регистры устройства
byte reg1 = 0;
byte reg2 = 0;

void setup() {
    // Инициализация I2C
    i2c_begin();
    // Назначение функции-обработчика для приема данных по I2C
    Wire.onReceive(receiveData);

    // Настройка пинов для кнопок
    pinMode(2, INPUT_PULLUP);
    pinMode(3, INPUT_PULLUP);
    pinMode(4, INPUT_PULLUP);
    pinMode(5, INPUT_PULLUP);
    pinMode(6, INPUT_PULLUP);
    pinMode(7, INPUT_PULLUP);
}

void loop() {
    // Обработка нажатий кнопок
    if (digitalRead(2) == LOW) {
        // Включить ШИМ
        reg1 |= 0b00000001;
        sendData();
    } else if (digitalRead(3) == LOW) {
        // Выключить ШИМ
        reg1 &= 0b11111110;
        sendData();
    } else if (digitalRead(4) == LOW) {
        // Увеличить частоту на 25%
        reg1 |= 0b00000010;
        sendData();
    } else if (digitalRead(5) == LOW) {
        // Уменьшить частоту на 20%
        reg1 |= 0b00000100;
        sendData();
    } else if (digitalRead(6) == LOW) {
        // Увеличить скважность
        reg2 |= 0b00000001;
        sendData();
    } else if (digitalRead(7) == LOW) {
        // Уменьшить скважность
        reg2 &= 0b11111110;
        sendData();
    }
}

// Функция-обработчик для приема данных по I2C
void receiveData(int byteCount) {
    while (Wire.available()) {
        byte reg = Wire.read();
        byte value = Wire.read();
        // Запись значения в соответствующий регистр
        if (reg == 1) {
            reg1 = value;
            // Включение ШИМ
            if (bitRead(reg1, 0) == 1) {
                analogWrite(9, 128);
            } else {
                analogWrite(9, 0);
            }
            // Изменение частоты ШИМ
            if (bitRead(reg1, 1) == 1) {
                analogWriteFrequency(9, 25000);
            } else if (bitRead(reg1, 2) == 1) {
                analogWriteFrequency(9, 8000);
            }
        } else if (reg == 2) {
            reg2 = value;
            // Изменение скважности ШИМ
            int dutyCycle = map(reg2, 0, 255, 0, 1023);
            analogWrite(9, dutyCycle);
        }
    }
}

// Функция для отправки данных по I2C
void sendData() {
    Wire.beginTransmission(deviceAddress);
    // Отправка значений регистров
    Wire.write(1);
    Wire.write(reg1);
    Wire.write(2);
    Wire.write(reg2);
    Wire.endTransmission();
}