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

#ifndef I2C_H
#define I2C_H

#include "gd32e23x_it.h"
#include "gd32e23x.h"
#include "systick.h"
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "board_config.h"

/******************************************************************************/

#define I2C_SPEED           100000U         /* 100kHz */
#define I2C_TIME_OUT        5000U           /* 5000 loops timeout */
#define I2C_MAX_RETRY       3U              /* Maximum retry attempts */
#define I2C_DELAY_10US      10U             /* Delay in microseconds for bus reset */
#define I2C_RECOVERY_CLOCKS 9U              /* Clock pulses for bus recovery */
#define I2C_MASTER_ADDRESS  0x00U           /* Master address (not used) */

/* Legacy compatibility */
#define I2C_OK              1
#define I2C_FAIL            0
#define I2C_END             1

/******************************************************************************/

/* I2C status enumeration */
typedef enum {
    I2C_STATUS_SUCCESS = 0,     /* Operation successful */
    I2C_STATUS_TIMEOUT,         /* Timeout occurred */
    I2C_STATUS_NACK,            /* No acknowledge received */
    I2C_STATUS_BUS_BUSY,        /* Bus is busy */
    I2C_STATUS_ERROR,           /* General error */
    I2C_STATUS_INVALID_PARAM    /* Invalid parameter */
} i2c_status_t;

/* I2C state machine enumeration */
typedef enum {
    I2C_STATE_IDLE = 0,         /* Idle state */
    I2C_STATE_START,            /* Generate start condition */
    I2C_STATE_SEND_ADDRESS,     /* Send slave address */
    I2C_STATE_CLEAR_ADDRESS,    /* Clear address flag */
    I2C_STATE_TRANSMIT_REG,     /* Transmit register address */
    I2C_STATE_TRANSMIT_DATA,    /* Transmit data */
    I2C_STATE_RESTART,          /* Generate restart condition */
    I2C_STATE_RECEIVE_DATA,     /* Receive data */
    I2C_STATE_STOP,             /* Generate stop condition */
    I2C_STATE_ERROR             /* Error state */
} i2c_state_t;

/* Legacy enumeration for compatibility */
typedef enum {
    I2C_START = 0,
    I2C_SEND_ADDRESS,
    I2C_CLEAR_ADDRESS_FLAG,
    I2C_TRANSMIT_DATA,
    I2C_STOP
} i2c_process_enum;

/******************************************************************************/

/* Function declarations */

/*!
    \brief      configure the GPIO ports for I2C
    \param[in]  none
    \param[out] none
    \retval     none
*/
void i2c_gpio_config(void);

/*!
    \brief      configure the I2C interface
    \param[in]  none
    \param[out] none
    \retval     i2c_status_t
*/
i2c_status_t i2c_config(void);

/*!
    \brief      reset I2C bus with proper recovery
    \param[in]  none
    \param[out] none
    \retval     i2c_status_t
*/
i2c_status_t i2c_bus_reset(void);

/*!
    \brief      scan I2C bus for devices
    \param[in]  none
    \param[out] none
    \retval     none
*/
void i2c_scan(void);

/*!
    \brief      write 16-bit data to I2C device
    \param[in]  slave_addr: 7-bit slave address
    \param[in]  reg_addr: register address
    \param[in]  data: pointer to 2-byte data array
    \param[out] none
    \retval     i2c_status_t
*/
i2c_status_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, const uint8_t data[2]);

/*!
    \brief      read 16-bit data from I2C device
    \param[in]  slave_addr: 7-bit slave address
    \param[in]  reg_addr: register address
    \param[out] data: pointer to 2-byte data buffer
    \retval     i2c_status_t
*/
i2c_status_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data);

/*!
    \brief      get status string for debugging
    \param[in]  status: i2c_status_t value
    \param[out] none
    \retval     const char* status string
*/
const char* i2c_get_status_string(i2c_status_t status);

#endif //I2C_H
