#ifndef LTR25API_H_
#define LTR25API_H_

#include "ltrapi.h"

#ifdef __cplusplus
extern "C" {
#endif


#ifdef _WIN32
    #ifdef LTR25API_EXPORTS
        #define LTR25API_DllExport(type) __declspec(dllexport) type APIENTRY
    #else
        #define LTR25API_DllExport(type) __declspec(dllimport) type APIENTRY
    #endif
#elif defined __GNUC__
    #define LTR25API_DllExport(type) __attribute__ ((visibility("default"))) type
#else
    #define LTR25API_DllExport(type) type
#endif


/***************************************************************************//**
  @addtogroup const_list Константы и перечисления
  @{
  *****************************************************************************/

/** Количество каналов АЦП в одном модуле LTR25 */
#define LTR25_CHANNEL_CNT        8

/** Количество частот дискретизации. */
#define LTR25_FREQ_CNT           8

/** Количество частот, для которых сохраняются калибровочные коэффициенты */
#define LTR25_CBR_FREQ_CNT       2

/** Количество значений источника тока */
#define LTR25_I_SRC_VALUE_CNT    2

/** Размер поля с названием модуля. */
#define LTR25_NAME_SIZE          8

/** Размер поля с серийным номером модуля. */
#define LTR25_SERIAL_SIZE       16

/** Максимальное пиковое значение в Вольтах для диапазона измерения модуля */
#define LTR25_ADC_RANGE_PEAK    10

/** Код АЦП, соответствующее максимальному пиковому значению */
#define LTR25_ADC_SCALE_CODE_MAX 2000000000



/** Адрес, с которого начинается пользовательская область flash-памяти */
#define LTR25_FLASH_USERDATA_ADDR   0x0
/** Размер пользовательской области flash-памяти */
#define LTR25_FLASH_USERDATA_SIZE   0x100000
/** Минимальный размер блока для стирания flash-памяти. Все операции стирания
    должны быть кратны данному размеру */
#define LTR25_FLASH_ERASE_BLOCK_SIZE 4096

/** Размер серийного номера узла  TEDS в байтах  */
#define LTR25_TEDS_NODE_SERIAL_SIZE    6






/** @brief Специфичные для модуля LTR25 коды ошибок

   Коды ошибок, которые определены и используются только в ltr25api.
   Остальные коды ошибок, которые используются разными модулями, определены в ltrapi.h */
typedef enum {
    LTR25_ERR_FPGA_FIRM_TEMP_RANGE      = -10600, /**< Загружена прошивка ПЛИС для неверного температурного диапазона */
    LTR25_ERR_I2C_ACK_STATUS            = -10601, /**< Ошибка обмена при обращении к регистрам АЦП по интерфейсу I2C */
    LTR25_ERR_I2C_INVALID_RESP          = -10602, /**< Неверный ответ на команду при обращении к регистрам АЦП по интерфейсу I2C */
    LTR25_ERR_INVALID_FREQ_CODE         = -10603, /**< Неверно задан код частоты АЦП */
    LTR25_ERR_INVALID_DATA_FORMAT       = -10604, /**< Неверно задан формат данных АЦП */
    LTR25_ERR_INVALID_I_SRC_VALUE       = -10605, /**< Неверно задано значение источника тока */
    LTR25_ERR_CFG_UNSUP_CH_CNT          = -10606, /**< Для заданной частоты и формата не поддерживается заданное количество каналов АЦП */
    LTR25_ERR_NO_ENABLED_CH             = -10607, /**< Не был разрешен ни один канал АЦП */
    LTR25_ERR_ADC_PLL_NOT_LOCKED        = -10608, /**< Ошибка захвата PLL АЦП */
    LTR25_ERR_ADC_REG_CHECK             = -10609, /**< Ошибка проверки значения записанных регистров АЦП */
    LTR25_ERR_LOW_POW_MODE_NOT_CHANGED  = -10610, /**< Не удалось перевести АЦП из/в низкопотребляющее состояние */
    LTR25_ERR_LOW_POW_MODE              = -10611, /**< Модуль находится в низкопотребляющем режиме */
    LTR25_ERR_INVALID_SENSOR_POWER_MODE = -10612, /**< Неверное значение режима питания датчиков */
    LTR25_ERR_CHANGE_SENSOR_POWER_MODE  = -10613, /**< Не удалось изменить режим питания датчиков */
    LTR25_ERR_INVALID_CHANNEL_NUMBER    = -10614, /**< Указан неверный номер канала модуля */
    LTR25_ERR_ICP_MODE_REQUIRED         = -10615, /**< Модуль не переведен в ICP-режим питания датчиков, необходимый для данной операции  */
    LTR25_ERR_TEDS_MODE_REQUIRED        = -10616, /**< Модуль не переведен в TEDS режим питания датчиков, необходимый для данной операции */
    LTR25_ERR_TEDS_UNSUP_NODE_FAMILY    = -10617, /**< Данное семейство устройств TEDS узла не поддерживается библиотекой */
    LTR25_ERR_TEDS_UNSUP_NODE_OP        = -10618, /**< Данная операция не поддерживается библиотекой для обнаруженого типа узла TEDS */    
    LTR25_ERR_TEDS_DATA_CRC             = -10619, /**< Неверное значение контрольной суммы в прочитанных данных TEDS */
    LTR25_ERR_TEDS_1W_NO_PRESENSE_PULSE = -10620, /**< Не обнаружено сигнала присутствия TEDS узла на однопроводной шине */
    LTR25_ERR_TEDS_1W_NOT_IDLE          = -10621, /**< Однопроводная шина не была в незанятом состоянии на момент начала обмена */
    LTR25_ERR_TEDS_1W_UNKNOWN_ERR       = -10622, /**< Неизвестная ошибка при обмене по однопроводной шине с узлом TEDS */
    LTR25_ERR_TEDS_MEM_STATUS           = -10623, /**< Неверное состояние памяти TEDS узла */
    LTR25_ERR_TEDS_NODE_URN_CRC         = -10624, /**< Неверное значение контрольной суммы в URN узла TEDS */
    LTR25_ERR_TEDS_1W_BAD_OPCODE        = -10625, /**< Неверный код операции однопроводной шины */
    LTR25_ERR_TEDS_1W_PREV_CYCLE_ERR    = -10626, /**< Команда откинута из-за ошибки в предыдущем цикле обмена по однопроводной шине */
} e_LTR25_ERROR_CODES;


/** Коды частот сбора АЦП */
typedef enum {
    LTR25_FREQ_78K     = 0,     /**< 78.125 кГц */
    LTR25_FREQ_39K     = 1,     /**< 39.0625 кГц */
    LTR25_FREQ_19K     = 2,     /**< 19.53125 кГц */
    LTR25_FREQ_9K7     = 3,     /**< 9.765625 кГц */
    LTR25_FREQ_4K8     = 4,     /**< 4.8828125 кГц */
    LTR25_FREQ_2K4     = 5,    /**< 2.44140625 кГц */
    LTR25_FREQ_1K2     = 6,    /**< 1.220703125 кГц */
    LTR25_FREQ_610     = 7,    /**< 610.3515625 Гц */
} e_LTR25_FREQS;


/** Форматы данных от модуля */
typedef enum {
    LTR25_FORMAT_20 = 0, /**< 20-битный целочисленный (1 слово на отсчет) */
    LTR25_FORMAT_32 = 1, /**< 32-битный целочисленный (2 слова на отсчет) */
} e_LTR25_FORMATS;

/** Значения источника тока */
typedef enum {
    LTR25_I_SRC_VALUE_2_86   = 0, /**< 2.86 мА. */
    LTR25_I_SRC_VALUE_10     = 1  /**< 10 мА. */
} e_LTR25_I_SOURCES;

/** @brief Флаги обработки данных

    Флаги, управляющие работой функции LTR25_ProcessData() */
typedef enum {
    /** Признак, что нужно перевести коды АЦП в Вольты. Если данный флаг не указан,
        то будут возвращены коды АЦП. При этом код #LTR25_ADC_SCALE_CODE_MAX
        соответствует максимальному напряжению для установленного диапазона. */
    LTR25_PROC_FLAG_VOLT          = 0x0001,


    /** Признак, что необходимо выполнить коррекцию фазы модуля
     *  с помощью специального фильтра, как описано в разделе @ref sec_sensor_pha_cor */
    LTR25_PROC_FLAG_PHASE_COR      = 0x010,
    /** При использовании этого флага будет исправлена инверсия сигнала модулем,
     *  как описано в разделе @ref sec_sig_inv. */
    LTR25_PROC_FLAG_SIGN_COR        = 0x080,

    /** По умолчанию LTR25_ProcessData() предполагает, что ей на обработку
        передаются все принятые данные и проверяет непрерывность счетчика не только
        внутри переданного блока данных, но и между вызовами, а также использует
        состояние фильтров с прошлого вызова.
        Если обрабатываются не все данные или одни и те же данные обрабатываются
        повторно, то нужно указать данный флаг. */
    LTR25_PROC_FLAG_NONCONT_DATA = 0x0100,
} e_LTR25_PROC_FLAGS;



/** @brief Состояние входного канала

    Возвращается LTR25_ProcessData() для каждого разрешенного канала и определяет,
    был ли обнаружен обрыв или КЗ для данного канала в обрабатываемом с помощью
    LTR25_ProcessData() блоке */
typedef enum {
    LTR25_CH_STATUS_OK          = 0, /**< Канал в рабочем состоянии */
    LTR25_CH_STATUS_SHORT       = 1, /**< Было обнаружено короткое замыкание */
    LTR25_CH_STATUS_OPEN        = 2, /**< Был обнаружен разрыв цепи */
} e_LTR25_CH_STATUS;

/** @brief Режим питания датчиков

    Режим питания всех датчиков для всех восьми каналов. Устанавливается функцией
    LTR25_SetSensorsPowerMode(). */
typedef enum {
    LTR25_SENSORS_POWER_MODE_ICP = 0, /**< Питание датчиков включено. Штатный режим работы,
                                            в котором могут проводится измерения. Соответствуют аналоговому режиму
                                            работы TEDS датчиков, совместимому с рабочим режимом  ICP-датчиков. */
    LTR25_SENSORS_POWER_MODE_OFF = 1, /**< В данном режиме питание датчиков отключено. */
    LTR25_SENSORS_POWER_MODE_TEDS = 2, /**< Подано питание обратной полярности. Это специальный
                                            цифровой режим работы для датчиков с поддержкой TEDS, который может 
                                            использоваться в частности для чтения данных TEDS с информацией 
                                            о датчике и его характеристиках */
} e_LTR25_SENSORS_POWER_MODE;



/** @brief Дополнительные возможности, поддерживаемые модулем

    Флаги, указывающие, какие дополнительные возможности реализованы в данной
    версии модуля. */
typedef enum {
    /** Расширенная полоса пропускания в области низких частот.
     *  Относится к модулям LTR25, выпущенным в 2020 году и позже.
     *  Флаг указывает, что в RC-цепи, использующейся для удаления постоянной
     *  составляющей сигнала, установлено сопротивление 110 кОм
     *  вместо 31.6 кОм, что приводит к расширению нижней границы полосы
     *  частот пропускания, а также к меньшему влиянию корректирующего фильтра
     *  фазы на АЧХ в области нижних частот и меньшей зависимости падения
     *  напряжения от выходного сопротивления датчика. */
    LTR25_FEATURE_EXT_BANDWIDTH_LF =    (1 << 0)
} e_LTR25_FEATURES;

/** @brief Коды семейств устройств узла TEDS

    Данное перечисление содержит значения кодов семейств устройств с протоколом "1-Wire",
    которые могут быть использованы при реализации узла TEDS как для хранения
    данных TEDS, так и для вспомогательных функций.

    Этот код определяет возможности, которые предоставляет устройство, и набор
    команд для работы с этим устройством.

    Данное определение содержит только коды семейств устройств, поддерживаемых
    библиотекой. По запросу этот список может быть увеличен.

    Код обнаруженного устройства узла TEDS возвращается в информации о устройстве
    при вызове LTR25_TEDSNodeDetect(). */
typedef enum {
    /** 256 бит EEPROM с 64-битным регистром для одноразовой записи базовой информации (DS2430A) */
    LTR25_TEDS_NODE_FAMILY_EEPROM_256_OTP = 0x14,
    LTR25_TEDS_NODE_FAMILY_EEPROM_4K      = 0x23, /**< 4 КБит EEPROM (DS2433) */
    LTR25_TEDS_NODE_FAMILY_EEPROM_1K      = 0x2D, /**< 1 КБит EEPROM (DS2431) */
    LTR25_TEDS_NODE_FAMILY_EEPROM_20K     = 0x43, /**< 20 КБит EEPROM (DS28EC20) */
} e_LTR25_TEDS_NODE_FAMILY_CODE;

/** @brief Флаги для чтения данных из памяти узла TEDS

    Набор флагов, которые могут быть переданы в функцию LTR25_TEDSMemoryRead()
    для управления ее поведением */
typedef enum {
    /** Данный флаг указывает, что чтение данных должно быть выполнено из OTP блока памяти
     * (также называемого Application Register), а не из основной области памяти.
        Имеет значения только для тех микросхем памяти, в которых присутствует
        OTP блок (#LTR25_TEDS_NODE_FAMILY_EEPROM_256_OTP). */
    LTR25_TEDS_NODE_MEMRD_FLAG_OTP = 0x0001
} e_LTR25_TEDS_NONE_MEMRD_FLAGS;

/** @} */

/***************************************************************************//**
  @addtogroup type_list Типы данных
  @{
  *****************************************************************************/

#pragma pack(4)

/** @brief Калибровочные коэффициенты

    Структура, хранящая калибровочные коэффициенты для одного канала
    и диапазона. */
typedef struct {
    float   Offset; /**< Код смещения */
    float   Scale;  /**< Коэффициент шкалы */
} TLTR25_CBR_COEF;



/** @brief Набор коэффициентов для коррекции АЧХ модуля */
typedef struct {
    /** Частота сигнала, для которой снято отношение амплитуд из FirCoef */
    double AfcFreq;
    /** Набор отношений измеренной амплитуды синусоидального сигнала
         к реальной амплитуде для макс. частоты дискретизации и частоты сигнала
         из AfcFreq для каждого канала */
    double FirCoef[LTR25_CHANNEL_CNT];
} TLTR25_AFC_COEFS;


/** @brief Набор коэффициентов для коррекции ФЧХ модуля */
typedef  struct {
    /** Частота, на которой измерен сдвиг фаз каналов модуля */
    double PhaseShiftRefFreq;
    double PhaseShift[LTR25_CHANNEL_CNT]; /**< Сдвиг фазы для каждого канала модуля в градусах */
} TLTR25_PHASE_SHIFT_COEFS;



/** @brief  Информация о модуле

    Структура, содержащая информацию о версиях прошивок микросхем модуля и
    информацию, считанную из Flash-памяти модуля (серийный номер, калибровочные
    коэффициенты).

    Все поля заполняются при вызове LTR25_Open(), а также могут быть обновлены
    при явном вызове LTR25_GetConfig().
 */
typedef struct {
    /** Название модуля ("LTR25").  */
    CHAR        Name[LTR25_NAME_SIZE];
    /** Серийный номер модуля.      */
    CHAR        Serial[LTR25_SERIAL_SIZE];
    /** Версия прошивки ПЛИС */
    WORD        VerFPGA;
    /** Версия прошивки PLD */
    BYTE        VerPLD;
    /** Ревизия платы */
    BYTE        BoardRev;
    /** Признак, это индустриальный вариант модуля или нет */
    BOOL        Industrial;
    DWORD       SupportedFeatures; /**< Флаги из #e_LTR25_FEATURES, указывающие,
                                        какие дополнительные возможности
                                        поддерживает данная версия модуля */
    /** Зарезервированные поля. Всегда равны 0 */
    DWORD       Reserved[7];
    /** Калибровочные коэффициенты модуля. Считываются из Flash-памяти
        модуля при вызове LTR25_Open() или LTR25_GetConfig() и загружаются
        в ПЛИС для применения во время вызова LTR25_SetADC() */
    TLTR25_CBR_COEF CbrCoef [LTR25_CHANNEL_CNT] [LTR25_CBR_FREQ_CNT];
    /** Коэффициенты для коррекции АЧХ модуля */
    TLTR25_AFC_COEFS AfcCoef;
    /** Коэффициенты для коррекции ФЧХ модуля */
    TLTR25_PHASE_SHIFT_COEFS PhaseCoef;
    /** Резервные поля */
    double     Reserved2[32*LTR25_CHANNEL_CNT - 9 - 9];
} TLTR25_MODULE_INFO;



/** @brief Настройки канала АЦП

    Структура, содержащая настройки одного канала АЦП. */
typedef struct {
    BOOL Enabled; /**< Признак, разрешен ли сбор по данному каналу */
    float SensorROut; /**< Выходное сопротивление датчика, подключенного к
                            данному входу ICP, с возможным учетом сопртивления
                            проводов подключения датчика, которое будет использовано
                            для коррекции падения напряжения из-за его взаимодействия
                            с входным сопротивлением ICP-входа.

                            Нулевое значение (по умолчанию) или значение меньше
                            нуля указывает, что коррекция падения напряжения
                            не требуется. */
    DWORD Reserved[10];  /**< Резервные поля (не должны изменяться пользователем) */
} TLTR25_CHANNEL_CONFIG;

/** @brief Настройки модуля

    Структура содержит все настройки модуля, которые должен заполнить
    пользователь перед вызовом LTR25_SetADC(). */
typedef struct {
    TLTR25_CHANNEL_CONFIG Ch[LTR25_CHANNEL_CNT]; /**< Настройки каналов АЦП */
    BYTE        FreqCode; /**< Код, задающий требуемую частоту сбора АЦП.
                               Одно из значений #e_LTR25_FREQS */
    BYTE        DataFmt;  /**< Формат, в котором будут передаваться отсчеты
                               АЦП от модуля. Одно из значений #e_LTR25_FORMATS.
                               Формат определяет также количество передаваемых
                               слов на один отсчет и влияет на максимальное
                               количество разрешенных каналов */
    BYTE        ISrcValue; /**< Используемое значение источника тока. Одно из
                                значений #e_LTR25_I_SOURCES */
    DWORD       Reserved[50]; /**< Резервные поля (не должны изменяться пользователем) */
} TLTR25_CONFIG;


/** @brief Параметры текущего состояния модуля

    Структура, содержащая параметры модуля, которые пользователь должен использовать
    только для чтения, так как они изменяются только внутри функций ltr25api. */
typedef struct {
    BYTE   FpgaState; /**<  Текущее состояние ПЛИС. Одно из значений из e_LTR_FPGA_STATE */
    BYTE   EnabledChCnt; /**< Количество разрешенных каналов. Устанавливается
                                после вызова LTR25_SetADC() */
    BOOL   Run;         /**< Признак, запущен ли сбор данных */
    double AdcFreq;     /**< Установленная частота АЦП. Обновляется после
                            вызова LTR25_SetADC() */
    BOOL   LowPowMode; /**< Признак, находится ли модуль в состоянии низкого
                            потребления. В этом состояние нельзя выполнять настройку
                            АЦП или запуск сбора данных. Управление данным
                            режимом выполняется с помощью LTR25_SetLowPowMode() */
    DWORD   SensorsPowerMode; /**< Текущий режим питания датчиков для всех восьми
                                   каналов. Значение из #e_LTR25_SENSORS_POWER_MODE.
                                   Управление данным режимом выполняется с помощью
                                   функции LTR25_SetSensorsPowerMode(). */
    DWORD   Reserved[30]; /**< Резервные поля */
} TLTR25_STATE;

/** @brief  Управляющая структура модуля

    Хранит текущие настройки модуля, информацию о его состоянии, структуру
    канала связи. Передается в большинство функций библиотеки.
    Некоторые поля структуры доступны для изменения пользователем
    для настройки параметров модуля. Перед использованием требует инициализации
    с помощью функции LTR25_Init().
 */
typedef struct {
    INT         Size; /**< Размер структуры. Заполняется при вызове LTR25_Init(). */
    /** Структура, содержащая состояние клиентского соединения со службой ltrd.
        Не используется напрямую пользователем. */
    TLTR        Channel;
    /** Указатель на непрозрачную структуру с внутренними параметрами,
      используемыми исключительно библиотекой и недоступными для пользователя. */
    PVOID       Internal;
    /** Настройки модуля. Заполняются пользователем перед вызовом LTR25_SetADC(). */
    TLTR25_CONFIG Cfg;
    /** Состояние модуля и рассчитанные параметры. Поля изменяются функциями
        библиотеки. Пользовательской программой могут использоваться
        только для чтения. */
    TLTR25_STATE  State;
    /** Информация о модуле */
    TLTR25_MODULE_INFO ModuleInfo;
} TLTR25;

/** @brief  Информация о устройстве узла TEDS

   В данной структуре содержится информация о микросхеме, которая используется
   для реализации узла TEDS и с которой взаимодействует модуль в цифровом режиме
   работы канала.
   Эта микросхема как правило содержит энергонезависимую память, которая хранит
   информаию о датчике (TEDS), но также может содержать и другие функиональные
   возможности.

   Данная информация возвращается при обнаружении устройства при вызове LTR25_TEDSNodeDetect(). */
typedef  struct {
    BOOL Valid; /**< Признак действительности информации */
    BYTE DevFamilyCode;  /**< Идентификатор семейства устройств, к которому принадлежит
                              данное устройство, реализующее узел TEDS.
                              Может быть равен одному из значений #e_LTR25_TEDS_NODE_FAMILY_CODE
                              или другому коду, если обнаружено устройство
                              не из списка поддерживаемых библиотекой */
    BYTE DevSerial[LTR25_TEDS_NODE_SERIAL_SIZE]; /**< Серийный номер устройства узла TEDS.
                                                        48-битное число, представленное в виде 6 байт. */
    DWORD TEDSDataSize; /**< Размер TEDS данных в байтах, который может
                              хранится в памяти в памяти узла.*/
    DWORD MemorySize;  /**< Размер  пмяти узла TEDS для прямого доступа.*/
    DWORD Reserved[6]; /**< Резерв */
} TLTR25_TEDS_NODE_INFO;

#pragma pack()

/** @} */

/***************************************************************************//**
    @addtogroup func_init Функции инициализации и работы с соединением с модулем
    @{
*******************************************************************************/

/***************************************************************************//**
  @brief Инициализация описателя модуля

  Функция инициализирует поля структуры описателя модуля значениями по умолчанию.
  Эта функция должна вызываться для каждой структуры #TLTR25 перед вызовом
  остальных функций.
   @param[in] hnd       Описатель модуля.
   @return              [Код ошибки](@ref e_LTR25_ERROR_CODES).
 ******************************************************************************/
LTR25API_DllExport(INT) LTR25_Init(TLTR25 *hnd);

/***************************************************************************//**
   @brief Открытие соединения с модулем

   Функция устанавливает соединение с модулем в соответствии с переданными
   параметрами, проверяет наличие модуля и считывает информацию о нем.
   Должна быть вызвана перед работой с модулем. После завершения работы
   необходимо закрыть соединение с помощью LTR25_Close().

   @param[in] hnd       Описатель модуля.
   @param[in] ltrd_addr  IP-адрес машины, на которой запущена служба ltrd, в 32-битном
                        формате (описан в разделе "Формат задания IP-адресов"
                        @docref_ltrapi{руководства для библиотеки ltrapi}).
                        Если служба ltrd запущена на той же машине, что и программа,
                        вызывающая данную функцию, то в качестве адреса
                        можно передать LTRD_ADDR_DEFAULT.
   @param[in] ltrd_port TCP-порт для подключения к службе ltrd. По умолчанию
                        используется LTRD_PORT_DEFAULT.
   @param[in] csn       Серийный номер крейта, в котором находится интересующий
                        модуль. Представляет собой оканчивающуюся нулем ASCII-строку.
                        Для соединения с первым найденным крейтом можно передать
                        пустую строку или нулевой указатель.
   @param[in] slot      Номер слота крейта, в котором установлен интересующий модуль.
                        Значение от LTR_CC_CHNUM_MODULE1 до LTR_CC_CHNUM_MODULE16.
   @return              [Код ошибки](@ref e_LTR25_ERROR_CODES).
*******************************************************************************/
LTR25API_DllExport(INT) LTR25_Open(TLTR25 *hnd, DWORD ltrd_addr, WORD ltrd_port, const CHAR *csn, INT slot);

/** @cond kd_extension */
LTR25API_DllExport(INT) LTR25_OpenEx(TLTR25 *hnd, DWORD ltrd_addr, WORD ltrd_port,
                                     const CHAR *crate_sn, INT slot, DWORD in_flags, DWORD *out_flags);
/** @endcond */

/***************************************************************************//**
   @brief Закрытие соединения с модулем

   Функция закрывает ранее открытое с помощью LTR25_Open() соединение. Должна
   вызываться после завершения работы с модулем. При любом возвращенном значении
   после вызова этой функции соответствующий описатель уже нельзя использовать
   для работы с модулем без открытия нового соединения.

   @param[in] hnd       Описатель модуля.
   @return              [Код ошибки](@ref e_LTR25_ERROR_CODES).
 ******************************************************************************/
LTR25API_DllExport(INT) LTR25_Close(TLTR25 *hnd);

/***************************************************************************//**
   @brief Проверка, открыто ли соединение с модулем

   Функция проверяет, открыто ли в данный момент соединение с модулем. Если
   соединение открыто, функция возвращает LTR_OK, если закрыто --- код ошибки
   LTR_ERROR_CHANNEL_CLOSED.
   @param[in] hnd       Описатель модуля.
   @return              [Код ошибки](@ref e_LTR25_ERROR_CODES)
                        (LTR_OK, если соединение установлено).
 ******************************************************************************/
LTR25API_DllExport(INT) LTR25_IsOpened(TLTR25 *hnd);

/** @} */

/***************************************************************************//**
    @addtogroup func_config Функции для изменения настроек модуля
    @{
*******************************************************************************/

/***************************************************************************//**
   @brief Запись настроек в модуль.

   Функция передает настройки, соответствующие значением полей поля
   @fieldref{TLTR25,Cfg} описателя модуля, в модуль.
   Должна вызываться перед первым запуском сбора данных с помощью
   LTR25_Start().

   @param[in] hnd       Описатель модуля.
   @return              [Код ошибки](@ref e_LTR25_ERROR_CODES).
 ******************************************************************************/
LTR25API_DllExport(INT) LTR25_SetADC(TLTR25 *hnd);

/** @} */



/***************************************************************************//**
    @addtogroup func_stream Функции для управления сбором данных
    @{
*******************************************************************************/

/***************************************************************************//**
    @brief Запуск сбора данных

    При вызове данной функции запускается сбор данных с АЦП модуля. После успешного
    завершения этой функции запускается АЦП и модуль начинает передавать в ПК
    полученные отсчеты, которые необходимо вычитывать с помощью LTR25_Recv().
    При завершении измерения для остановки сбора данных необходимо вызвать
    LTR25_Stop().

    Хотя бы один из каналов АЦП должен быть до этого разрешен и модуль должен быть
    хотя бы раз сконфигурирован с помощью LTR25_SetADC().

   @param[in] hnd       Описатель модуля.
   @return              [Код ошибки](@ref e_LTR25_ERROR_CODES).
 ******************************************************************************/
LTR25API_DllExport(INT) LTR25_Start(TLTR25 *hnd);

/***************************************************************************//**
    @brief Останов сбора данных

    При вызове данной функции модуль останавливает сбор и выдачу данных АЦП.

    При этом вычитываются и выбрасываются все переданные, но непрочитанные
    данные от модуля.

   @param[in] hnd       Описатель модуля.
   @return              [Код ошибки](@ref e_LTR25_ERROR_CODES).
 ******************************************************************************/
LTR25API_DllExport(INT) LTR25_Stop(TLTR25 *hnd);

/***************************************************************************//**
   @brief Прием данных от модуля

   Функция принимает запрашиваемое число слов от модуля. Возвращаемые слова
   находятся в специальном формате, который включает в себя служебную информацию.
   Формат и количество слов на один отсчет определяется настройкой
   @fieldref{TLTR25_CONFIG,DataFmt}.

   Для обработки принятых слов и получения значений АЦП используется функция
   LTR25_ProcessData().

   Функция возвращает управление либо когда примет запрошенное количество слов,
   либо по истечению таймаута. При этом реально принятое количество слов можно
   узнать по возвращенному значению.

   @param[in]  hnd      Описатель модуля.
   @param[out] data     Массив, в который будут сохранены принятые слова. Должен
                        быть размером на size 32-битных слов.
   @param[out] tmark    Указатель на массив размером на size 32-битных слов,
                        в который будут сохранены значения счетчиков синхрометок,
                        соответствующие принятым данным. Генерация меток
                        настраивается для крейта или специального модуля отдельно.
                        Синхрометки подробнее описаны в разделе "Синхрометки"
                        @docref_ltrapi{руководства для библиотеки ltrapi}.
                        Если синхрометки не используются, то можно передать
                        в качестве параметра нулевой указатель.
   @param[in]  size     Запрашиваемое количество 32-битных слов на прием.
   @param[in]  timeout  Таймаут на выполнение операции в миллисекундах. Если в течение
                        заданного времени не будет принято запрашиваемое количество
                        слов, то функция все равно вернет управление, возвратив
                        в качестве результата реально принятое количество слов
   @return              Значение меньше нуля соответствует коду ошибки. Значение
                        больше или равное нулю соответствует количеству реально
                        принятых и сохраненных в массив data слов.
*******************************************************************************/
LTR25API_DllExport(INT) LTR25_Recv(TLTR25 *hnd, DWORD *data, DWORD *tmark, DWORD size,
                                   DWORD timeout);


/****************************************************************************//**
   @brief Обработка принятых от модуля слов

   Функция используется для обработки слов, принятых от модуля с помощью LTR25_Recv().
   Функция проверяет служебные поля принятых слов, извлекает полезную информацию
   с отсчетами и, при указании флага #LTR25_PROC_FLAG_VOLT, переводит отсчеты в
   Вольты.

   Функция предполагает, что передаваемые слова выровнены на начало кадра (первое
   слово первого разрешенного канала). Если это не так, то неполный кадр в начале
   будет отброшен и функция вернет ошибку LTR_ERROR_PROCDATA_UNALIGNED.

   Также функция анализирует признаки обрыва или КЗ в разрешенных каналах. При
   наличии подобного признака для хотя бы одного отсчета соответствующего
   канала устанавливается соответствующей статус в элементе массива ch_status.

   В отличие от модуля LTR25 в модуле LTR25 калибровка отсчетов и корректировка
   АЧХ выполняется внутри модуля аппаратно, поэтому в LTR25_ProcessData() нет
   подобных флагов.

   По умолчанию функция предполагает, что все принятые данные обрабатываются
   и только один раз, проверяя непрерывность счетчика и между вызовами функции,
   а также сохраняя состояния фильтров между вызывами.
   Если это условие не выполняется, то нужно передать флаг #LTR25_PROC_FLAG_NONCONT_DATA.

   @param[in] hnd      Описатель модуля.
   @param[in] src      Указатель на массив, содержащий слова, принятые от модуля
                       с помощью LTR25_Recv(), которые нужно обработать.
   @param[out] dest    Указатель на массив, в который будут сохранены обработанные
                       данные. Порядок следования соответствует порядку во входном
                       массиве (т.е. сперва первый отсчет первого разрешенного канала,
                       затем первый отсчет второго канала и т.д.). Массив должен
                       иметь достаточно места для сохранения как минимум size
                       элементов для 20-битного режима или size/2 для 32-битного.
   @param[in,out] size  На входе принимает размер массива src для обработки. На
                        выходе, при успешном завершении, возвращает количество
                        сохраненных отсчетов в массиве dest.
   @param[in]  flags   Флаги из #e_LTR25_PROC_FLAGS, управляющие работой функции.
                        Может быть объединено несколько флагов через логическое
                        ИЛИ.
   @param[out] ch_status  Массив размером на количество элементов, соответствующее
                        количеству разрешенных каналов. В каждом элементе сохраняется
                        статус канала (одно из значений #e_LTR25_CH_STATUS),
                        определяющий, были ли признаки КЗ или обрыва
                        в соответствующем канале. Может быть передан нулевой
                        указатель, если эта информация не нужна.
   @return              [Код ошибки](@ref e_LTR25_ERROR_CODES).
  *****************************************************************************/
LTR25API_DllExport(INT) LTR25_ProcessData(TLTR25 *hnd, const DWORD *src, double *dest,
                                    INT *size, DWORD flags, DWORD *ch_status);


/****************************************************************************//**
   @brief Поиск начала первого кадра

   Функция находит в принятом массиве сырых данных от модуля индекс первого
   слова первого начала кадра. Может использоваться для выравнивания на
   начало кадра данных в случае произошедшего сбоя без останова сбора.

   Если в переданном массиве начало кадра не найдено, то функция вернет ошибку
   LTR_ERROR_FIRSTFRAME_NOTFOUND.

   @param[in] hnd      Описатель модуля.
   @param[in] data     Указатель на массив, содержащий слова, принятые от модуля
                       с помощью LTR25_Recv(), в которых ищется начало кадра.
   @param[in] size     Количество слов в массиве data
   @param[out] index   В этой переменной возвращается индекс элемента,
                       соответствующего началу первого кадра, если функция
                       завершилась успешно.
   @return             [Код ошибки](@ref e_LTR25_ERROR_CODES).
  *****************************************************************************/
LTR25API_DllExport(INT) LTR25_SearchFirstFrame(TLTR25 *hnd, const DWORD *data, DWORD size,
                                                DWORD *index);

/** @} */

/***************************************************************************//**
    @addtogroup func_misc Функции вспомогательного характера
    @{
*******************************************************************************/

/***************************************************************************//**
   @brief Получение сообщения об ошибке

   Функция возвращает строку, соответствующую переданному коду ошибки, в кодировке
   CP1251 для ОС Windows или UTF-8 для ОС Linux. Функция может обработать как ошибки
   из ltr25api, так и общие коды ошибок из ltrapi.

   @param[in] err       [Код ошибки](@ref e_LTR25_ERROR_CODES).
   @return              Указатель на строку, содержащую сообщение об ошибке.
 ******************************************************************************/
LTR25API_DllExport(LPCSTR) LTR25_GetErrorString(INT err);


/***************************************************************************//**
    @brief Чтение информации и калибровочных коэффициентов

    Функция считывает информацию из flash-памяти модуля и обновляет поля
    @fieldref{TLTR25,ModuleInfo} в управляющей структуре модуля.
    Так как данная операция уже выполняется при вызове LTR25_Open(),
    то как правило вызов данной функции не требуется.
    Однако данная функция может быть использована для восстановления измененных
    коэффициентов в @fieldref{TLTR25,ModuleInfo} на заводские.


   @param[in] hnd      Описатель модуля.
   @return             [Код ошибки](@ref e_LTR25_ERROR_CODES).
 ******************************************************************************/
LTR25API_DllExport(INT) LTR25_GetConfig(TLTR25 *hnd);

/** @cond kd_extension */
LTR25API_DllExport(INT) LTR25_StoreConfig(TLTR25 *hnd, TLTR_CARD_START_MODE start_mode);
/** @endcond */


/***************************************************************************//**
    @brief Перевод модуля в режим низкого потребления

    Функция переводит модуль в режим низкого потребления или переводит его
    из этого режима снова в рабочий. В режиме низкого потребления
    снято питание с АЦП и источники тока установлены 2.86 мА. Доступ
    к регистрам АЦП невозможен. Этот режим может быть использован для полного
    сброса АЦП, для чего в этом режиме модуль должен находится не менее 5 с.

   @param[in] hnd           Описатель модуля.
   @param[in] lowPowMode    Если FALSE --- перевод модуля в рабочий режим, иначе ---
                            в режим низкого потребления.
   @return                  [Код ошибки](@ref e_LTR25_ERROR_CODES).
 ******************************************************************************/
LTR25API_DllExport(INT) LTR25_SetLowPowMode(TLTR25 *hnd, BOOL lowPowMode);





/***************************************************************************//**
   @brief Проверка, разрешена ли работа ПЛИС модуля

   Функция проверяет, разрешена ли работа ПЛИС модуля. Для настройки и сбора
   данных ПЛИС должен быть всегда разрешен.

   @param[in] hnd      Описатель модуля.
   @param[out] enabled В случае успешного выполнения функции в этой переменной
                       возвращается FALSE, если ПЛИС запрещен, или TRUE в
                       противном случае.
   @return             [Код ошибки](@ref e_LTR25_ERROR_CODES).
 ******************************************************************************/
LTR25API_DllExport(INT) LTR25_FPGAIsEnabled(TLTR25 *hnd, BOOL *enabled);

/***************************************************************************//**
   @brief Разрешение работы ПЛИС модуля

   Функция разрешает или запрещает работу ПЛИС модуля. Для настройки и сбора
   данных ПЛИС должен быть всегда разрешен. В LTR25_Open() выполняется разрешение
   работы ПЛИС, если была найдена прошивка ПЛИС в памяти модуля и она была
   успешно загружена, поэтому в штатной работе данная функция не используется.

   @param[in] hnd      Описатель модуля.
   @param[in] enable   Если FALSE --- запрет работы ПЛИС, иначе --- разрешение
   @return             [Код ошибки](@ref e_LTR25_ERROR_CODES).
 ******************************************************************************/
LTR25API_DllExport(INT) LTR25_FPGAEnable(TLTR25 *hnd, BOOL enable);

/** @} */


/***************************************************************************//**
    @addtogroup func_flash Функции для работы с flash-памятью модуля
    @{
*******************************************************************************/

/***************************************************************************//**
   @brief Чтение данных из flash-памяти модуля

   Функция вычитывает данные, записанные во flash-памяти модуля по заданному
   адресу. Пользователю выделяется область памяти с адреса
   #LTR25_FLASH_USERDATA_ADDR размером #LTR25_FLASH_USERDATA_SIZE байт.

   @param[in] hnd      Описатель модуля.
   @param[in] addr     Адрес памяти, начиная с которого необходимо прочитать данные
   @param[out] data    Массив на size байт, в который будут записаны прочитанные
                       из Flash-памяти данные
   @param[in] size     Количество данных в байтах, которое необходимо прочитать
   @return             [Код ошибки](@ref e_LTR25_ERROR_CODES).
 ******************************************************************************/
LTR25API_DllExport(INT) LTR25_FlashRead(TLTR25 *hnd, DWORD addr, BYTE *data, DWORD size);

/***************************************************************************//**
   @brief Запись данных во flash-память модуля

   Функция записывает данные во flash-память модуля по заданному
   адресу. Записываемая область должна быть предварительно стерта с помощью
   LTR25_FlashErase(). Пользователю выделяется область памяти с адреса
   #LTR25_FLASH_USERDATA_ADDR размером #LTR25_FLASH_USERDATA_SIZE байт.

   @param[in] hnd      Описатель модуля.
   @param[in] addr     Адрес памяти, начиная с которого необходимо выполнить запись
   @param[in] data     Массив из size байт с данными, которые будут записаны
   @param[in] size     Количество данных в байтах, которое необходимо записать
   @return             [Код ошибки](@ref e_LTR25_ERROR_CODES).
 ******************************************************************************/
LTR25API_DllExport(INT) LTR25_FlashWrite(TLTR25 *hnd, DWORD addr, const BYTE *data, DWORD size);

/***************************************************************************//**
   @brief Стирание области flash-память модуля

   Функция стирает область во flash-памяти модуля по заданному
   адресу. Стирание необходимо выполнять перед записью данных.
   Стирание возможно только блоками, кратными #LTR25_FLASH_ERASE_BLOCK_SIZE байт.
   Пользователю выделяется область памяти с адреса
   #LTR25_FLASH_USERDATA_ADDR размером #LTR25_FLASH_USERDATA_SIZE байт.

   @param[in] hnd      Описатель модуля.
   @param[in] addr     Адрес памяти, начиная с которого необходимо выполнить стирание
   @param[in] size     Размер стираемой области в байтах. Должен быть кратен
                       #LTR25_FLASH_ERASE_BLOCK_SIZE.
   @return             [Код ошибки](@ref e_LTR25_ERROR_CODES).
 ******************************************************************************/
LTR25API_DllExport(INT) LTR25_FlashErase(TLTR25 *hnd, DWORD addr, DWORD size);

/** @} */



/***************************************************************************//**
    @addtogroup func_teds Функции для работы с памятью TEDS-датчиков
    @{

    Данные функции доступны только для ревизии модуля 2 или выше и для прошивки
    ПЛИС версии 8 или выше.
*******************************************************************************/

/***************************************************************************//**
    @brief Проверка поддержки модуля работы с TEDS

    Данная функция служит для проверки, поддерживает ли данный
    экземпляр модуля LTR25 работу с TEDS-датчиками в цифровом режиме, что
    определяет возможность использования остальных функций из данной главы.

    Если поддерживает, то функция возвращает LTR_OK, иначе --- код ошибки.

   @param[in] hnd      Описатель модуля.
   @return             [Код ошибки](@ref e_LTR25_ERROR_CODES).
******************************************************************************/
LTR25API_DllExport(INT) LTR25_CheckSupportTEDS(TLTR25 *hnd);

/***************************************************************************//**
   @brief Установка режима питания датчиков

   Функция устанавливает режим питания датчиков для всех каналов модуля.
   Основным рабочим режимом является #LTR25_SENSORS_POWER_MODE_ICP (единственный
    доступный для ревизии модуля 0 или 1).

   Для доступа к энергонезависимой памяти TEDS-датчиков (или другим функциям узлов TEDS)
   необходимо сперва  установить режим #LTR25_SENSORS_POWER_MODE_TEDS, в котором 
   на датчики подается питание противоположной полярности.

   @param[in] hnd      Описатель модуля.
   @param[in] mode     Устанавливаемый режим. Значение из #e_LTR25_SENSORS_POWER_MODE.
   @return             [Код ошибки](@ref e_LTR25_ERROR_CODES).
 ******************************************************************************/
LTR25API_DllExport(INT) LTR25_SetSensorsPowerMode(TLTR25 *hnd, DWORD mode);

/***************************************************************************//**
   @brief Обнаружение узла TEDS

   Функция выполняет определение наличия устройства (как правило памяти),
   реализующего узел TEDS, подключенного к указанному каналу модуля LTR25.

   Функция также считывает  64-битный URN (уникальный регистрационный номер)
   устройства, содержащий код семейства, которому принадлежит устройство,
   серийный номер и CRC.

   При успешном считывании и проверке CRC функция анализирует считанный код
   семейства устройств, и, если он принадлежит одному из поддерживаемых устройств,
   определяет по этому коду основные параметры устройства.

   Считанная и полученная по коду семейства информация, описывающая устройство,
   возвращается в виде структуры #TLTR25_TEDS_NODE_INFO.

   Список поддерживаемых библиотекой семейств устройств определен в перечислении
   #e_LTR25_TEDS_NODE_FAMILY_CODE.

   Если устройство обнаружено успешно, но тип не поддерживается библиотекой,
   то функция вернет ошибку #LTR25_ERR_TEDS_UNSUP_NODE_FAMILY, но считанная
   часть информации о устройстве будет возвращена (идентификатор и серийный номер).
   Действительность возвращенной информации о памяти можно проверить по полю
   [Valid](@ref TLTR25_TEDS_NODE_INFO::Valid).

   Для данной функции предварительно должен быть установлен режим
   питания датчиков #LTR25_SENSORS_POWER_MODE_TEDS.

   @param[in] hnd      Описатель модуля.
   @param[in] ch       Номер канала модуля (от 0 до #LTR25_CHANNEL_CNT-1).
   @param[in] devinfo  Указатель на структуру, в которую будет возвращена информация
                       об обнаруженном узле.
                       Если информацию получить не удалось, то будет сброшено
                       поле [Valid](@ref TLTR25_TEDS_NODE_INFO::Valid) структуры.
                       Может быть передан нулевой указатель, если данная информация не
                       требуется.
   @return             [Код ошибки](@ref e_LTR25_ERROR_CODES).
 ******************************************************************************/
LTR25API_DllExport(INT) LTR25_TEDSNodeDetect(TLTR25 *hnd, INT ch, TLTR25_TEDS_NODE_INFO *devinfo);


/***************************************************************************//**
   @brief Чтение TEDS данных из энергонезависимой памяти датчика

   Функция выполняет чтение данных TEDS из энергонезависимой памяти узла TEDS.

   Функция выполняет чтение всех данных последовательно, как они хранятся в памяти
   в нужном порядке, проверяя и удаляя байты с контрольной суммой.

   Предварительно должен быть установлен режим питания датчиков #LTR25_SENSORS_POWER_MODE_TEDS.

   @param[in]  hnd       Описатель модуля.
   @param[in]  ch        Номер канала модуля (от 0 до #LTR25_CHANNEL_CNT-1).
   @param[out] data      Буфер, в котором при успешном выполнении функции будут сохранены
                         прочитанные данные. В нем должно быть достаточно места для
                         сохранения size байт.
   @param[in]  size      Размер буфера для сохранения данных в байтах
   @param[out] read_size Размер сохраненных в буфер байт с данными TEDS
   @return               [Код ошибки](@ref e_LTR25_ERROR_CODES).
 ******************************************************************************/
LTR25API_DllExport(INT) LTR25_TEDSReadData(TLTR25 *hnd, INT ch, BYTE *data, DWORD size, DWORD *read_size);


/***************************************************************************//**
   @brief Прямое чтение данных из энергонезависимой памяти TEDS-датчика

   В отличие от LTR25_TEDSReadData() данная функция предназначена для чтения
   непосредственно содержимого энергонезависимой памяти узла TEDS без какой-либо
   их интерпретации, что может быть полезно, если датчик поддерживает интерфейс
   для чтения данных, совместимый с TEDS, но сам формат хранимых данных отличается
   от спецификации.

   Данная функция не выполняет проверку контрольной суммы блоков данных и не
   удаляет слова с контрольной суммой из результирующего массива. Также данная
   функция требует явно указать место чтения данных, а не полагается на стандартное
   их последовательное расположение. Место в памяти задается адресом, а также
   может зависеть от флагов для некоторых микросхем памяти.

   Предварительно должен быть установлен режим питания датчиков #LTR25_SENSORS_POWER_MODE_TEDS.

   @param[in]  hnd       Описатель модуля.
   @param[in]  ch        Номер канала модуля (от 0 до #LTR25_CHANNEL_CNT-1).
   @param[in]  addr      Адрес памяти, начиная с которого необходимого прочитать
                         данные. Его интерпретация может зависеть от флагов.
   @param[out] data      Буфер, в котором при успешном выполнении функции будут сохранены
                         прочитанные данные. В нем должно быть достаточно места для
                         сохранения size байт.
   @param[in]  size      Размер буфера для сохранения данных в байтах
   @param[in]  flags     Флаги из #e_LTR25_TEDS_NONE_MEMRD_FLAGS, которые могут
                         быть объединены битовому "ИЛИ".
   @return               [Код ошибки](@ref e_LTR25_ERROR_CODES).
 ******************************************************************************/
LTR25API_DllExport(INT) LTR25_TEDSMemoryRead(TLTR25 *hnd, INT ch, DWORD addr, BYTE *data, DWORD size, DWORD flags);

/** @} */

#ifndef LTRAPI_DISABLE_COMPAT_DEFS
/** @cond obsoleted */
typedef TLTR25_MODULE_INFO TINFO_LTR25;
/** @endcond */
#endif
#ifdef __cplusplus
}
#endif

#endif
