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

#ifndef HAL_ADC_H
#define HAL_ADC_H

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

/**
 * @brief ADC instance identifier definitions
 */
typedef enum {
    HAL_ADC_INSTANCE_1 = 0,
    HAL_ADC_INSTANCE_2,
    HAL_ADC_INSTANCE_3,
    HAL_ADC_INSTANCE_MAX
} hal_adc_instance_t;

/**
 * @brief ADC resolution definitions
 */
typedef enum {
    HAL_ADC_RESOLUTION_12B = 0,
    HAL_ADC_RESOLUTION_10B,
    HAL_ADC_RESOLUTION_8B,
    HAL_ADC_RESOLUTION_6B
} hal_adc_resolution_t;

/**
 * @brief ADC channel definitions
 */
typedef enum {
    HAL_ADC_CHANNEL_0 = 0,
    HAL_ADC_CHANNEL_1,
    HAL_ADC_CHANNEL_2,
    HAL_ADC_CHANNEL_3,
    HAL_ADC_CHANNEL_4,
    HAL_ADC_CHANNEL_5,
    HAL_ADC_CHANNEL_6,
    HAL_ADC_CHANNEL_7,
    HAL_ADC_CHANNEL_8,
    HAL_ADC_CHANNEL_9,
    HAL_ADC_CHANNEL_10,
    HAL_ADC_CHANNEL_11,
    HAL_ADC_CHANNEL_12,
    HAL_ADC_CHANNEL_13,
    HAL_ADC_CHANNEL_14,
    HAL_ADC_CHANNEL_15,
    HAL_ADC_CHANNEL_16,
    HAL_ADC_CHANNEL_17,
    HAL_ADC_CHANNEL_18,
    HAL_ADC_CHANNEL_MAX
} hal_adc_channel_t;

/**
 * @brief ADC sample time definitions
 */
typedef enum {
    HAL_ADC_SAMPLETIME_3CYCLES = 0,
    HAL_ADC_SAMPLETIME_15CYCLES,
    HAL_ADC_SAMPLETIME_28CYCLES,
    HAL_ADC_SAMPLETIME_56CYCLES,
    HAL_ADC_SAMPLETIME_84CYCLES,
    HAL_ADC_SAMPLETIME_112CYCLES,
    HAL_ADC_SAMPLETIME_144CYCLES,
    HAL_ADC_SAMPLETIME_480CYCLES
} hal_adc_sampletime_t;

/**
 * @brief ADC channel configuration structure
 */
typedef struct {
    hal_adc_channel_t channel;
    hal_adc_sampletime_t sampletime;
    uint8_t rank;
    uint8_t enable;
} hal_adc_channel_config_t;

/**
 * @brief ADC configuration structure
 */
typedef struct {
    hal_adc_instance_t instance;
    hal_adc_resolution_t resolution;
    uint8_t scan_conversion_mode;
    uint8_t continuous_conversion_mode;
    uint8_t discontinuous_conversion_mode;
    uint8_t discontinuous_number_of_conversions;
    uint8_t nbr_of_conversions;
    uint8_t channel_count;
    const hal_adc_channel_config_t* channels;
    uint32_t timeout;
} hal_adc_config_t;

/**
 * @brief Initialize ADC hardware
 * @param config: ADC configuration structure
 * @retval HAL status code
 */
hal_ret_t hal_adc_init(const hal_adc_config_t *config);

/**
 * @brief Deinitialize ADC hardware
 * @param instance: ADC instance identifier
 * @retval HAL status code
 */
hal_ret_t hal_adc_deinit(hal_adc_instance_t instance);

/**
 * @brief Start ADC conversion
 * @param instance: ADC instance identifier
 * @retval HAL status code
 */
hal_ret_t hal_adc_start(hal_adc_instance_t instance);

/**
 * @brief Stop ADC conversion
 * @param instance: ADC instance identifier
 * @retval HAL status code
 */
hal_ret_t hal_adc_stop(hal_adc_instance_t instance);

/**
 * @brief Get ADC conversion value
 * @param instance: ADC instance identifier
 * @param channel: ADC channel
 * @param value: Pointer to store conversion value
 * @param timeout: Timeout in milliseconds
 * @retval HAL status code
 */
hal_ret_t hal_adc_get_value(hal_adc_instance_t instance, hal_adc_channel_t channel, uint16_t *value, uint32_t timeout);

/**
 * @brief Get multiple ADC conversion values
 * @param instance: ADC instance identifier
 * @param values: Pointer to store conversion values
 * @param length: Number of values to get
 * @param timeout: Timeout in milliseconds
 * @retval HAL status code
 */
hal_ret_t hal_adc_get_values(hal_adc_instance_t instance, uint16_t *values, uint8_t length, uint32_t timeout);

/**
 * @brief Configure ADC channel
 * @param instance: ADC instance identifier
 * @param config: ADC channel configuration structure
 * @retval HAL status code
 */
hal_ret_t hal_adc_configure_channel(hal_adc_instance_t instance, const hal_adc_channel_config_t *config);

/**
 * @brief Enable ADC channel
 * @param instance: ADC instance identifier
 * @param channel: ADC channel
 * @retval HAL status code
 */
hal_ret_t hal_adc_enable_channel(hal_adc_instance_t instance, hal_adc_channel_t channel);

/**
 * @brief Disable ADC channel
 * @param instance: ADC instance identifier
 * @param channel: ADC channel
 * @retval HAL status code
 */
hal_ret_t hal_adc_disable_channel(hal_adc_instance_t instance, hal_adc_channel_t channel);

#endif /* HAL_ADC_H */