/**
  ******************************************************************************
  * @file    adc.h
  * @author  Разваляев Алексей
  * @brief   Драйвер ADC на основе PLIB035.
  *          Данный файл содержит определения типов, структур и прототипы функций
  *          для работы с ADC, включая:
  *           + Структуры и typedef для ADC
  *           + Прототипы функций для инициализации и API драйвера
  *
  ******************************************************************************
  */
#ifndef __ADC_H
#define __ADC_H
//-- Includes ------------------------------------------------------------------
#include "plib035.h"
#include "retarget_conf.h"

//-- Defines -------------------------------------------------------------------
// Дефайны для пинов ADC
#define ADC_Ch0_Pin        GPIO_Pin_0    /**< PB0 — ADC Channel 0 */
#define ADC_Ch0_GPIO_Port  GPIOB         /**< GPIO порт ADC Channel 0 */

#define ADC_Ch1_Pin        GPIO_Pin_1    /**< PB1 — ADC Channel 1 */
#define ADC_Ch1_GPIO_Port  GPIOB         /**< GPIO порт ADC Channel 1 */

#define ADC_Ch2_Pin        GPIO_Pin_2    /**< PB2 — ADC Channel 2 */
#define ADC_Ch2_GPIO_Port  GPIOB         /**< GPIO порт ADC Channel 2 */

#define ADC_Ch3_Pin        GPIO_Pin_3    /**< PB3 — ADC Channel 3 */
#define ADC_Ch3_GPIO_Port  GPIOB         /**< GPIO порт ADC Channel 3 */


//-- Types ---------------------------------------------------------------------
/**
  * @brief Типы callback-функций ADC
  */
typedef enum
{
  ADC_Callback_SeqCplt,   /*!< Преобразование секвенсора завершено */
  ADC_Callback_BuffHalf,  /*!< Буфер заполнен наполовину */
  ADC_Callback_BuffFull,  /*!< Буфер заполнен полностью */
  ADC_Callback_DCTrig,    /*!< Компаратор сработал */
  ADC_Callback_Error,     /*!< Ошибка */
}ADC_CallbackTypeDef;

/**
  * @brief Типы callback-функций ADC
  */
typedef struct
{
    unsigned Ch0:1; /*!< АЦП Канал 0 */
    unsigned Ch1:1; /*!< АЦП Канал 1 */
    unsigned Ch2:1; /*!< АЦП Канал 2 */
    unsigned Ch3:1; /*!< АЦП Канал 3 */
}ADC_ChannelEnableTypeDef;

/**
  * @brief Расширенная конфигурация секвенсора ADC
  */
typedef struct
{
  ADC_SEQ_Init_TypeDef SEQ_Init; /* Стандартная конфигурация из PLIB */
  FunctionalState IT;         /*!< Включить прерывания */
  uint8_t ITCount;            /*!< Количество запросов для генерации прерывания */
  FunctionalState BufferCircular;     /*!< Циклический буфер */
  
  
  void (*SEQCpltCallback)(void);   /*!< Вызывается при завершении секвенсора */
  void (*BuffHalfCallback)(void);  /*!< Вызывается при заполнении половины буфера */
  void (*BuffFullCallback)(void);  /*!< Вызывается при заполнении буфера */
  void (*ErrorCallback)();          /*!< Вызывается при ошибке */
}ADC_SEQ_ExtInit_TypeDef;

/**
  * @brief Расширенная конфигурация компаратора ADC
  */
typedef struct
{
  ADC_DC_Init_TypeDef DC_Init;
  FunctionalState IT;   /*!< Включить прерывания */  
  
  void (*DC_TrigCallback); /*!< Вызывается при срабатывании компаратора */
  void (*ErrorCallback)();    /*!< Вызывается при ошибке */    
}ADC_DC_ExtInit_TypeDef;

/**
  * @brief Хендл секвенсора ADC
  */
typedef struct
{
  ADC_SEQ_ExtInit_TypeDef *Config;  /*!< Конфигурации секвенсоров */  
  
  uint16_t *data_buffer;    /*!< Указатель на буфер данных [ch][buffer_size]*/
  uint32_t buffer_size;     /*!< Размер буфера (16-bit слова) */
  uint32_t buffer_count;    /*!< Счетчик текущего индекса буфера */
}ADC_SEQ_HandleTypeDef;

/**
  * @brief Хендл компаратора ADC
  */
typedef struct
{
  ADC_DC_ExtInit_TypeDef  *Config;  /*!< Конфигурации компараторов */
}ADC_DC_HandleTypeDef;

/**
  * @brief Хендл ADC
  */
typedef struct
{
  ADC_TypeDef *Instance;        /*!< Регистры ADC */
  
  ADC_SEQ_HandleTypeDef     SEQ[ADC_SEQ_Total]; /*!< Хендл секвенсоров */  
  ADC_DC_ExtInit_TypeDef    DC[ADC_DC_Total];   /*!< Хендл компараторов */
  
  /* ===== Channels ===== */
  ADC_ChannelEnableTypeDef  *ChannelEnable; /*!< Какие каналы АЦП инициализировать (GPIO Pin) */  
  uint16_t ChannelData[ADC_CH_Total];       /*!< Текущие значения каналов */
}ADC_HandleTypeDef;
//-- External handles ----------------------------------------------------------
extern ADC_HandleTypeDef hadc;

//-- Exported functions prototypes ---------------------------------------------
/* Первичная инициализация ADC */
void adc_init_first(void);
void adc_gpio_init(ADC_ChannelEnableTypeDef *ChEn);

/* ADC API functions */

/* Записать калибровочные значения канала */
OperationStatus ADC_Channel_Calibr(ADC_HandleTypeDef *hadc, ADC_CH_Num_TypeDef channel, int OFFSET, int GAIN);
/* Получение текущего значения канала */
uint16_t ADC_Channel_GetValue(ADC_HandleTypeDef *hadc, ADC_CH_Num_TypeDef channel);

/* Sequencer Init functions*/

/* Инициализация секвенсора АЦП */
OperationStatus adc_seq_init(ADC_HandleTypeDef *hadc, ADC_SEQ_Num_TypeDef SEQ_Num, ADC_SEQ_ExtInit_TypeDef *NewConfig);
/* Обработчик прерываний секвенсора */
void adc_seq_irq_handler(ADC_HandleTypeDef *hadc, ADC_SEQ_Num_TypeDef SEQ_Num);

/* Sequencer API functions */

/* Установка коллбека секвенсора АЦП */
OperationStatus ADC_SEQ_Set_Callback(ADC_HandleTypeDef* hadc, ADC_SEQ_Num_TypeDef SEQ_Num, ADC_CallbackTypeDef CallbackType, void (*Callback)(void));

/* Запуск секвенсора АЦП с буфером */
OperationStatus ADC_SEQ_Start(ADC_HandleTypeDef *hadc, ADC_SEQ_Num_TypeDef SEQ_Num, uint16_t (*data_buffer)[], uint32_t buffer_size);
/* Остановка секвенсора АЦП */
OperationStatus ADC_SEQ_Stop(ADC_HandleTypeDef *hadc, ADC_SEQ_Num_TypeDef SEQ_Num);

/* Программный запуск преобразования секвенсора */
void ADC_SEQ_SoftwareStart(void);




/* Comparator API functions*/

void adc_dc_handler(ADC_HandleTypeDef *hadc, ADC_DC_Num_TypeDef DC_Num);
#endif /*__ADC_H*/
