#include <math.h>
#include "common.h"
#include "softiic.h"

int sda_pin = 0; // GPIO0
int scl_pin = 1; // GPIO1

// 软件 I2C 延时
void i2c_delay() {
    delayMicroseconds(5); // ~5μs 延迟，适配 100kHz I2C
}

// 初始化 I2C 引脚
int softiic_init() {
    pinMode(sda_pin, OUTPUT);
    pinMode(scl_pin, OUTPUT);
    digitalWrite(sda_pin, HIGH);
    digitalWrite(scl_pin, HIGH);
    return 0;
}

// I2C 起始信号
void i2c_start() {
    pinMode(sda_pin, OUTPUT);
    digitalWrite(sda_pin, HIGH);
    digitalWrite(scl_pin, HIGH);
    i2c_delay();
    digitalWrite(sda_pin, LOW);
    i2c_delay();
    digitalWrite(scl_pin, LOW);
    i2c_delay();
}

// I2C 停止信号
void i2c_stop() {
    pinMode(sda_pin, OUTPUT);
    digitalWrite(sda_pin, LOW);
    digitalWrite(scl_pin, LOW);
    i2c_delay();
    digitalWrite(scl_pin, HIGH);
    i2c_delay();
    digitalWrite(sda_pin, HIGH);
    i2c_delay();
}

// I2C 发送一个字节，并检查 ACK（不返回，但内部可判断是否 ACK）
void i2c_write_byte(uint8_t data) {
    pinMode(sda_pin, OUTPUT);
    for (int i = 7; i >= 0; i--) {
        digitalWrite(sda_pin, (data >> i) & 0x01);
        i2c_delay();
        digitalWrite(scl_pin, HIGH);
        i2c_delay();
        digitalWrite(scl_pin, LOW);
        i2c_delay();
    }

    // 接收 ACK
    pinMode(sda_pin, INPUT);           // 释放 SDA
    i2c_delay();
    digitalWrite(scl_pin, HIGH);
    i2c_delay();

    int ack = digitalRead(sda_pin);    // 0 = ACK，1 = NACK（你可以打印或设置状态变量）

    digitalWrite(scl_pin, LOW);
    pinMode(sda_pin, OUTPUT);          // 拉回输出模式
    i2c_delay();
}

// I2C 读取一个字节并发送 ACK/NACK
uint8_t i2c_read_byte(bool ack) {
    uint8_t data = 0;
    pinMode(sda_pin, INPUT);

    for (int i = 7; i >= 0; i--) {
        digitalWrite(scl_pin, HIGH);
        i2c_delay();
        data |= (digitalRead(sda_pin) << i);
        digitalWrite(scl_pin, LOW);
        i2c_delay();
    }

    pinMode(sda_pin, OUTPUT);
    digitalWrite(sda_pin, ack ? LOW : HIGH); // 发送 ACK or NACK
    i2c_delay();
    digitalWrite(scl_pin, HIGH);
    i2c_delay();
    digitalWrite(scl_pin, LOW);
    i2c_delay();
    pinMode(sda_pin, INPUT);

    return data;
}
