/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : hal_i2c.h
  * @brief          : I2C hardware abstraction layer header file
  ******************************************************************************
  */
/* USER CODE END Header */

#ifndef HAL_I2C_H
#define HAL_I2C_H

#include <stdint.h>
#include <stddef.h>
#include "hal.h"

/**
 * @brief I2C instance identifier definitions
 */
typedef enum {
    HAL_I2C_INSTANCE_1 = 0,
    HAL_I2C_INSTANCE_2,
    HAL_I2C_INSTANCE_3,
    HAL_I2C_INSTANCE_4,
    HAL_I2C_INSTANCE_MAX
} hal_i2c_instance_t;

/**
 * @brief I2C clock speed definitions
 */
typedef enum {
    HAL_I2C_SPEED_STANDARD = 100000U,    /*!< Standard speed (100 kHz) */
    HAL_I2C_SPEED_FAST = 400000U,        /*!< Fast speed (400 kHz) */
    HAL_I2C_SPEED_FAST_PLUS = 1000000U,  /*!< Fast plus speed (1 MHz) */
    HAL_I2C_SPEED_HIGH = 3400000U        /*!< High speed (3.4 MHz) */
} hal_i2c_speed_t;

/**
 * @brief I2C address mode definitions
 */
typedef enum {
    HAL_I2C_ADDRESS_7BIT = 0,
    HAL_I2C_ADDRESS_10BIT
} hal_i2c_address_mode_t;

/**
 * @brief I2C duty cycle definitions
 */
typedef enum {
    HAL_I2C_DUTYCYCLE_2 = 0,
    HAL_I2C_DUTYCYCLE_16_9
} hal_i2c_dutycycle_t;

/**
 * @brief I2C configuration structure
 */
typedef struct {
    hal_i2c_instance_t instance;
    hal_i2c_speed_t speed;
    hal_i2c_address_mode_t address_mode;
    hal_i2c_dutycycle_t dutycycle;
    uint16_t own_address1;
    uint32_t timeout;
} hal_i2c_config_t;

/**
 * @brief Initialize I2C hardware
 * @param config: I2C configuration structure
 * @retval HAL status code
 */
hal_ret_t hal_i2c_init(const hal_i2c_config_t *config);

/**
 * @brief Deinitialize I2C hardware
 * @param instance: I2C instance identifier
 * @retval HAL status code
 */
hal_ret_t hal_i2c_deinit(hal_i2c_instance_t instance);

/**
 * @brief Transmit data to I2C slave
 * @param instance: I2C instance identifier
 * @param dev_address: Slave device address
 * @param data: Pointer to data buffer
 * @param length: Data length in bytes
 * @param timeout: Timeout in milliseconds
 * @retval HAL status code
 */
hal_ret_t hal_i2c_master_transmit(hal_i2c_instance_t instance, uint16_t dev_address, const uint8_t *data, uint16_t length, uint32_t timeout);

/**
 * @brief Receive data from I2C slave
 * @param instance: I2C instance identifier
 * @param dev_address: Slave device address
 * @param data: Pointer to data buffer
 * @param length: Data length to receive in bytes
 * @param timeout: Timeout in milliseconds
 * @retval HAL status code
 */
hal_ret_t hal_i2c_master_receive(hal_i2c_instance_t instance, uint16_t dev_address, uint8_t *data, uint16_t length, uint32_t timeout);

/**
 * @brief Transmit and receive data from I2C slave
 * @param instance: I2C instance identifier
 * @param dev_address: Slave device address
 * @param tx_data: Pointer to transmit data buffer
 * @param tx_length: Transmit data length in bytes
 * @param rx_data: Pointer to receive data buffer
 * @param rx_length: Receive data length in bytes
 * @param timeout: Timeout in milliseconds
 * @retval HAL status code
 */
hal_ret_t hal_i2c_master_transmit_receive(hal_i2c_instance_t instance, uint16_t dev_address, const uint8_t *tx_data, uint16_t tx_length, uint8_t *rx_data, uint16_t rx_length, uint32_t timeout);

/**
 * @brief Check if I2C bus is ready
 * @param instance: I2C instance identifier
 * @param dev_address: Slave device address
 * @param trials: Number of trials
 * @param timeout: Timeout in milliseconds
 * @retval HAL status code
 */
hal_ret_t hal_i2c_is_device_ready(hal_i2c_instance_t instance, uint16_t dev_address, uint32_t trials, uint32_t timeout);

#endif /* HAL_I2C_H */