/** \file asa.h
 * Библиотека для управления аналоговым сигнатурным анализатором. Позволяет подключиться к серверно-аппаратной части, управлять настройками оборудования и получать сигнатуры.
 */

#ifndef LIBASA_H
#define LIBASA_H
#include "stdint.h"
#include "ivcmp.h"
#if defined(_WIN32) || defined (_WIN64) 
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif

/*********************************/
/*        Definitions            */
/*********************************/

#define MAX_NUM_POINTS        1000  /**< Максимально возможное количество точек кривой */
#define NUM_ALL_COMBINATIONS  380   /**< Количество возможных кобинаций настроек (частота пробного сигнала, амплитуда напряжения и амплитуда тока) */

#define COMPONENT_MODEL_TYPE_NONE       0  /**< Неопределённый тип */
#define COMPONENT_MODEL_TYPE_RESISTOR   1  /**< Резистор */
#define COMPONENT_MODEL_TYPE_CAPACITOR  2  /**< Конденсатор */

#define MODE_AUTO    0  /**< Автоматический запуск измерений. Устройство непрерывно проводит измерения и сохраняет результат последнего измерения */
#define MODE_MANUAL  1  /**< Ручной запуск измерений. Измерения производятся только в случае получения запроса от клиента (вызов функции TriggerMeasurement()) либо в случае нажатия аппаратной кнопки на щупе */

#define API_VERSION_MAJOR   0  /**< Основной номер версии протокола */
#define API_VERSION_MINOR   1  /**< Второстепенный номер версии протокола */
#define API_VERSION_BUGFIX  6  /**< Номер правок протокола */


#define status_t  int32_t
#define message_t char

/**
* Коды ошибок.
*/
#define ASA_OK                 0  /**< Всё работает штатно */
#define ASA_IN_PROGRESS        1  /**< Операция выполняется */
#define SERVER_RESPONSE_ERROR -1  /**< Некорректный ответ сервера */ 
#define INTERNAL_SERVER_ERROR -2  /**< В ходе выполнения функции на сервере возникала ошибка */
#define ASA_VALUE_ERROR       -3  /**< Сервером было получено значение вне допустимого диапазона */
#define ASA_TYPE_ERROR        -4  /**< Сервером было получено значение с неправильным типом */
#define ASA_FORMAT_ERROR      -5  /**< Сервером было получено значение с неправильным форматом или не получено вовсе */
#define ASA_CONNECTION_ERROR  -6  /**< Серверу не удалось подключиться к устройству */

/**
 * Типы калибровки.
 */
#define FAST_CLOSE_CALIBRATE          0  /**< Запуск калибровки для заданного набора параметров с замкнутыми щупами (калибровка наклона и калибровка по напряжению) */
#define FAST_OPEN_CALIBRATE           1  /**< Запуск калибровки для заданного набора параметров с разомкнутыми щупами (калибровка по току) */
#define FAST_CLOSE_CALIBRATE_AND_SAVE 2  /**< Запуск калибровки для заданного набора параметров с замкнутыми щупами (калибровка наклона и калибровка по напряжению) с сохранением результата в энергонезависимую память устройства */
#define FAST_OPEN_CALIBRATE_AND_SAVE  3  /**< Запуск калибровки для заданного набора параметров с разомкнутыми щупами (калибровка по току) с сохранением результата в энергонезависимую память устройства */
#define FULL_CLOSE_CALIBRATE_AND_SAVE 4  /**< Запуск калибровки для всех режимов с замкнутыми щупами (калибровка наклона и калибровка по напряжению) с сохранением результатов в энергонезависимую память устройства */
#define FULL_OPEN_CALIBRATE_AND_SAVE  5  /**< Запуск калибровки для всех режимов с разомкнутыми щупами (калибровка по току) с сохранением результатов в энергонезависимую память устройства */


/*********************************/
/*        Data types             */
/*********************************/

/**
 * Структура для хранения трёхциферных номеров версий.
 */
typedef struct
{
  uint8_t Major;   /**< Основной номер версии */
  uint8_t Minor;   /**< Второстепенный номер версии */
  uint8_t Bugfix;  /**< Номер правок */
} version_t;

/**
 * Структура для хранения ip и порта.
 */
typedef struct
{
  const char *Host;  /**< IP адрес или URL сервера. Данные хранятся в виде строки. Пример: "127.0.0.1" */
  const char *Port;  /**< Порт сервера. Пример: "8888" */
} server_t;

/**
 * Структура для хранения настроек сигнатурного анализатора.
 */
typedef struct
{
  double   SamplingRateHz;          /**< Частота дискретизации в Гц. Определяется устройством и зависит от текущей частоты пробного сигнала. При получении настроек возвращается актуальное для данной частоты пробного сигнала значение частоты дискретизации. При установке настроек данное поле никак не влияет на параметры работы устройства. */
  double   ProbeSignalFrequencyHz;  /**< Частота пробного сигнала в Гц. */
  uint32_t NumberPoints;            /**< Количество точек, образующих кривую (одно измерение). */
  uint32_t NumberChargePoints;      /**< Значение данного поля не должно использоваться в прикладном ПО. Добавлено для совместимости с другими устройствами. */
  double   VoltageAmplV;            /**< Амплитуда пробного сигнала по напряжению в В. Важно! Данный параметр вместе с параметром MaxCurrentMA должен принимать значения строго в соответствии со спецификацией. */
  double   MaxCurrentMA;            /**< Максимальный ток в мА (определяет выбор токоизмерительного резистора). Важно! Данный параметр вместе с параметром VoltageAmplV должен принимать значения строго в соответствии со спецификацией. */
  uint32_t MeasureFlags;            /**< Значение данного поля не должно использоваться в прикладном ПО. Добавлено для совместимости с другими устройствами. */
  uint32_t DebugModelType;          /**< Модель измеряемого элемента. Используется для отладки совместно с виртуальным измерителем. В нормальном режиме работы смысла не имеет. Принимает одно из значений:  COMPONENT_MODEL_TYPE_NONE, COMPONENT_MODEL_TYPE_RESISTOR или COMPONENT_MODEL_TYPE_CAPACITOR. */
  double   DebugModelNominal;       /**< Номинал измеряемого компонента. Для резистора в Омах. Для конденсатора в Фарадах. Используется для отладки совместно с виртуальным измерителем. В нормальном режиме работы смысла не имеет.*/
  uint32_t TriggerMode;             /**< Режим запуска измерений. Принимает одно из значений: COMPONENT_TRIGGER_AUTO (непрерывный автоматический запуск измерений), COMPONENT_TRIGGER_MANUAL (запуск измерений по запросу клиента или по нажатию аппаратной кнопки запуска измерений на щупе). */
} asa_settings_t;

/**
 * Структура для передачи измеренной сигнатуры.
 */
typedef struct
{
  double Voltages[MAX_NUM_POINTS];  /**< Массив напряжений (координат сигнатуры по напряжению). Единицы измерения: Вольты. Количество актуальных значений может быть меньше MAX_NUM_POINTS и определяется текущими настройками измерителя (поле NumberPoints структуры asa_settings_t).Актуальные значения располагаются начиная с нулевого элемент массива. */
  double Currents[MAX_NUM_POINTS];  /**< Массив токов (координат сигнатуры по току). Единицы измерения: мА. Количество актуальных значений может быть меньше MAX_NUM_POINTS и определяется текущими настройками измерителя (поле NumberPoints структуры asa_settings_t). Актуальные значения располагаются начиная с нулевого элемент массива. */
} iv_curve_t;

/**
 * Структура для передачи состояния кнопок щупов.
 */
typedef struct
{
  uint32_t GrayProbeButton;  /**< Состояние кнопки щупа-генератора. 1 - если кнопка нажата, 0 - если нет. */
  uint32_t BlueProbeButton;  /**< Состояние кнопки щупа-измерителя. 1 - если кнопка нажата, 0 - если нет. */
} asa_buttons_t;

/**
 * Структура для температуры и индикаторов превышения температуры щупов.
 */
typedef struct
{
  uint32_t GrayTemperature;  /**< Температура кнопки щупа-генератора. Значение в градусах. */
  uint32_t BlueTemperature;  /**< Температура кнопки щупа-измерителя. Значение в градусах. */
  uint32_t GrayOverheat;     /**< Индикатор превышения температуры кнопки щупа-измерителя допустимого порога. 1 - температура превышена, 0 - нет. */
  uint32_t BlueOverheat;     /**< Индикатор превышения температуры кнопки щупа-измерителя допустимого порога. 1 - температура превышена, 0 - нет. */
} asa_temperature_t;

/**
* Таблица соотвествия коэффициентов калибровки и значений резисторов настройкам устройства (частота пробного сигнала, амплитуда напряжения, максимальный ток).
*/
typedef struct
{
  double ProbeFrequencyArray[NUM_ALL_COMBINATIONS];       /**< Массив частот пробного сигнала. */
  double VoltageAmplArray[NUM_ALL_COMBINATIONS];          /**< Массив амплитуд пробного сигнала по напряжению в В. */
  double MaxCurrentArray[NUM_ALL_COMBINATIONS];           /**< Массив максимальных токов в мА. */
  uint32_t LimitResistorArray[NUM_ALL_COMBINATIONS];      /**< Массив токоораничительных резисторов в Ом. */
  uint32_t SenseResistorArray[NUM_ALL_COMBINATIONS];      /**< Массив токоизмерительных резисторов в Ом. */
  uint32_t CurCalibrationArray[NUM_ALL_COMBINATIONS];     /**< Массив коэффициентов калибровки по осям для тока. */
  uint32_t VoltCalibrationArray[NUM_ALL_COMBINATIONS];    /**< Массив коэффициентов калибровки по осям для напряжения. */
  uint32_t CurCalibrationKZArray[NUM_ALL_COMBINATIONS];   /**< Массив коэффициентов калибровки наклона для тока. */
  uint32_t VoltCalibrationKZArray[NUM_ALL_COMBINATIONS];  /**< Массив коэффициентов калибровки наклона для напряжения. */
} asa_coefficients_t;


/*********************************/
/*         Functions             */
/*********************************/

/**
 * Функция для получения версии используемой библиотеки.
 * @param[out] Version Версия библиотеки.
 */
EXPORT version_t GetLibraryVersion(void);

/**
 * Функция для получения версии протокола.
 * @param[out] Version Версия протокола.
 */
EXPORT version_t GetAPIVersion(void);

/**
 * Функция для установки настроек сигнатурного анализатора.
 * Установленные настройки будут применены ко всем последующим измерениями
 * до следующего вызова функции установки настроек либо до аппаратной перезагрузке устройства.
 * Настройки измерителя могут быть независимо изменены другими клиентскими приложениями.
 * Для получения актуальных настроек измерителя используйте функцию GetSettings().
 * @param[in] Server Указатель на структуру с параметрами подключения сервера.
 * @param[in] Settings Указатель на структуру с настройками, которые требуется установить.
 * @param[out] Status Код статуса завершения. Если функция завершилась успешно, должен быть возвращён статус ASA_OK.
 */
EXPORT status_t SetSettings(server_t *Server, asa_settings_t *Settings);

/**
 * Функция для получения настроек сигнатурного анализатора.
 * Настройки могут быть изменены с помощью явного вызова функции SetSettings(),
 * перезагрузки измерителя, а также из других клиентских приложений.
 * @param[in] Server Указатель на структуру с параметрами подключения сервера.
 * @param[in] Settings Указатель на структуру, в которую будут записаны актуальные настройки.
 * @param[out] Status Код статуса завершения. Если функция завершилась успешно, должен быть возвращён статус ASA_OK.
 */
EXPORT status_t GetSettings(server_t *Server, asa_settings_t *Settings);

/**
 * Функция для получения измеренной сигнатуры. Возвращает результат последнего измерения.
 * Для запуска измерений в ручном режиме используется функция TriggerMeasurement()
 * либо аппаратная кнопка запуска измерений на щупе.
 * Режим измерений определяется полем TriggerMode в структуре asa_settings_t.
 * @param[in] Server Указатель на структуру с параметрами подключения сервера.
 * @param[in] IVC Указатель на структуру, в которую будет записан результат измерения.
 * @param[in] size Количество точек сигнатуры. Зависит от текущих настроек измерителя. Определяется значением поля NumberPoints в структуре asa_settings_t.
 * @param[out] Status Код статуса завершения. Если функция завершилась успешно, должен быть возвращён статус ASA_OK.
 */
EXPORT status_t GetIVCurve(server_t *Server, iv_curve_t *IVC, uint32_t size);

/**
 * Функция осуществляет запуск единичного измерения.
 * Актуальна только для ручного режима запуска измерений (определяется параметром TriggerMode структуры asa_settings_t).
 * Результат измерения можно получить с помощью функции GetIVCurve().
 * Вызов данной функции эквивалентен нажатию аппаратной кнопки запуска измерений на щупе.
 * @param[in] Server Указатель на структуру с параметрами подключения сервера.
 * @param[out] Status Код статуса завершения. Если функция завершилась успешно, должен быть возвращён статус ASA_OK.
 */
EXPORT status_t TriggerMeasurement(server_t *Server);

/**
 * Функция запускает калибровку в зависимости от выбранного типа.
 * Актуальна только для реального режима запуска измерений.
 * Результат измерения можно получить с помощью функции GetIVCurve().
 * @param[in] Server Указатель на структуру с параметрами подключения сервера.
 * @param[in] Type Тип калибровки.
 * @param[out] Status Код статуса завершения. Если функция завершилась успешно, должен быть возвращён статус ASA_OK.
 */
EXPORT status_t Calibrate(server_t *Server, uint8_t Type);

/**
 * Функция возвращает статус кнопок щупов.
 * @param[in] Server Указатель на структуру с параметрами подключения сервера.
 * @param[in] Buttons содержит статусы кнопок.
 * @param[out] Status Код статуса завершения. Если функция завершилась успешно, должен быть возвращён статус ASA_OK.
 */
EXPORT status_t GetStatusButtons(server_t *Server, asa_buttons_t *Buttons);

/**
 * Функция возвращает температуру щупов.
 * @param[in] Server Указатель на структуру с параметрами подключения сервера.
 * @param[in] Temperature - структура для хранения величин температуры и индикаторов превышения температуры щупов.
 * @param[out] Status Код статуса завершения. Если функция завершилась успешно, должен быть возвращён статус ASA_OK.
 */
EXPORT status_t GetTempProbes(server_t *Server, asa_temperature_t *Temperature);

/**
 * Функция возвращает количество точек в одном периоде. Количество точек зависит от частоты и поэтому нужно вызывать эту функцию каждый раз при её изменении.
 * @param[in] Settings Указатель на структуру с параметрами настроек. Настройки обязательно должны быть получены с устройства, чтобы все поля в них соответствовали параметрам, которые в данный момент установлены на устройстве.
 * @param[out] OnePeriodPoints количество точек в одном периоде.
 */
EXPORT uint32_t GetNumberPointsForSinglePeriod(asa_settings_t *Settings);

/**
 * Функция позволяет узнать результат последней операции. В случае, если операция еще выполняется, функция возвращает ASA_IN_PROGRESS.
 * @param[in] Settings Указатель на структуру с параметрами настроек. Настройки обязательно должны быть получены с устройства, чтобы все поля в них соответствовали параметрам, которые в данный момент установлены на устройстве.
 * @param[out] OperationStatus статус выполнения последней операции.
 */
EXPORT status_t GetLastOperationResult(server_t *Server);

/**
* Функция загружает таблицу соответствия частот, напряжения, токов, резисторов и калибровочных коэффициентов в буффер.
* @param[in] FileName Имя файла, из котрого нужно загрузить таблицу.
* @param[in] C Структура, хранящая в себе таблицу соответствия частот, напряжения, токов, резисторов и калибровочных коэффициентов.
*/
EXPORT void LoadCoefficientTable(char *FileName, asa_coefficients_t *C);

/**
* Функция сохраняет таблицу соответствия частот, напряжения, токов, резисторов и калибровочных коэффициентов в файл.
* @param[in] FileName Имя файла, в который нужно сохранить таблицу.
* @param[in] C Структура, хранящая в себе таблицу соответствия частот, напряжения, токов, резисторов и калибровочных коэффициентов.
*/
EXPORT void SaveCoefficientTable(char *FileName, asa_coefficients_t *C);

/**
* Функция отправляет таблицу соответствия частот, напряжения, токов, резисторов и калибровочных коэффициентов серверу для последующей установки значений на устройство.
* @param[in] Server Указатель на структуру с параметрами подключения сервера.
* @param[in] C Структура, хранящая в себе таблицу соответствия частот, напряжения, токов, резисторов и калибровочных коэффициентов.
* @param[out] Status Код статуса завершения. Если функция завершилась успешно, должен быть возвращён статус ASA_OK.
*/
EXPORT status_t SetCoefficients(server_t *Server, asa_coefficients_t *C);

/**
* Функция отправляет запрос на получение таблицы соответствия частот, напряжения, токов, резисторов и калибровочных коэффициентов с сервера.
* @param[in] Server Указатель на структуру с параметрами подключения сервера.
* @param[in] C Структура, хранящая в себе таблицу соответствия частот, напряжения, токов, резисторов и калибровочных коэффициентов.
* @param[out] Status Код статуса завершения. Если функция завершилась успешно, должен быть возвращён статус ASA_OK.
*/
EXPORT status_t GetCoefficients(server_t *Server, asa_coefficients_t *C);

#endif // LIBASA_H
