#ifndef LTR12API_H_
#define LTR12API_H_


#include "ltrapi.h"

#ifdef __cplusplus
extern "C" {                                 // only need to export C interface if
// used by C++ source code
#endif

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


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

/** Максимальное число измерительных каналов в одном модуле */
#define LTR12_CHANNELS_CNT              32

/** Максимальное число измерительных разностных каналов в одном модуле */
#define LTR12_DIFF_CHANNELS_CNT         16

/** Количество диапазонов измерения */
#define LTR12_RANGES_CNT                1

/** Предел диапазона измерения модуля в мА */
#define LTR12_ADC_RANGE_MA              20
/** Номинальное значение входного сопротивления в Омах */
#define LTR12_R_IN_NOM                  25

/** Максимальное количество каналов в логической таблице */
#define LTR12_MAX_LCHANNELS_CNT         128

/** Размер поля с названием модуля */
#define LTR12_NAME_SIZE                 8
/** Размер поля с серийным номером модуля */
#define LTR12_SERIAL_SIZE               16
/** Размер поля с информацией о дате создания прошивки контроллера модуля */
#define LTR12_FIRMDATE_SIZE             14



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

/** Значение входной тактовой частоты  контроллера модуля в Гц */
#define LTR12_IN_CLOCK_FREQ             15000000

/** Максимальное допустимое значение поля делителя частоты АЦП */
#define LTR12_MAX_ADC_DIVIDER           65535
/** Минимальное допустимое значение поля делителя частоты АЦП */
#define LTR12_MIN_ADC_DIVIDER           2

/** Максимальное значение частоты АЦП в Гц */
#define LTR12_MAX_ADC_FREQ              400000

/** Размер пользовательской области flash-памяти */
#define LTR12_FLASH_USERDATA_SIZE       2048


/** @brief Коды ошибок, специфичные для модуля LTR12

   Коды ошибок, которые определены и используются только в ltr12api.
   Общие коды ошибок, которые используются разными модулями, определены в ltrapi.h. */
typedef enum {
    LTR12_ERR_INVALID_MODULEINFO_RESP_FORMAT = -10900, /**< Неверный формат ответов с информацией о модуле. */
    LTR12_ERR_INVALID_CFG_LCH_CNT            = -10901, /**< Задано неверное количество логических каналов в настройках модуля. */
    LTR12_ERR_INVALID_CFG_PHY_CH_NUM         = -10902, /**< Задан неверный номер физического канала в настройках модуля. */
    LTR12_ERR_INVALID_CFG_CH_MODE            = -10903, /**< Задан неверный режим измерения канала в настройках модуля. */
    LTR12_ERR_INVALID_CFG_ADC_PRESCALER      = -10904, /**< Задано неверное значение предварительного делителя частоты АЦП в настройках модуля. */
    LTR12_ERR_INVALID_CFG_ADC_DIVIDER        = -10905, /**< Задано неверное значение делителя частоты АЦП в настройках модуля. */
    LTR12_ERR_INVALID_CFG_ADC_RATE           = -10906, /**< Заданная частота АЦП находится вне допустимого диапазона. */
    LTR12_ERR_INVALID_CFG_CONV_START_SRC     = -10907, /**< Задан неверный источник запуска преобразования АЦП в настройках модуля. */
    LTR12_ERR_INVALID_CFG_ACQ_START_SRC      = -10908, /**< Задан неверный источник запуска сбора данных в настройках модуля. */
    LTR12_ERR_NO_END_OF_FRAME_RECVD          = -10909, /**< Не обнаружено действительного признака конца кадра в принятых данных. */
} e_LTR12_ERROR_CODES;


/** Источник запуска сбора данных модулем */
typedef enum {
    LTR12_ACQ_START_SRC_INT      =    0,  /**< Внутренний запуск. Сбор запускается
                                               непосредственно по команде модулю
                                               при вызове LTR12_Start(). */
    LTR12_ACQ_START_SRC_EXT_RISE =    1,  /**< Запуск сбора осуществляется по фронту
                                               внешнего сигнала на входе START
                                               сигнального разъема модуля. */
    LTR12_ACQ_START_SRC_EXT_FALL =    2   /**< Запуск сбора осуществляется по спаду
                                               внешнего сигнала на входе START
                                               сигнального разъема модуля. */
} e_LTR12_ACQ_START_SRC;

/** Источник запуска преобразования АЦП */
typedef enum {
    LTR12_CONV_START_SRC_INT      =    0,     /**< Запуск преобразований АЦП осуществляется
                                                   от внутреннего периодического сигнала
                                                   модуля, частота которого определяется
                                                   настройками из @fieldref{TLTR12_CONFIG,AdcFreqParams}.
                                               */
    LTR12_CONV_START_SRC_EXT_RISE =    1,     /**< Запуск преобразований АЦП осуществляется
                                                   по фронту внешнего сигнала на входе SYN
                                                   сигнального разъема модуля */
    LTR12_CONV_START_SRC_EXT_FALL =    2      /**< Запуск преобразований АЦП осуществляется
                                                   по спаду внешнего сигнала на входе SYN
                                                   сигнального разъема модуля */
} e_LTR12_CONV_START_SRC;


/** Режим измерения логического канала */
typedef enum {
    LTR12_CH_MODE_COMM      = 0, /**< Режим измерения с общей землей одного из 32 каналов
                                  модуля. Данный режим является основным рабочим
                                  режимом модуля LTR12. */
    LTR12_CH_MODE_DIFF      = 1, /**< Дифференциальный режим измерения (X-Y)
                                  дифференциального источника тока.
                                  Выполняется измерение разности токов между
                                  выбранным одним из первых 16 каналов (X)
                                  и соответствующим ему каналом из вторых 16.
                                  В качестве калибровочного коэффициента используется
                                  среднее между коэффициентами двух соответствующих каналов. */
    LTR12_CH_MODE_ZERO      = 2, /**< Режим измерения собственного нуля модуля. */
    LTR12_CH_MODE_DIFF_X_Y0 = 3, /**< Дифференциальный режим измерения (X-Y0) источника
                                      тока с общей землей, подключенного к одному из первых
                                      16 каналов (X). На соответствующий канал из вторых
                                      16 каналов (Y) ток не подается.
                                      */
    LTR12_CH_MODE_DIFF_Y_X0 = 4, /**< Дифференциальный режим измерения (Y-Y0) источника
                                      тока с общей землей , подключенного к одному из вторых
                                      16 каналов (Y). На соответствующий канал из первых
                                      16 каналов (X) ток не подается.
                                      */
} e_LTR12_CH_MODE;


/** @brief Флаги, управляющие обработкой данных


  Набор флагов, который может быть передан в функцию LTR12_ProcessData() для
  указания, какие преобразования и какую обработку данных требуется
  выполнить.
*/
typedef enum {
    /** Признак, что нужно выполнить калибровку, применив к данным калибровочные
      *  коэффициенты, как описано в разделе @ref sect_gen_cbr. */
    LTR12_PROC_FLAG_CALIBR              = 0x00000001,
    /** Признак, что нужно перевести коды АЦП в измеряемые величины (мА). */
    LTR12_PROC_FLAG_CONV_UNIT           = 0x00000002,
    /** Данный флаг указывает, что необходимо выполнять коррекцию нуля с учетом
        измеренного значения смещения нуля из @fieldref{TLTR12_STATE,AdcZeroOffsetCode}.
        Данное значение может быть измерено перед запуском сбора данных
        с помощью LTR12_MeasAdcZeroOffset(), а также во время сбора данных в фоновом режиме.
        Если измерение собственного нуля не производилось,
        то использование данного флага не оказывает влияние на результат. */
    LTR12_PROC_FLAG_ZERO_OFFS_COR        = 0x00010000,

    /** Данный флаг указывает, что необходимо использовать все обрабатываемые
        измерения собственного нуля АЦП для перерасчета текущего значения
        смещения нуля в поле @fieldref{TLTR12_STATE,AdcZeroOffsetCode},
        которое может быть использовано для коррекции нуля измерительных
        каналов при передаче флага #LTR12_PROC_FLAG_ZERO_OFFS_COR.

        Данное действие относится как к фоновым каналам, задаваемым с помощью
        поля @fieldref{TLTR12_CONFIG,BgLChCnt}, так и к каналам из логической
        таблицы с режимом измерения #LTR12_CH_MODE_ZERO.

        Если в кадре отсутствуют измерения нуля, то передача данного флага
        не влияет на работу функции. */
    LTR12_PROC_FLAG_ZERO_OFFS_AUTORECALC = 0x00020000,

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



/** @} */

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

#pragma pack (4)

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

   Структура содержит значения заводских калибровочных коэффициентов модуля,
   считанных из flash-памяти модуля. */
typedef struct {
    float Offset; /**< Код смещения нуля. Общий для всех каналов модуля. */
    float ChScale[LTR12_CHANNELS_CNT]; /**< Индивидуальный коэффициент шкалы для
                                            каждого канала модуля */
    float Reserved[63]; /**< Резерв */
} TLTR12_CBR_INFO;


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

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

    Все поля заполняются при вызове LTR12_Open(),  а также могут быть повторно
    вычитаны из flash-памяти при явном вызове LTR12_GetConfig().
 */
typedef struct {    
    CHAR Name[LTR12_NAME_SIZE]; /**< Название модуля. Оканчивающаяся нулем ASCII-строка ("LTR12"). */
    CHAR Serial[LTR12_SERIAL_SIZE]; /**< Серийный номер модуля. Оканчивающаяся нулем ASCII-строка. */
    WORD FirmwareVersion; /**< Версия прошивки контроллера модуля
                               (младший байт --- минорная, старший - мажорная) */
    CHAR FirmwareDate[LTR12_FIRMDATE_SIZE]; /**< Дата создания прошивки контроллера. Оканчивающаяся нулем ASCII-строка. */
    BYTE Reserved[8]; /**< Резерв */
    TLTR12_CBR_INFO Cbr; /**< Заводские калибровочные коэффициенты,
                              считанные из flash-памяти модуля. */
} TLTR12_MODULE_INFO;



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

    Структура, содержащая параметры модуля, которые пользователь может использовать
    только для чтения, так как они изменяются только внутри функций ltr12api. */
typedef struct {
    BOOLEAN Configured;  /**< Признак, что была выполнена конфигурация модуля
                              с помощью LTR12_SetADC() с момента установления соединения. */
    BOOLEAN Run;         /**< Признак, запущен ли сбор данных. Изменяется при
                              вызове функций LTR12_Start() и LTR12_Stop().*/
    DWORD   FrameWordsCount;   /**< Количество слов в одном кадре.
                                   В LTR12_ProcessData() нужно передавать
                                   количество слов, кратное этому значению.
                                   Обновляется после вызова LTR12_SetADC().
                                   Определяется суммой количества каналов
                                   в логической таблице (@fieldref{TLTR12_CONFIG,LChCnt})
                                   и количеством фоновых измерений
                                   (@fieldref{TLTR12_CONFIG,BgLChCnt}) */
    double  AdcFreq;     /**< Установленная частота АЦП в Гц. Обновляется после вызова LTR12_SetADC(). */
    double  FrameFreq;   /**< Установленная частота следования кадров в Гц.
                              Соответствует частоте на каждый логический канал.
                              Обновляется после вызова LTR12_SetADC(). */
    double AdcZeroOffsetCode;  /**< Текущее измеренное значение смещения нуля АЦП в кодах.
                                 После установления соединения устанавливается
                                 равным калибровочному коэффициенту смещения нуля.
                                 Смещение может быть измерено явно до старта сбора данных
                                 с помощью функции LTR12_MeasAdcZeroOffset(),
                                 а также автоматически корректироваться во время сбора,
                                 если включены фоновые измерения нуля
                                 и в LTR12_ProcessData() передан флаг
                                 #LTR12_PROC_FLAG_ZERO_OFFS_AUTORECALC.
                                 Применяется для корректировки нуля вместо калибровочного
                                 коэффициента при передаче флага #LTR12_PROC_FLAG_ZERO_OFFS_COR
                                 в LTR12_ProcessData(). */
    DWORD Reserved[16];   /**< Резерв. */
} TLTR12_STATE;


/** @brief Настройки логического канала

   Структура определяет настройки одного опроса АЦП из последовательности опросов,
   определяемых логической таблицей. */
typedef struct {
    BYTE PhyChannel; /**< Номер физического канала (входа на разъеме), сигнал на котором должен
                          быть измерен при данном опросе АЦП, начиная от 0. */
    BYTE Mode;      /**< Используемый режим измерения. Значение из #e_LTR12_CH_MODE. */
    WORD Reserved;   /**< Резерв */
} TLTR12_LCHANNEL;


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

   Структура содержит набор настроек, определяющих частоту преобразования АЦП в
   случае, если используется внутренний источник запуска преобразований АЦП
   (значение @fieldref{TLTR12_CONFIG,ConvStartSrc} равно #LTR12_CONV_START_SRC_INT).

   Значение частоты пробразования АЦП определяется по формуле:
    \f[ F_{adc} = \frac{LTR12\_IN\_CLOCK\_FREQ}{Prescaler * (Divider + 1)} \f]
   Частота 400 КГц является специальным случаем и задается явно с помощью
   установки поля @fieldref{TLTR12_ADCFREQ_CFG,Is400KHz}, либо с помощью задания
   специальных значений @fieldref{TLTR12_ADCFREQ_CFG,Prescaler} = 1,
   @fieldref{TLTR12_ADCFREQ_CFG,Divider} = 36 (по аналогии с LTR11).

   Поля данной структуры могут быть заполнены автоматически с помощью функций
   LTR12_FillAdcFreqParam() или LTR12_FindAdcFreqParams().
   Для расчета полученной частоты АЦП по заполненным параметрам можно использовать
   функцию LTR12_CalcAdcFreq().
*/
typedef struct {
    BOOLEAN Is400KHz; /**< Признак использования частоты 400КГц. Если истина,
                           то частота преобразования равна 400 КГц,
                           а остальные параметры не имеют значения */
    WORD Prescaler;   /**< Предварительный делитель тактовый частоты модуля.
                           Должен быть равен одному из следующих значений:
                           1, 8, 64, 256 или 1024. */
    DWORD Divider;    /**< Значение делителя тактовой частоты модуля. Может
                           принимать значения в интервале от
                           #LTR12_MIN_ADC_DIVIDER до #LTR12_MAX_ADC_DIVIDER
                           включительно при условии, что полученная частота
                           АЦП не превышает #LTR12_MAX_ADC_FREQ. */
    DWORD Reserved[6]; /**< Резерв */
} TLTR12_ADCFREQ_CFG;


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

    Структура содержит все настройки модуля, которые должен заполнить
    пользователь перед вызовом LTR12_SetADC().
    Для заполнения параметров частоты АЦП и логических каналов могут
    использоваться вспомогательные функции.
*/
typedef struct {
    /** Параметры, определяющие частоту преобразования АЦП при использовании
        внутреннего источника запуска преобразования.
        Если @fieldref{TLTR12_CONFIG,ConvStartSrc} отлично от
        #LTR12_CONV_START_SRC_INT, то данные настройки не имеют значения. */
    TLTR12_ADCFREQ_CFG AdcFreqParams;
    DWORD AcqStartSrc; /**< Источник запуска сбора данных.
                           Одно из значений #e_LTR12_ACQ_START_SRC. */
    DWORD ConvStartSrc; /**< Источник запуска каждого отдельного преобразования АЦП.
                           Одно из значений #e_LTR12_CONV_START_SRC. */
    DWORD Reserved[30]; /**< Резерв */
    DWORD BgLChCnt; /**< Количество фоновых измерений в одном кадре. Если отлично
                          от нуля, то после опроса АЦП в соответствии с логической
                          таблицей происходит указанное количество измерений собственного
                          нуля, которые не будут возвращены в результатах обработки
                          с помощью LTR12_ProcessData(), а могут только использоваться
                          для корректировки смещения нуля модуля. */
    DWORD LChCnt; /**< Количество используемых логических каналов в таблице опроса АЦП
                       @fieldref{TLTR12_CONFIG,LChTbl}.
                       Определяет число пользовательских измерений в одном кадре
                       (цикле опроса каналов) АЦП. Сумма @fieldref{TLTR12_CONFIG,LChCnt}
                       и @fieldref{TLTR12_CONFIG,BgLChCnt} не должна превышать
                       #LTR12_MAX_LCHANNELS_CNT. */
    /** Логическая таблица. Определяет, какие каналы модуля должны быть опрошены в каком
        порядке и с какими настройками. */
    TLTR12_LCHANNEL LChTbl[LTR12_MAX_LCHANNELS_CNT];
} TLTR12_CONFIG;



/***************************************************************************//**
  @brief  Описатель модуля модуля

    Структура, которая хранит всю необходимую информацию о модуле и связи с ним:
    текущие настройки модуля, информацию о  его состоянии, структуру канала связи
    и т.д.

    При работе с несколькими модулями одновременно для каждого модуля должен быть
    создан свой описатель.

    Передается в большинство функций библиотеки.
    Некоторые поля структуры доступны для изменения пользователем
    для настройки параметров модуля.

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


#pragma pack ()


/** @} */

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

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

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


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

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

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

   @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_LTR12_ERROR_CODES).
*******************************************************************************/
LTR12API_DllExport(INT) LTR12_Open(TLTR12 *hnd, DWORD ltrd_addr, WORD ltrd_port, const CHAR *csn, INT slot);

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

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

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

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

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


/** @} */

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

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

   Функция передает настройки, соответствующие значениям полей
   [структуры конфигурации](@ref TLTR12::Cfg) описателя модуля, в модуль.
   Должна вызываться хотя бы раз до первого запуска сбора, а также после любых изменений
   настроек модуля, чтобы они вступили в силу.

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


/***************************************************************************//**
   @brief Вычисление частоты АЦП

   Вспомогательная функция, которая вычисляет значение частоты АЦП,
   соответствующее переданным параметрам в структуре конфигурации
   частоты #TLTR12_ADCFREQ_CFG.

   @param[in] adcCfg         Структура с параметрами, задающими частоту АЦП.
   @param[out] resultAdcFreq В данном параметре возвращается расчитанное значение
                             частоты АЦП в Гц, соответствующее переданным параметрам,
                             если переданные параметры были корректны.
   @return                  [Код ошибки](@ref e_LTR12_ERROR_CODES).
 ******************************************************************************/
LTR12API_DllExport(INT) LTR12_CalcAdcFreq(const TLTR12_ADCFREQ_CFG *adcCfg, double *resultAdcFreq);


/***************************************************************************//**
   @brief Подбор параметров частоты АЦП

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

   Полученные параметры возвращаются в виде заполненной структуры #TLTR12_ADCFREQ_CFG.

   Функция аналогична LTR12_FillAdcFreqParams(), но может использоваться без описателя
   модуля.

   @param[in] adcFreq         Требуемая частота АЦП в Гц.
   @param[out] adcCfg         Указатель на структуру, поля которой будут заполнены
                              подобранными значениями  параметров.
   @param[out] resultAdcFreq  Указатель на переменную, в которой будет возвращено
                              реально полученное значение частоты АЦП в Гц. Может быть
                              передан нулевой указатель, если это значение не требуется.
   @return                    [Код ошибки](@ref e_LTR12_ERROR_CODES).
******************************************************************************/
LTR12API_DllExport(INT) LTR12_FindAdcFreqParams(double adcFreq, TLTR12_ADCFREQ_CFG *adcCfg,
                                                double *resultAdcFreq);


/***************************************************************************//**
   @brief Заполнение параметров частоты АЦП

   Вспомогательная функция, которая по заданному значению частоты АЦП
   (суммарной на все каналы)  заполняет соответствующие параметры конфигурации
   описателя модуля  (структуру поля @fieldref{TLTR12_CONFIG,AdcFreqParams}),
   чтобы результирующая частота была наиболее близка к заданной.

   @param[in] hnd             Описатель модуля.
   @param[in] adcFreq         Требуемая частота АЦП в Гц.
   @param[out] resultAdcFreq  Указатель на переменную, в которой будет возвращено
                              реально полученное значение частоты АЦП в Гц. Может быть
                              передан нулевой указатель, если это значение не требуется.
   @return                    [Код ошибки](@ref e_LTR12_ERROR_CODES).
******************************************************************************/
LTR12API_DllExport(INT) LTR12_FillAdcFreqParams(TLTR12 *hnd, double adcFreq, double *resultAdcFreq);



/***************************************************************************//**
   @brief Заполнение параметров канала логической таблицы

   Вспомогательная функция для заполнения логического канала таблицы опроса
   АЦП в настройках описателя модуля.
   Функция принимает номер логического канала и его параметры и заполняет
   соответствующий элемент массива @fieldref{TLTR12_CONFIG,LChTbl}.

   @param[in] hnd             Описатель модуля.
   @param[in] lchNum          Номер логического канала (номер элемента таблицы
                              @fieldref{TLTR12_CONFIG,LChTbl}). Значение от 0
                              до #LTR12_MAX_LCHANNELS_CNT - 1.
   @param[in] phyChNum        Номер физического канала, который должен быть опрошен,
                              считая от 0.
   @param[in] mode            Режим измерения канала. Значение из #e_LTR12_CH_MODE.
   @return                    [Код ошибки](@ref e_LTR12_ERROR_CODES).
******************************************************************************/
LTR12API_DllExport(INT) LTR12_FillLChannel(TLTR12 *hnd, DWORD lchNum, BYTE phyChNum, BYTE mode);


/** @} */



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

/***************************************************************************//**
    @brief Измерение смещения нуля

    Функция выполняет измерение собственного нуля АЦП на заданной в конфигурации
    модуля частоте преобразования и сохраняет результирующее усредненное значение
    в поле   @fieldref{TLTR12_STATE,AdcZeroOffsetCode} структуры состояния
    @fieldref{TLTR12,State} описателя модуля.

    Это измеренное значение может быть использовано для корректировки смещения
    нуля принятых данных при передаче флага #LTR12_PROC_FLAG_ZERO_OFFS_COR
    в LTR12_ProcessData(), что позволяет учесть уход нуля АЦП на момент запуска
    измерений.

    Эта функция вызывается после конфигурации модуля непосредственно перед
    запуском сбора данных АЦП с помощью LTR12_Start().


    @param[in] hnd      Описатель модуля.
    @param[in] flags    Флаги (резерв --- должен передаваться 0)
    @return             [Код ошибки](@ref e_LTR12_ERROR_CODES).
*******************************************************************************/
LTR12API_DllExport(INT) LTR12_MeasAdcZeroOffset(TLTR12 *hnd, DWORD flags);


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

    Данная функция переводит модуль в режим сбора данных с АЦП.
    Если используется запуск сбора по внутреннему сигналу
    (@fieldref{TLTR12_CONFIG,AcqStartSrc} равно #LTR12_ACQ_START_SRC_INT),
    то при вызове данной функции запускается непосредственно опрос АЦП и
    модуль начинает передавать полученные отсчеты, которые необходимо вычитывать
    с помощью LTR12_Recv().

    В режиме запуска сбора от внешнего сигнала при вызове данной функции модуль
    переходит в режим ожидания указанного условия запуска, после чего уже
    будет запущен опрос АЦП и передача отсчетов.

    При завершении измерений для остановки сбора данных необходимо вызвать
    LTR12_Stop().

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

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

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

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

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


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

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

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

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

   @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 слов.
*******************************************************************************/
LTR12API_DllExport(INT) LTR12_Recv(TLTR12 *hnd, DWORD *data, DWORD *tmark,
                                   DWORD size,  DWORD timeout);



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

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

   Функция возвращает результаты только для измерений, соответствующей пользовательской
   таблице логических каналов (@fieldref{TLTR12_CONFIG,LChTbl}). Если включены
   фоновые измерения (@fieldref{TLTR12_CONFIG,BgLChCnt} > 0), то соответствующие
   измерения могут быть использованы только для корректировки текущего значения
   нуля, а сами результаты по этим каналам не сохраняются в выходной массив.

   В функцию необходимо передавать слова, выравненные на начало кадра и
   в количестве, кратном количеству слов в кадре (можно узнать по значению поля
   @fieldref{TLTR12_STATE,FrameWordsCount}).

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

   @param[in] hnd      Описатель модуля.
   @param[in] src      Указатель на массив, содержащий слова, принятые от модуля
                       с помощью LTR12_Recv(), которые нужно обработать.
   @param[out] dest    Указатель на массив, в который будут сохранены обработанные
                       значения измерений, соответствующих логическим каналам
                       таблицы @fieldref{TLTR12_CONFIG,LChTbl}.
                       Порядок следования соответствует порядку во входном
                       массиве: сперва первый отсчет первого логического канала,
                       затем первый отсчет второго логического канала и т.д.
   @param[in,out] size  На входе принимает размер массива src для обработки. На
                        выходе, при успешном завершении, возвращает количество
                        сохраненных отсчетов в массиве dest.
   @param[in]  flags   Флаги из #e_LTR12_PROC_FLAGS, управляющие работой функции.
                        Может быть объединено несколько флагов через логическое
                        ИЛИ.
   @return              [Код ошибки](@ref e_LTR12_ERROR_CODES).
  *****************************************************************************/
LTR12API_DllExport(INT) LTR12_ProcessData(TLTR12 *hnd, const DWORD *src,
                                          double *dest, INT *size, DWORD flags);


/***************************************************************************//**
   @brief Сбор одного кадра

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

   Принятые слова должны быть далее обработаны с помощью  LTR12_ProcessData().


   @param[in]  hnd      Описатель модуля.
   @param[out] data     Массив, в который будут сохранены принятые слова. Размер
                        должен быть достаточен для сохранения слов одного кадра,
                        который можно определить по полю
                        @fieldref{TLTR12_STATE,FrameWordsCount}.
   @param[in]  timeout  Таймаут на выполнение операции в миллисекундах. Если в течение
                        заданного времени не будет принято всех слов кадра,
                        то функция завершится с ошибкой.
   @return              [Код ошибки](@ref e_LTR12_ERROR_CODES).
*******************************************************************************/
LTR12API_DllExport(INT) LTR12_GetFrame(TLTR12 *hnd, DWORD *data, DWORD timeout);



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

   Функция находит в принятом с помощью LTR12_Recv() массиве слов от модуля
   индекс первого слова, соответствующего началу кадра.

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

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

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



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

/***************************************************************************//**
   @brief Чтение данных из пользователькой области flash-памяти модуля

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

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

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

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

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


/** @} */


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


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

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


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


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

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

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

/** @} */




#ifdef __cplusplus
}                                          // only need to export C interface if
// used by C++ source code
#endif

#endif                      /* #ifndef LTR12API_H_ */
