//
// Created by dell on 24-12-3.
//

#include "LDC1612.h"



void I2C_config(void) {
    rcu_periph_clock_enable(RCU_IR_GPIO);
    rcu_periph_clock_enable(RCU_I2C);

    gpio_af_set(I2C_SCL_PORT, I2C_GPIO_AF, I2C_SCL_PIN);
    gpio_af_set(I2C_SDA_PORT, I2C_GPIO_AF, I2C_SDA_PIN);

    gpio_mode_set(I2C_SCL_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SCL_PIN);
    gpio_output_options_set(I2C_SCL_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SCL_PIN);

    gpio_mode_set(I2C_SDA_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SDA_PIN);
    gpio_output_options_set(I2C_SDA_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SDA_PIN);

    i2c_clock_config(I2C0, I2C_SPEED, I2C_DTCY_2);

    // i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, LDC1612_ADDR);
    i2c_enable(I2C0);
    i2c_ack_config(I2C0, I2C_ACK_ENABLE);
}

// void LDC1612_Init(void) {
//     uint8_t RCOUNT0_ALL[3]={SET_CONVERSION_TIME_REG_START,0x05,0x36};//csdn
//     uint8_t SETTLECOUNT0_ALL[3]={SET_LC_STABILIZE_REG_START,0x00,0x0a};
//     uint8_t CLOCK_DIVIDERS0_ALL[3]={SET_FREQ_REG_START,0x10,0x02};
//     uint8_t ERROR_CONFIG_ALL[3]={ERROR_CONFIG_REG,0x00,0x00};
//     uint8_t MUX_CONFIG_ALL[3]={MUL_CONFIG_REG,0x82,0x0c};
//     uint8_t DRIVE_CURRENT0_ALL[3]={SET_DRIVER_CURRENT_REG,0x90,0x00};
//     uint8_t CONFIG_ALL[3]={SENSOR_CONFIG_REG,0x14,0x01};//csdn
//
// }

/**
 * @brief 扫描I2C总线，查找连接的设备
 *
 * 该函数会扫描I2C总线上的所有地址（1到126），并尝试与每个地址进行通信。
 * 如果在某个地址上发现了设备，则会打印出该设备的地址。
 * 最后会打印出找到的设备总数。
 */
void I2C_scan(void) {
    uint32_t timeout;
    uint8_t address;
    int found_devices = 0;

    printf("Scanning I2C bus...\r\n");

    for (address = 1; address < 127; address++) {
        timeout = 0;

        // 生成起始条件
        while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT))
            timeout++;
        if (timeout >= I2C_TIME_OUT) {
            continue; // 超时，跳过该地址
        }
        i2c_start_on_bus(I2C0);
        timeout = 0;

        // 等待起始条件发送完成
        while (!i2c_flag_get(I2C0, I2C_FLAG_SBSEND) && (timeout < I2C_TIME_OUT))
            timeout++;
        if (timeout >= I2C_TIME_OUT) {
            continue; // 超时，跳过该地址
        }
        i2c_master_addressing(I2C0, (address << 1), I2C_TRANSMITTER);
        timeout = 0;

        // 等待地址发送完成
        while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND) && (timeout < I2C_TIME_OUT))
            timeout++;
        if (timeout < I2C_TIME_OUT) {
            i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
            printf("Found device at 0x%02X\r\n", address);
            found_devices++;
        }

        // 生成停止条件
        i2c_stop_on_bus(I2C0);

        timeout = 0;

        while (i2c_flag_get(I2C0, I2C_FLAG_STPDET) && (timeout < I2C_TIME_OUT))
            timeout++;
    }

    if (found_devices == 0) {
        printf("No I2C devices found.\r\n");
    } else {
        printf("Total %d I2C devices found.\r\n", found_devices);
    }
}

int LDC1612_IIC_read_16bits(uint8_t reg, uint16_t *data) {
    uint32_t timeout = 0;
    i2c_ack_config(I2C0, I2C_ACK_ENABLE);

    while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) //判断IIC总线是否忙，发送起始信号
        timeout++;
    if (timeout < I2C_TIME_OUT) {
        i2c_start_on_bus(I2C0);
        timeout = 0;
    } else {
        printf("err\r\n");
        return -1; // 超时返回错误
    }

    while (!i2c_flag_get(I2C0, I2C_FLAG_SBSEND) && (timeout < I2C_TIME_OUT)) //判断起始位是否发送，设置sensor地址并设置为写
        timeout++;
    if (timeout < I2C_TIME_OUT) {
        i2c_master_addressing(I2C0, LDC1612_ADDR, I2C_TRANSMITTER);
        timeout = 0;
    } else {
        return -1; // 超时返回错误
    }

    while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND) && (timeout < I2C_TIME_OUT))
        timeout++;
    if (timeout < I2C_TIME_OUT) {
        i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
        timeout = 0;
    } else {
        return -1; // 超时返回错误
    }

    while (!i2c_flag_get(I2C0, I2C_FLAG_TBE) && (timeout < I2C_TIME_OUT)) //判断地址是否发送完成，然后发送寄存器地址
        timeout++;
    if (timeout < I2C_TIME_OUT) {
        i2c_data_transmit(I2C0, reg);
        timeout = 0;
        // i2c_start_on_bus(I2C0);
    } else {
        return -1; // 超时返回错误
    }

    while (i2c_flag_get(I2C0, I2C_FLAG_BTC) && (timeout < I2C_TIME_OUT)) //判断发送缓冲器是否为空，为空后（发送完毕）重新发送开始信号
        timeout++;
    if (timeout < I2C_TIME_OUT) {
        i2c_start_on_bus(I2C0);
        timeout = 0;
    } else {
        return -1; // 超时返回错误
    }

    while (!i2c_flag_get(I2C0, I2C_FLAG_SBSEND) && (timeout < I2C_TIME_OUT)) {
        timeout++;
    }
    if (timeout < I2C_TIME_OUT) {
        i2c_master_addressing(I2C0, LDC1612_ADDR, I2C_RECEIVER);
        timeout = 0;
    } else {
        return -1; // 超时返回错误
    }

    while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND) && (timeout < I2C_TIME_OUT))
        timeout++;
    if (timeout < I2C_TIME_OUT) {
        i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
        timeout = 0;
    } else {
        return -1; // 超时返回错误
    }

    // 读取第一个字节的数据
    while (!i2c_flag_get(I2C0, I2C_FLAG_RBNE) && (timeout < I2C_TIME_OUT)) {
        timeout++;
    }
    if (timeout < I2C_TIME_OUT) {
        data[0] = i2c_data_receive(I2C0);
        timeout = 0;
    } else {
        return -1; // 超时返回错误
    }

    i2c_ack_config(I2C0, I2C_ACK_DISABLE); // 关闭发送ACK，它会在下一个字节完成后发送NAK

    // 读取第二个字节的数据
    while (!i2c_flag_get(I2C0, I2C_FLAG_RBNE) && (timeout < I2C_TIME_OUT)) {
        timeout++;
    }
    if (timeout < I2C_TIME_OUT) {
        data[1] = i2c_data_receive(I2C0);
        timeout = 0;
    } else {
        return -1; // 超时返回错误
    }

    i2c_stop_on_bus(I2C0);

    return 0;
}