
#ifndef __LTR35API__
#define __LTR35API__

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


#include "ltrapi.h"

#ifdef __cplusplus
extern "C" {
#endif


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

/** Размер строки с именем модуля в структуре #TLTR35_MODULE_INFO */
#define LTR35_NAME_SIZE     8
/** Размер строки с серийным номером модуля в структуре #TLTR35_MODULE_INFO */
#define LTR35_SERIAL_SIZE   16

/** Максимальное количество каналов ЦАП */
#define LTR35_DAC_CHANNEL_CNT       8
/** Максимальное количество выходов для каждого канала ЦАП */
#define LTR35_DAC_CH_OUTPUT_CNT     2
/** Максимальное количество цифровых выходов */
#define LTR35_DOUT_MAX_CNT          16
/** Количество цифровых входов модуля */
#define LTR35_DIN_CNT               2

/** Максимальное количество отсчетов в одной странице буфера на вывод в режиме циклического автогенератора */
#define LTR35_MAX_POINTS_PER_PAGE   (4*1024*1024)

/** Количество арифметических синусоидальных генераторов в модуле */
#define LTR35_ARITH_SRC_CNT         4

/** Максимальное значение частоты генерации ЦАП в Гц, которое можно установить */
#define LTR35_DAC_FREQ_MAX              192000
/** Минимальное значение частоты генерации ЦАП в Гц, которое можно установить */
#define LTR35_DAC_FREQ_MIN              36000
/** Максимальное значение частоты генерации ЦАП в Гц для скорости #LTR35_DAC_RATE_SINGLE  */
#define LTR35_DAC_SINGLE_RATE_FREQ_MAX  54000
/** Максимальное значение частоты генерации ЦАП в Гц для скорости #LTR35_DAC_RATE_DOUBLE */
#define LTR35_DAC_DOUBLE_RATE_FREQ_MAX  108000

/** Стандартная частота генерации ЦАП в Гц для скорости #LTR35_DAC_RATE_QUAD */
#define LTR35_DAC_QUAD_RATE_FREQ_STD    192000
/** Стандартная частота генерации ЦАП в Гц для скорости #LTR35_DAC_RATE_DOUBLE */
#define LTR35_DAC_DOUBLE_RATE_FREQ_STD  96000
/** Стандартная частота генерации ЦАП в Гц для скорости #LTR35_DAC_RATE_SINGLE */
#define LTR35_DAC_SINGLE_RATE_FREQ_STD  48000
/** Частота синтезатора  в Гц , используемая для стандартных частот генерации ЦАП */
#define LTR35_SYNT_FREQ_STD             36864000


/** Максимальный код ЦАП */
#define LTR35_DAC_CODE_MAX                  0x7FFFFF
/** Код ЦАП, соответствующий максимальному значению диапазона в Вольтах */
#define LTR35_DAC_SCALE_CODE_MAX            0x600000


/** Устанавливаемое по умолчанию количество прочитанных отсчетов для выдачи
    периодического статуса в потоковом режиме */
#define LTR35_STREAM_STATUS_PERIOD_DEFAULT  1024
/** Максимальное значение количества отсчетов для выдачи
    периодического статуса в потоковом режиме */
#define LTR35_STREAM_STATUS_PERIOD_MAX      1024
/** Минимальное значение количества отсчетов для выдачи
    периодического статуса в потоковом режиме */
#define LTR35_STREAM_STATUS_PERIOD_MIN      8

/** Делитель частоты синтезатора для получения базовой частоты синхронного ввода
 *  с цифровых линий */
#define LTR35_DIN_SYNT_FREQ_DIV             4
/** Максимальное значение для степени делителя частоты синхронного ввода
 *  с цифровых линий */
#define LTR35_DI_STREAM_FREQ_DIV_POW_MAX    5

/** Адрес, с которого начинается пользовательская область Flash-памяти */
#define LTR35_FLASH_USERDATA_ADDR   0x100000
/** Размер пользовательской области flash-памяти */
#define LTR35_FLASH_USERDATA_SIZE   0x700000

/** Минимальный размер блока для стирания во Flash-памяти модуля */
#define LTR35_FLASH_ERASE_BLOCK_SIZE   1024



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

   Коды ошибок, которые определены и используются только в ltr35api.
   Остальные коды ошибок, которые используются разными модулями, определены в ltrapi.h. */
typedef enum {
    LTR35_ERR_INVALID_SYNT_FREQ             = -10200, /**< Задана неподдерживаемая частота синтезатора */
    LTR35_ERR_PLL_NOT_LOCKED                = -10201, /**< Ошибка захвата PLL*/
    LTR35_ERR_INVALID_CH_SOURCE             = -10202, /**< Задано неверное значение источника данных для канала */
    LTR35_ERR_INVALID_CH_RANGE              = -10203, /**< Задано неверное значение диапазона канала */
    LTR35_ERR_INVALID_DATA_FORMAT           = -10204, /**< Задано неверное значение формата данных */
    LTR35_ERR_INVALID_OUT_MODE              = -10205, /**< Задано неверное значение режима вывода */
    LTR35_ERR_INVALID_DAC_RATE              = -10206, /**< Задано неверное значение скорости выдачи на ЦАП */
    LTR35_ERR_INVALID_SYNT_CNTRS            = -10207, /**< Задано недопустимое значение счетчиков синтезатора */
    LTR35_ERR_UNSUPPORTED_CONFIG            = -10208, /**< Заданная конфигурация ЦАП не поддерживается */
    LTR35_ERR_INVALID_STREAM_STATUS_PERIOD  = -10209, /**< Задано неверное количество отсчетов для выдачи статуса в потоковом режиме */
    LTR35_ERR_DAC_CH_NOT_PRESENT            = -10210, /**< Выбранный канал ЦАП отсутствует в данном модуле */
    LTR35_ERR_DAC_NO_SDRAM_CH_ENABLED       = -10211, /**< Не разрешен ни один канал ЦАП на вывод из SDRAM */
    LTR35_ERR_DAC_DATA_NOT_ALIGNED          = -10212, /**< Данные ЦАП не выравнены на кол-во разрешенных каналов */
    LTR35_ERR_NO_DATA_LOADED                = -10213, /**< Не было загружено ни одного отсчета для циклического вывода */
    LTR35_ERR_LTRD_UNSUP_STREAM_MODE        = -10214, /**< Данная версия службы ltrd не поддерживает контроль переполнения буфера в потоковом режиме */
    LTR35_ERR_MODE_UNSUP_FUNC               = -10215, /**< Данная функция не поддерживается в установленном режиме */
    LTR35_ERR_INVALID_ARITH_GEN_NUM         = -10216, /**< Задано неверное значение номера арифметического генератора */
    LTR35_ERR_INVALID_IN_STREAM_MODE        = -10217, /**< Задан неверный режим потокового ввода */
    LTR35_ERR_INVALID_IN_DI_FREQ_DIV_POW    = -10218, /**< Задано неверное значение степени делителя частоты синхронного ввода с цифровых линий */
    LTR35_ERR_IN_DI_NO_CHANNELS             = -10219, /**< Не разрешен ни один вход для синхронного ввода с цифровых линий */
    LTR35_ERR_INVALID_IN_DI_CH_LIST         = -10220, /**< Задан неверный список каналов для синхронного ввода с цифровых линий */
    LTR35_ERR_INVALID_SYNC_MODE             = -10221, /**< Задано неверное значение режима синхронизации */
    LTR35_ERR_INVALID_SYNC_SLAVE_SRC        = -10222, /**< Задано неверное значение источника синхронизации для ведомого модуля */
    LTR35_ERR_SYNC_MODE_NOT_SET             = -10223, /**< Не удалось установить заданный режим синхронизации */
    LTR35_ERR_NO_START_REQUESTED            = -10224, /**< Не был выполнен запрос старта, завершение которого бы следовало ожидать */
    LTR35_ERR_DAC_REG_VALUE_CHECK           = -10225, /**< Ошибка контроля записи значений в регистры ЦАП */
} e_LTR35_ERROR_CODES;



/** Модификации модуля LTR35 */
typedef enum {
    LTR35_MOD_UNKNOWN = 0, /**< Неизвестная (не поддерживаемая библиотекой) модификация */
    LTR35_MOD_1 = 1,  /**< LTR35-1 */
    LTR35_MOD_2 = 2,  /**< LTR35-2 */
    LTR35_MOD_3 = 3   /**< LTR35-3 */
} e_LTR35_MODIFICATION;

/** Флаги, связанные с калибровочной информацией модуля */
typedef enum {
    LTR35_CBR_FLAG_HAS_FLASH_AFC_CBR   = 1 << 1, /**< Признак наличия во flash-памяти модуля индивидуальных калибровочных коэффициентов */
} e_LTR35_CBR_FLAGS;


/** @brief Флаги для управления цифровыми выходами

    Флаги управления цифровыми выходами. Могут быть объединены через логическое
    “ИЛИ” со значениями цифровых выходов при подготовке данных на вывод с помощью
    LTR35_PrepareData() */
typedef enum {
    LTR35_DIGOUT_WORD_DIS_H = 0x00020000, /**< Запрещение (перевод в третье состояние)
                                              старшей половины цифровых выходов.
                                              Имеет значение только для LTR35-3. */
    LTR35_DIGOUT_WORD_DIS_L = 0x00010000  /**< Запрещение младшей половины
                                              цифровых выходов */
} e_LTR35_DOUTS_WORD_FLAGS;


/** @brief Флаги для подготовки данных

    Флаги, управляющие работой функций LTR35_PrepareData() и LTR35_PrepareDacData() */
typedef enum {
    LTR35_PREP_FLAGS_VOLT   = 0x01, /**< Флаг указывает, что данные на входе
                                         заданы в Вольтах и их нужно перевести в коды */
} e_LTR35_PREP_FLAGS;


/** Формат отсчетов для передачи данных вывода модулю */
typedef enum {
    LTR35_OUTDATA_FORMAT_24 = 0, /**< 24-битный формат. Один отсчет занимает два 32-битных слова LTR */
    LTR35_OUTDATA_FORMAT_20 = 1  /**< 20-битный формат. Один отсчет занимает одно 32-битное слово LTR */
} e_LTR35_OUTDATA_FORMAT;

/** Режим вывода модуля */
typedef enum {
    LTR35_OUT_MODE_CYCLE    = 0, /**< Режим циклического автогенератора. Данные загружаются
                                  в буфер перед запуском выдачи, после чего выводятся
                                  по кругу без подкачки новых данных. Описан в разделе @ref sect_gen_mode_cycle. */
    LTR35_OUT_MODE_STREAM   = 1  /**< Потоковый режим. Данные постоянно должны загружаться
                                  в буфер модуля. Данные из буфера последовательно вычитываются при их наличии 
                                  и выводятся модулем.  Описан в разделе @ref sect_gen_mode_stream. */
} e_LTR35_OUT_MODE;

/** Используемый выход для канала ЦАП */
typedef enum {
    LTR35_DAC_OUT_FULL_RANGE = 0, /**< Выход 1:1 с диапазоном от -10 до +10 В для
                                       LTR35-1 и от 0 до +20 В для LTR35-2. */
    LTR35_DAC_OUT_DIV_RANGE  = 1  /**< Выход 1:10 (от -1 до 1 В) для LTR35-1.
                                       Для LTR35-2 данный выход не используется. */
} e_LTR35_DAC_OUTPUT;

/** Источники сигнала для каналов ЦАП */
typedef enum {
    LTR35_CH_SRC_SDRAM = 0, /**< Сигнал берется из буфера в SDRAM модуля.
                                 При этом буфер работает циклически или в виде
                                 очереди в зависимости от [режима вывода](@ref #e_LTR35_OUT_MODE). */
    LTR35_CH_SRC_SIN1  = 1, /**< Синус  от первого арифметического синусоидального
                                 генератора. */
    LTR35_CH_SRC_COS1  = 2, /**< Косинус  от первого арифметического синусоидального
                                 генератора. */
    LTR35_CH_SRC_SIN2  = 3, /**< Синус  от второго арифметического синусоидального
                                 генератора. */
    LTR35_CH_SRC_COS2  = 4, /**< Косинус  от второго арифметического синусоидального
                                 генератора. */
    LTR35_CH_SRC_SIN3  = 5, /**< Синус  от третьего арифметического синусоидального
                                 генератора. */
    LTR35_CH_SRC_COS3  = 6, /**< Косинус  от третьего арифметического синусоидального
                                 генератора. */
    LTR35_CH_SRC_SIN4  = 7, /**< Синус  от четвертого арифметического синусоидального
                                 генератора. */
    LTR35_CH_SRC_COS4  = 8 /**<  Косинус  от четвертого арифметического синусоидального
                                 генератора. */
} e_LTR35_CH_SRC;

/** @brief Скорость выдачи отсчетов ЦАП

    Скорость выдачи отсчетов ЦАП определяет количество тактов частоты
    синтезатора (\f$f_{synt}\f$), которое требуется для  выдачи одного отсчета ЦАП, 
    т.е. отношение частоты   генерации ЦАП к частоте синтезатора.
    */
typedef enum {
    LTR35_DAC_RATE_SINGLE = 0, /**< Одиночная скорость. Частота генерации равна \f$ f_{synt}/768\f$.
                                    Используется для частот генерации от 36 КГц (#LTR35_DAC_FREQ_MIN)
                                    до 54  КГц (#LTR35_DAC_SINGLE_RATE_FREQ_MAX) включительно. */
    LTR35_DAC_RATE_DOUBLE = 1, /**< Двойная скорость. Частота генерации равна \f$ f_{synt}/384\f$.
                                    Используется для частот вывода выше 54 КГц и до 108 КГц
                                    (#LTR35_DAC_DOUBLE_RATE_FREQ_MAX) включительно. */
    LTR35_DAC_RATE_QUAD   = 2  /**< Четверная скорость. Частота генерации равна \f$ f_{synt}/192\f$.
                                    Используется для частот генерации выше 108 КГц и до 192  КГц
                                    (#LTR35_DAC_FREQ_MAX) включительно. */
} e_LTR35_RATE;

/** @brief Режим синхронного ввода

   Данный режим определяет, будет ли одновременно с генерацией вывода запущен
   и синхронный ввод данных, а также какие именно данные будет передаваться в потоке
   на ввод.
   */
typedef enum {
    LTR35_IN_STREAM_MODE_OFF       = 0, /**< Синхронный ввод не используется. */
    LTR35_IN_STREAM_MODE_CH_ECHO   = 1, /**< Режим эхо-канала, в котором от модуля
                                             передается поток отсчетов, соответствующих
                                             выводимым на заданный с помощью поля
                                             @fieldref{TLTR35_IN_STREAM_CONFIG,EchoChannel} канал
                                             отсчетам ЦАП. Частота ввода соответствует частоте генерации ЦАП. */
    LTR35_IN_STREAM_MODE_DI        = 2 /**< Режим синхронного ввода состояний цифровых входов.
                                            Опрашиваемые входы определяются значением поля
                                            @fieldref{TLTR35_IN_STREAM_CONFIG,DIChEnMask},
                                            а частота ввода --- значением поля  
                                            @fieldref{TLTR35_IN_STREAM_CONFIG,DIFreqDivPow}. */
} e_LTR35_IN_STREAM_MODE;


/** @brief Флаги задания цифровых линий для синхронного ввода

    С помощью данных флагов определяется,  какие входы будут опрашиваться
    при синхронном вводе с цифровых линий.
*/
typedef enum {
    LTR35_IN_STREAM_DI1 = 0x00001, /**< Ввод значений с линии DI1 */
    LTR35_IN_STREAM_DI2 = 0x00002  /**< Ввод значений с линии DI2 */
} e_LTR35_IN_STREAM_DI_CHS;

/** @brief Режим синхронизации старта генерации модулей

   Данный режим определяет роль модуля при многомодульной синхронизации старта. */
typedef enum {
    LTR35_SYNC_MODE_INTERNAL = 0, /**< Внутренняя синхронизация. Модуль используются
                                       отдельно без синхронизации запуска с другими
                                       модулями. Запуск выполняется по команде от ПК,
                                       функции цифровых входов и выходов не переопределяются. */
    LTR35_SYNC_MODE_MASTER   = 1, /**< Модуль является ведущим при синхронизации старта
                                       нескольких модулей. Запуск выполняется по команде с ПК.
                                       При этом выход DO8 на время вывода используется для выдачи
                                       сигнала синхронизации для ведомых модулей. */
    LTR35_SYNC_MODE_SLAVE    = 2, /**< Запуск генерации определяется по 
                                       условию, заданному с помощью поля @fieldref{TLTR35_SYNC_CONFIG,SlaveSrc}.
                                       Данный режим используется для ведомых модулей при 
                                       синхронизации старта нескольких модулей, а также для синхронизации
                                       запуска генерации от внешнего источника. */
} e_LTR35_SYNC_MODE;


/** @brief Условие запуска генерации для подчиненного модуля

    Варианты условий запуска генерации для модуля в режиме синхронизации
    #LTR35_SYNC_MODE_SLAVE.
*/
typedef enum {
    LTR35_SYNC_SLAVE_SRC_DI2_RISE   = 0, /**< Запуск по фронту сигнала на входе DI2.
                                              Этот режим должен использоваться также в случае,
                                              если источником сигнала является другой
                                              модуль LTR35 в режиме мастера. */
    LTR35_SYNC_SLAVE_SRC_DI2_FALL   = 1, /**< Запуск по спаду сигнала на входе DI2. */
} e_LTR35_SYNC_SLAVE_SRC;


/** @brief Флаги конфигурации модуля

    Флаги, определяющие дополнительные параметры конфигурации модуля. */
typedef enum {
    /** Если данный флаг установлен, то при генерации сигнала не используется
     * фильтр для коррекции АЧХ модуля. */
    LTR35_CFG_FLAG_DISABLE_AFC_COR         = 0x00000001,

    /** Запрет передачи статусных слов для контроля переполнения буфера службой ltrd. */
    LTR35_CFG_FLAG_DISABLE_PERIODIC_STATUS =  0x00000100
}  e_LTR35_CFG_FLAGS;

/** Флаги для записи во flash-память модуля */
typedef enum {
    /** Признак, что записываемая область памяти уже стерта и не требуется
        дополнительно стирать обновляемые сектора. */
    LTR35_FLASH_WRITE_ALREADY_ERASED = 0x00001
} e_LTR35_FLASH_WRITE_FLAGS;


/** @brief Флаги состояния модуля

    Набор флагов, определяющих состояние модуля. Возвращаются функцией
    LTR35_GetStatus() */
typedef enum {
    LTR35_STATUS_FLAG_PLL_LOCK      = 0x0001, /**< Признак захвата PLL в момент
                                                    передачи статуса. Если равен
                                                   нулю, то модуль неработоспособен. */
    LTR35_STATUS_FLAG_PLL_LOCK_HOLD = 0x0002, /**< Признак, что захват PLL не
                                                   пропадал с момента предыдущей
                                                   передачи статуса. Должен быть
                                                   установлен во всех статусах,
                                                   кроме первого после сброса модуля. */

    LTR35_STATUS_FLAG_SYNC_MODE     = 0x0030, /**< 2 бита, определяющие текущий
                                                   настроенный режим синхронизации
                                                   модуля (коды из перечисления
                                                   #e_LTR35_SYNC_MODE).
                                                   Данное значение обновляется после
                                                   вызова LTR35_Configure() в соответствии
                                                   со значением поля @fieldref{TLTR35_SYNC_CONFIG,SyncMode}. */
    LTR35_STATUS_FLAG_DI1_STATE     = 0x0040, /**< Состояние входа DI1 */
    LTR35_STATUS_FLAG_DI2_STATE     = 0x0080  /**< Состояние входа DI2 */
} e_LTR35_STATUS;


/** @brief Состояние запуска ввода-вывода

    Текущее состояние процесса запуска синхронного ввода-вывод модуля LTR35. */
typedef enum {
    LTR35_RUNSTATE_STOPPED           = 0, /**< Ввод-вывод остановлен. */
    LTR35_RUNSTATE_SLAVE_RDY_WAITING = 1, /**< Передана команда запуска ввода-вывода для подчиненного модуля,
                                            но еще не получен ответ, что модуль принял команду и уже
                                            готов реагировать на сигнал запуска.
                                            В данное состояние переходит подчиненный модуль после вызова
                                            LTR35_StreamStartRequest() для прошивки FPGA версии 25 или выше. */
    LTR35_RUNSTATE_START_ACK_WAITING = 2, /**< Передана команда запуска ввода-вывода, но еще не получен
                                            ответ, что ввод-вывод был реально запущен модулем.
                                            В данное состояние переходит модуль по вызову
                                            LTR35_SwitchCyclePageRequest() и LTR35_StreamStartRequest(),
                                            если модуль не является подчиненным, либо после успешного
                                            завершения LTR35_StreamStartWaitSlaveReady() для подчиненного.
                                            */
    LTR35_RUNSTATE_RUNNING           = 3  /**< Ввод-вывод активен (получен ответ от модуля, что ввод-вывод
                                            был запущен). В данное состояние модуль переходит при успешном
                                            завершении ожидания запуска с помощью LTR35_SwitchCyclePageWaitDone()
                                            или LTR35_StreamStartWaitDone(), а также при успешном выполнении
                                            функций запуска без выделения стадии ожидания: LTR35_SwitchCyclePage()
                                            или LTR35_StreamStart() */
} e_LTR35_RUN_STATE;

/** @} */

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

#pragma pack(4)

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

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

/** @brief Описание выхода ЦАП

    Структура описывает характеристики определенного выхода для данной модификации
    модуля LTR35. */
typedef struct {
    double AmpMax; /**< Максимальное пиковое значение амплитуды сигнала для данного выхода. */
    double AmpMin; /**< Минимальное пиковое значение амплитуды сигнала для данного выхода. */
    INT    CodeMax; /**< Код ЦАП, соответствующий максимальной амплитуде. */
    INT    CodeMin; /**< Код ЦАП, соответствующий минимальной амплитуде. */
    DWORD  Reserved[3]; /**< Резервные поля. */
} TLTR35_DAC_OUT_DESCR;


/** @brief Коэффициенты для калибровки АЧХ

    Структура описывает коэффициенты и параметры, используемые для коррекции АЧХ ЦАП  */
typedef struct {
    BOOLEAN Valid;      /**< Признак действительности значения остальных полей. */
    DWORD  Reserved[3]; /**< Резервные поля. */
    double Fd;          /**< Частота генерации ЦАП, на которой измерено отношение амплитуд. */
    double SigFreq;     /**< Частота сигнала, для которой измерено отношение амплитуд. */
    /** Набор отношений реально выставленной амплитуды синусоидального сигнала
     *  частоты @fieldref{TLTR35_AFC_COEF,SigFreq} к задаваемой амплитуде
     *  при частоте генерации @fieldref{TLTR35_AFC_COEF,Fd} для каждого канала ЦАП. */
    double K[LTR35_DAC_CHANNEL_CNT];
} TLTR35_AFC_COEF;

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

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

    Все поля доступны после вызова LTR35_Open(). */
typedef struct {
    CHAR        Name[LTR35_NAME_SIZE];      /**< Название модуля
                                                (оканчивающаяся нулем ASCII-строка) */
    CHAR        Serial[LTR35_SERIAL_SIZE];  /**< Серийный номер модуля
                                                  (оканчивающаяся нулем ASCII-строка) */
    WORD        VerFPGA;                     /**< Версия прошивки ПЛИС модуля
                                                  (действительна только при ее наличии) */
    BYTE        VerPLD;                      /**< Версия прошивки PLD  */

    BYTE        Modification;               /**< Модификация модуля. Одно из значений из #e_LTR35_MODIFICATION. */
    BYTE        DacChCnt;                   /**< Количество установленных каналов ЦАП */
    BYTE        DoutLineCnt;                /**< Количество линий цифрового вывода */

    /** Описание параметров выходов ЦАП для данной модификации модуля. */
    TLTR35_DAC_OUT_DESCR  DacOutDescr[LTR35_DAC_CH_OUTPUT_CNT];
    DWORD       Reserved1[25]; /**< Резервные поля */
    DWORD       CbrFlags; /**< Набор флагов из #e_LTR35_CBR_FLAGS */
    /** Заводские калибровочные коэффициенты. */
    TLTR35_CBR_COEF CbrCoef[LTR35_DAC_CHANNEL_CNT][LTR35_DAC_CH_OUTPUT_CNT];
    /** Заводские коэффициенты для коррекции АЧХ модуля. */
    TLTR35_AFC_COEF CbrAfcCoef;
    /** Дополнительные резервные поля */
    DWORD       Reserved2[64*LTR35_DAC_CHANNEL_CNT*LTR35_DAC_CH_OUTPUT_CNT - 24];
} TLTR35_MODULE_INFO;



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

    Структура, содержащая настройки одного канала ЦАП. */
typedef struct {
    BOOLEAN Enabled; /**< Разрешение выдачи сигнала для данного канала. */
    BYTE    Output;  /**< Используемый выход для данного канала (значение из #e_LTR35_DAC_OUTPUT). */
    BYTE    Source;  /**< Источник данных для данного канала (значение из #e_LTR35_CH_SRC). */
    double  ArithAmp; /**< Амплитуда сигнала в режиме арифметического генератора. */
    double  ArithOffs; /**< Смещение сигнала в режиме арифметического генератора. */
    DWORD   Reserved[10]; /**< Резервные поля. */
} TLTR35_CHANNEL_CONFIG;

/** @brief Значение фазы для арифметических генероторов

    Структура используется для задания значения фазы в настройках
    арифметического генератора.
    Для заполнения данной структуры по требуемому значению фазы в градусах
    можно использовать функцию LTR35_FillArithPhaseDegree().
*/
typedef struct {
    DWORD Reserved; /**< Резерв */
    DWORD CodeH;    /**< 32-битный код, задающий фазу. Каждый разряд имеет вес
                         \f$2\pi/2^{32}\f$. */
} TLTR35_ARITH_PHASE;

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

    Структура, содержащая настройки одного арифметического генератора. */
typedef struct {
    TLTR35_ARITH_PHASE Phase; /**< Начальная фаза сигнала. */
    TLTR35_ARITH_PHASE Delta; /**< Приращение фазы сигнала.
                                   На данное значение изменяется фаза каждого следующего выводимого
                                   отсчета относительно предыдущего. */
    DWORD   Reserved[14]; /**< Резервные поля. */
} TLTR35_ARITH_SRC_CONFIG;

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

    Стркутура, содержащая коэффициенты, определяющие результирующую частоту
    на выходе синтезатора частоты.

    Для получения входной частоты ЦАП из опорной частоты 30 МГц в модуле
    используется синтезатор. Полученная на выходе синтезатора частота определяется
    3-мя коэффициентами, заданными в данной структуре, и рассчитывается по формуле
    \f$ f_{synt}=\frac{f_{in}*b}{r*2*a}\f$, где \f$f_{in}=30 \f$ МГц.
    
    Отношение результирующей частоты генерации ЦАП к полученной частоте синтезатора
    определяется заданной с помощью поля @fieldref{TLTR35_CONFIG,DacRate}
    скорости выдачи на ЦАП.

    Также частота с выхода синтезатора является базовой частотой для синхронного ввода
    с цифровых линий, как указано в описании настройки @fieldref{TLTR35_IN_STREAM_CONFIG,DIFreqDivPow}.

    Как правило пользователю не требуется заполнять эти параметры вручную. Для
    их заполнения используется функция LTR35_FillOutFreq().
 */
typedef struct {
    WORD b; /**< Коэффициент b в настройках синтезатора */
    WORD r; /**< Коэффициент r в настройках синтезатора */
    BYTE a; /**< Коэффициент a в настройках синтезатора */
} TLTR35_FREQ_SYNT_CONFIG;

/** @brief Настройки синхронного ввода

    Данная структура содержит параметры синхронного ввода данных, выполняемого
    при необходимости одновременно с выводом. */
typedef struct {
    BYTE InStreamMode;  /**< Используемый режим синхронного ввода. Значение из #e_LTR35_IN_STREAM_MODE. */
    BYTE EchoChannel;   /**<  Для режима синхронного ввода #LTR35_IN_STREAM_MODE_CH_ECHO
                              данное поле задает номер канала (начиная с 0), выводимые
                              значения которого будут содержать эхо-данные. Данный
                              канал должен быть разрешен, чтобы эти данные были корректны. */
    BYTE DIChEnMask;    /**< Для режима синхронного ввода #LTR35_IN_STREAM_MODE_DI данное
                             поле задает, какие именно цифровые входы будут опрашиваться.
                             Данное поле определяется как комбинация флагов из
                             #e_LTR35_IN_STREAM_DI_CHS, объединенных по битовому
                             "ИЛИ". При режиме ввода #LTR35_IN_STREAM_MODE_DI должен
                             быть разрешен опрос хотя бы одного входа. */
    BYTE DIFreqDivPow;  /**< Для режима синхронного ввода #LTR35_IN_STREAM_MODE_DI
                             данное поле задает значение степени делителя в формуле
                             определения частоты синхронного ввода.
                             Данное поле может принимать значения от 0 (при опросе одного входа)
                             или 1 (если опрашиваются оба входа) до #LTR35_DI_STREAM_FREQ_DIV_POW_MAX.
                             Формула для определения частоты опроса описана в разделе
                             @ref sect_gen_cfg_in_stream. Также для заполнения
                             этого поля можно использовать функцию LTR35_FillDIAcqFreq(). */
    DWORD Reserved[7]; /**< Резервные поля. */
} TLTR35_IN_STREAM_CONFIG;

/** @brief Настройки синхронизации старта

    Данная структура содержит параметры синхронизации
    запуска ввода-вывода модуля с другими модулями или  с внешним сигналом. */
typedef struct {
    BYTE SyncMode; /**< Режим синхронизации старта. Значение из #e_LTR35_SYNC_MODE. */
    BYTE SlaveSrc; /**< Для режима синхронизации #LTR35_SYNC_MODE_SLAVE данное
                        поле задает условие запуска ввода-вывода.
                        Значение из #e_LTR35_SYNC_SLAVE_SRC. */
    DWORD Reserved[7]; /**< Резервные поля. */
} TLTR35_SYNC_CONFIG;

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

    Структура содержит все настройки модуля, которые должен заполнить
    пользователь перед вызовом LTR35_Configure(). */
typedef struct {
    /** Настройки каналов ЦАП. */
    TLTR35_CHANNEL_CONFIG    Ch[LTR35_DAC_CHANNEL_CNT];
    /** Настройки арифметических генераторов. */
    TLTR35_ARITH_SRC_CONFIG  ArithSrc[LTR35_ARITH_SRC_CNT];
    /** Резервные поля (должны быть установлены в 0) */
    TLTR35_ARITH_SRC_CONFIG  ArithSrcReserved[LTR35_ARITH_SRC_CNT];

    BYTE OutMode; /**< Режим вывода модуля (значение из #e_LTR35_OUT_MODE). */
    BYTE OutDataFmt; /**< Формат данных для вывода (значение из #e_LTR35_OUTDATA_FORMAT). */

    BYTE DacRate; /**< Скорость выдачи данных на ЦАП (константа из #e_LTR35_RATE).
                       Как правило заполняется с помощью функции LTR35_FillOutFreq(). */
    TLTR35_FREQ_SYNT_CONFIG FreqSynt; /**< Настройки синтезатора.
                        Как правило заполняются с помощью функции LTR35_FillOutFreq().*/

    WORD StreamStatusPeriod; /**< Период передачи статусных слов. В потоковом
                                  режиме (@fieldref{TLTR35_CONFIG,OutMode}
                                  = #LTR35_OUT_MODE_STREAM) статусное слово будет
                                  передаваться после вывода каждых
                                  @fieldref{TLTR35_CONFIG,StreamStatusPeriod} слов из буфера.
                                  0 означает выбор значения по-умолчанию. */
    DWORD Flags;          /**< Дополнительные флаги конфигурации. Объединение
                               по битовому "ИЛИ" флагов из перечисления #e_LTR35_CFG_FLAGS. */
    TLTR35_IN_STREAM_CONFIG InStream; /**< Настройки синхронного ввода. */
    TLTR35_SYNC_CONFIG Sync; /**< Настройки синхронизации запуска нескольких модулей. */
    DWORD Reserved[47];   /**< Резервные поля (должны быть установлены в 0). */
} TLTR35_CONFIG;


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

    Структура, содержащая параметры модуля, которые пользователь должен использовать
    только для чтения, так как они изменяются только внутри функций ltr35api. */
typedef struct {
    BYTE    FpgaState; /**<  Текущее состояние ПЛИС. Одно из значений из e_LTR_FPGA_STATE. */
    BOOLEAN Run;      /**< Признак, запущен ли сейчас ввод-вывод данных. */
    BYTE    RunState; /**< Более подробное состояние запуска ввода-вывода. Принимает одно из значений
                           перечисления #e_LTR35_RUN_STATE. */
    double OutFreq; /**< Установленная частота генерации ЦАП (Гц) и вывода на цифровые линии.
                          Обновляется после вызова LTR35_Configure(). */
    BYTE   EnabledChCnt; /**< Количество разрешенных каналов ЦАП. Обновляется после
                               вызова LTR35_Configure(). */
    BYTE   SDRAMChCnt; /**< Количество разрешенных каналов ЦАП, отсчеты для
                             которых берутся из буфера модуля. Обновляется после
                             вызова LTR35_Configure(). */
    BYTE   ArithChCnt; /**< Количество разрешенных каналов ЦАП, настроенных
                             на режим арифметического генератора. Обновляется после
                             вызова LTR35_Configure(). */
    BYTE   InStreamDIChCnt;  /**< Количество опрашиваемых цифровых входов в
                               режиме #LTR35_IN_STREAM_MODE_DI.
                               Обновляется после вызова LTR35_Configure(). */
    double InStreamDIAcqFreq; /**< Частота опроса (Гц) каналов цифровых входов #LTR35_IN_STREAM_MODE_DI
                                   (соответствует одному биту каждого опрашиваемого канала).
                                   Обновляется после вызова LTR35_Configure(). */
    double InStreamWordFreq; /**< Установленная частота (Гц) передачи слов из модуля в ПК
                                   при разрешенном синхронном вводе. Обновляется после вызова LTR35_Configure(). */
    double SyntFreq; /**< Частота синтезатора (Гц). Обновляется после вызова LTR35_Configure(). */
    DWORD  Reserved[26]; /**< Резервные поля. */
} TLTR35_STATE;

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

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

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

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

    Перед использованием требует инициализации с помощью функции  LTR35_Init().
 */
typedef struct {
    INT size;            /**< Размер структуры. Заполняется в LTR35_Init(). */
    /** Структура, содержащая состояние клиентского соединения со службой ltrd.
        Не используется напрямую пользователем. */
    TLTR Channel;
    /** Указатель на непрозрачную структуру с внутренними параметрами,
      используемыми исключительно библиотекой и недоступными для пользователя. */
    void *Internal;
    TLTR35_CONFIG Cfg;           /**< Настройки модуля. Заполняются пользователем
                                      перед вызовом LTR35_Configure(). */
    /** Состояние модуля и рассчитанные параметры. Поля изменяются функциями
        библиотеки. Пользовательской программой могут использоваться
        только для чтения. */
    TLTR35_STATE  State;
    TLTR35_MODULE_INFO ModuleInfo; /**< Информация о модуле. */
} TLTR35;
#pragma pack()


/** @} */

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

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

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

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

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

   В случае возникновения некритических ошибок, функция может вернуть код ошибки,
   но оставить соединение открытым, но не в полностью рабочем состоянии. Проверить, осталось
   ли соединение открытым, можно с помощью LTR35_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_LTR35_ERROR_CODES).
*******************************************************************************/
LTR35API_DllExport(INT) LTR35_Open(TLTR35 *hnd, DWORD ltrd_addr, WORD ltrd_port,
                                   const CHAR *csn, WORD slot);
/***************************************************************************//**
   @brief Закрытие соединения с модулем

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

   @param[in] hnd       Описатель модуля
   @return              Код ошибки
 ******************************************************************************/
LTR35API_DllExport(INT) LTR35_Close (TLTR35 *hnd);

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

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

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


/***************************************************************************//**
   @brief Подбор коэффициентов для получения заданной частоты генерации ЦАП и цифрового вывода

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

   @param[in,out] cfg       Структура с настройками модуля, поля которой будут изменены,
                            чтобы полученная частота преобразования ЦАП была наиболее
                            близка к заданной. Поля, не влияющие на частоту
                            преобразования ЦАП, будут оставлены без изменений.
   @param[in]     freq      Требуемая частота преобразования ЦАП в Гц.
   @param[out]    fnd_freq  В данной переменной возвращается реально полученная
                            частота генерации ЦАП в Гц, соответствующая подобранным
                            параметрам. Может быть передан нулевой указатель,
                            если это значение не интересует.
   @return                  [Код ошибки](@ref e_LTR35_ERROR_CODES).
 ******************************************************************************/
LTR35API_DllExport(INT) LTR35_FillOutFreq(TLTR35_CONFIG *cfg, double freq, double *fnd_freq);

/***************************************************************************//**
   @brief Подбор степени делителя частоты ввода с цифровых линий

   Функция подбирает значение поля @fieldref{TLTR35_IN_STREAM_CONFIG,DIFreqDivPow}
   так, чтобы полученная частота опроса цифровых входов была наиболее близкой к заданной
   пользователю.

   Перед вызовом данной функции уже должны быть заполнены настройки синтезатора
   (явным заданием значений в поле @fieldref{TLTR35_CONFIG,FreqSynt} или с помощью
   LTR35_FillOutFreq()), а также значения полей @fieldref{TLTR35_IN_STREAM_CONFIG,InStreamMode}
   и @fieldref{TLTR35_IN_STREAM_CONFIG,DIChEnMask}.

   @param[in,out] cfg       Структура с настройками модуля, в которой должны быть
                            уже заполнены указанные в описании функции поля и
                            в которую будет записано полученное значение поля
                            @fieldref{TLTR35_IN_STREAM_CONFIG,DIFreqDivPow} в случае
                            успешного завершения функции.
   @param[in]     freq      Требуемая частота опроса синхронных входов в Гц.
   @param[out]    fnd_freq  В данной переменной возвращается реально полученная
                            частота опроса цифровых линий, соответствующая подобранным
                            параметрам. Может быть передан нулевой указатель,
                            если это значение не интересует.
   @return                  [Код ошибки](@ref e_LTR35_ERROR_CODES).
******************************************************************************/
LTR35API_DllExport(INT) LTR35_FillDIAcqFreq(TLTR35_CONFIG *cfg, double freq, double *fnd_freq);


/***************************************************************************//**
   @brief Подбор кода арифметической фазы по значению в градусах.

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

   @param[out]  phase_code  Структура настроек фазы, которая будет заполненна
                            нужными значениями при успешном выполнении функции.
   @param[in]   degree      Требуемая фаза в градусах. Может принимать значения
                            от 0 (включая) до 360 (не включая) градусов.
   @param[out]  res_degree  В данной переменной возвращается реально полученное значение
                            фазы в градусах. Может быть передан нулевой указатель,
                            если это значение не интересует.
   @return                  [Код ошибки](@ref e_LTR35_ERROR_CODES).
******************************************************************************/
LTR35API_DllExport(INT) LTR35_FillArithPhaseDegree(TLTR35_ARITH_PHASE *phase_code, double degree, double *res_degree);


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

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

   @param[in] hnd       Описатель модуля
   @return              [Код ошибки](@ref e_LTR35_ERROR_CODES).
 ******************************************************************************/
LTR35API_DllExport(INT) LTR35_Configure(TLTR35 *hnd);
/** @} */



/***************************************************************************//**
    @addtogroup func_stream Функции для управления выдачей данных
    @{
*******************************************************************************/

/***************************************************************************//**
    @brief Передача данных ЦАП и цифровых выходов в модуль

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

    Завершение функции означает только то, что данные записаны в буфер канала обмена
    со службой ltrd. Данные могут дойти до самого модуля и быть выведены позже.

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

    @param[in]  hnd     Описатель модуля.
    @param[in]  data    Массив со словами, которые необходимо передать модулю.
    @param[in]  size    Количество передаваемых 32-битных слов.
    @param[in]  timeout Таймаут на выполнение функции в мс.
    @return    Значение меньше 0 соответствует [коду ошибки](@ref e_LTR35_ERROR_CODES).
                         Значение больше или равное нулю --- количество записанных слов.
 ******************************************************************************/
LTR35API_DllExport(INT) LTR35_Send(TLTR35 *hnd, const DWORD *data,
                                    DWORD size, DWORD timeout);

/***************************************************************************//**
    @brief Подготовка данных для передачи в модуль

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

    Данные от ЦАП принимаются в следующем порядке: 1-ый отсчет первого разрешенного
    канала с источником из буфера модуля, затем 1-ый отсчет второго такого канала
    и т.д., затем по второму отсчету каждого канала и т.д. Количество данных
    ЦАП на входе должно быть кратно количеству разрешенных каналов с источником
    #LTR35_CH_SRC_SDRAM (поле @fieldref{TLTR35_STATE,SDRAMChCnt}
    структуры состояния модуля @fieldref{TLTR35,State}). Данные для ЦАП могут
    быть либо в кодах ЦАП, либо в Вольтах (если передан флаг #e_LTR35_PREP_FLAGS).
    При этом калибровки применяются всегда аппаратно внутри модуля.

    Также функция принимает данные цифровых линий --- младшие биты соответствуют
    значениям цифровых линий, которые могут быть объединены по битовому "ИЛИ" с флагами
    из #e_LTR35_DOUTS_WORD_FLAGS. На каждые @fieldref{TLTR35_STATE,SDRAMChCnt}
    отсчетов ЦАП в выходной буфер помещается одно слово цифровых линий.

    Формат выходных слов и количество слов на отсчет определяется заданным
    [форматом передаваемых данных](@ref TLTR35_CONFIG::OutDataFmt).
    Функция завершает работу как только закончится один из входных массивов
    или место в выходном буфере.

    @param[in]  hnd         Описатель модуля.
    @param[in]  dac_data    Массив отсчетов ЦАП. Может быть передан нулевой указатель,
                            если используются только вывод на цифровые линии.
    @param[in,out] dac_size На входе задает количество отсчетов в массиве dac_data,
                            на выходе возвращает, сколько отсчетов было реально
                            записано в выходной массив.
    @param[in] dout_data    Массив значений для вывода на цифровые линии.
                            Может быть передан нулевой указатель,
                            если используются только данные ЦАП.
    @param[in,out] dout_size На входе задает количество значений в массиве dout_data,
                             на выходе возвращает, сколько значений было реально
                             записано в выходной массив.
    @param[in] flags         Набор флагов из #e_LTR35_PREP_FLAGS.
    @param[out] result       Результирующий массив в специальном формате для
                             передачи в модуль.
    @param[in,out] snd_size  На входе задает размер массива result, на выходе
                             возвращает, сколько всего 32-битных слов было записано
                             в массив result в ходе выполнения функции.
    @return                  [Код ошибки](@ref e_LTR35_ERROR_CODES).
 ******************************************************************************/
LTR35API_DllExport(INT) LTR35_PrepareData(TLTR35 *hnd, const double *dac_data,
                                          DWORD *dac_size, const DWORD *dout_data,
                                          DWORD *dout_size,DWORD flags,
                                          DWORD *result, DWORD *snd_size);

/***************************************************************************//**
    @brief Подготовка данных ЦАП для передачи в модуль

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

    @param[in]  hnd         Описатель модуля.
    @param[in]  dac_data    Массив отсчетов ЦАП. Формат аналогичен
                            LTR35_PrepareData().
    @param[in]  size        Количество отсчетов в массиве dac_data. Значение
                            должно быть кратно @fieldref{TLTR35_STATE,SDRAMChCnt}.
    @param[in] flags        Набор флагов из #e_LTR35_PREP_FLAGS
    @param[out] result      Результирующий массив в специальном формате для
                            передачи в модуль. Массив должен быть размером
                            не меньше n*size, где n = 1 или 2 в зависимости от
                            [формата передаваемых данных](@ref TLTR35_CONFIG::OutDataFmt).
    @param[out] snd_size    Если не нулевой указатель, то в данной переменной
                            возвращается количество подготовленных слов для
                            передачи в модуль.
    @return                 [Код ошибки](@ref e_LTR35_ERROR_CODES).
 ******************************************************************************/
LTR35API_DllExport(INT) LTR35_PrepareDacData(TLTR35 *hnd, const double *dac_data,
                                             DWORD size, DWORD flags, DWORD *result,
                                             DWORD *snd_size);
/***************************************************************************//**
    @brief Смена страницы вывода в режиме циклического автогенератора

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

    Функция доступна только в режиме циклического автогенератора
    (@fieldref{TLTR35_CONFIG,OutMode} = #LTR35_OUT_MODE_CYCLE).

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

    Функция возвращает управления после получения подтверждения смены страницы.
    Так как для этого все ранее записанные данные должны быть переданы в модуль
    и кроме того, если уже идет выдача данных, то она должна дойти до последнего
    отсчета из выдаваемой страницы, то время ответа может быть значительным.
    Именно поэтому таймаут задается вручную через параметр функции. 
    
    @param[in]  hnd         Описатель модуля.
    @param[in]  flags       Флаги (резерв --- должен передаваться 0).
    @param[in]  tout        Таймаут в мс на время выполнения функции (на время
                            ожидания ответа о завершении смены страницы).
    @return                 [Код ошибки](@ref e_LTR35_ERROR_CODES).
 ******************************************************************************/
LTR35API_DllExport(INT) LTR35_SwitchCyclePage(TLTR35 *hnd, DWORD flags, DWORD tout);

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

    Функция аналогична LTR35_SwitchCyclePage(), но не дожидается ответа от модуля
    о том, что смена страниц завершилась.
    Ожидание завершения смены страниц выполняется с помощью функции LTR35_SwitchCyclePageWaitDone().

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


/***************************************************************************//**
    @brief Ожидание завершения смены страницы в режиме циклического автогенератора

    Данная функция ожидает возвращения подтверждения от модуля об успешной
    смене страниц после вызова LTR35_SwitchCyclePageRequest().

    Если подтверждение смены страницы успешно принято, то данная функция вернет
    LTR_OK.

    Если же ответа дождаться не удалось, то функция вернет ошибку
    LTR_ERROR_OP_DONE_WAIT_TOUT. В этом случае данную функции можно вызывать повторно
    для продолжения ожидания, либо вызвать LTR35_Stop() для отмены смены страницы
    и останова вывода.

    @param[in]  hnd         Описатель модуля.
    @param[in]  tout        Максимальное время ожидания подтверждения.
    @return                 [Код ошибки](@ref e_LTR35_ERROR_CODES).
 ******************************************************************************/
LTR35API_DllExport(INT) LTR35_SwitchCyclePageWaitDone(TLTR35 *hnd, DWORD tout);

/***************************************************************************//**
    @brief Запуск ввода-вывода в потоковом режиме

    При вызове данной функции начинается выдача данных на ЦАП в потоковом режиме
    (@fieldref{TLTR35_CONFIG,OutMode} = #LTR35_OUT_MODE_STREAM).

    При этом для реализации непрерывного вывода часть данных уже должна
    быть предзагружена в буфер модуля с помощью LTR35_Send().

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


/***************************************************************************//**
    @brief Запрос на запуск ввода-вывода в потоковом режиме

    Функция аналогична LTR35_StreamStart(), но не дожидается ответа от модуля
    о том, что запуск произошел.
    Ожидание запуска выполняется с помощью функции LTR35_StreamStartWaitDone().

    Использование такого разделения удобно в частности для запуска ведомого модуля
    (#LTR35_SYNC_MODE_SLAVE), так как в этом случае между посылкой команды запуска с помощью
    LTR35_StreamStartRequest() и до собственно осуществления запуска по внешнему
    условию синхронизации (после чего только и вернет модуль ответ)
    может пройти значительное время.

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


/***************************************************************************//**
    @brief Ожидание готовности подчиненного модуля к приему сигнала запуска ввода-вывода

    Данная функция ожидает возвращения подтверждения от подчиненного модуля LTR35 о
    готовности принимать внешний сигнал запуска ввода-вывода.

    Данная функция позволяет определить, когда можно запускать ведущий модуль, при
    одновременном запуске нескольких LTR35 в режиме ведущий-ведомые. Только когда
    все ведомые модули будут готовы принимать внешний сигнал запуска, можно
    вызывать LTR35_StreamStartRequest() или LTR35_StreamStart() для ведущего модуля.


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

    Если же ответа дождаться не удалось, то функция вернет ошибку
    LTR_ERROR_OP_DONE_WAIT_TOUT. В этом случае данную функции можно вызывать повторно
    для продолжения ожидания, либо вызвать LTR35_Stop() для отмены запуска ввода-вывода.

    @param[in]  hnd         Описатель модуля.
    @param[in]  tout        Максимальное время ожидания подтверждения.
    @return                 [Код ошибки](@ref e_LTR35_ERROR_CODES).
 ******************************************************************************/
LTR35API_DllExport(INT) LTR35_StreamStartWaitSlaveReady(TLTR35 *hnd, DWORD tout);

/***************************************************************************//**
    @brief Ожидание запуска ввода-вывода в потоковом режиме

    Данная функция ожидает возвращения подтверждения от модуля об успешном
    запуске ввода-вывода после вызова LTR35_StreamStartRequest().

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

    Если же ответа дождаться не удалось, то функция вернет ошибку
    LTR_ERROR_OP_DONE_WAIT_TOUT. В этом случае данную функции можно вызывать повторно
    для продолжения ожидания, либо вызвать LTR35_Stop() для отмены запуска ввода-вывода.

    @param[in]  hnd         Описатель модуля.
    @param[in]  tout        Максимальное время ожидания подтверждения.
    @return                 [Код ошибки](@ref e_LTR35_ERROR_CODES).
 ******************************************************************************/
LTR35API_DllExport(INT) LTR35_StreamStartWaitDone(TLTR35 *hnd, DWORD tout);

/***************************************************************************//**
   @brief Останов выдачи данных

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

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

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

/***************************************************************************//**
   @brief Останов выдачи данных с заданным временем ожидания ответа

   Функция аналогична LTR35_Stop() за исключением того, что время ожидания
    ответа можно задать явно в мс. Служит для случая, если время ответа может
    быть существенно больше стандартного времени ответа на команду (например,
    в потоковом режиме, если буфер ltrd заполнен данными на передачу).

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




/***************************************************************************//**
   @brief Изменение частоты для арифметического генератора

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

    При этом частота задается также как и при настройке с помощью значения
    приращения фазы на каждый выводимый отсчет. При успешном выполнении функции
    соответствующим образом обновляется поле @fieldref{TLTR35_ARITH_SRC_CONFIG,Delta}
    настроек соответствующего арифметического генератора.

    @param[in]  hnd         Описатель модуля.
    @param[in]  gen_num     Номер арифметического генератора (от 0 до #LTR35_ARITH_SRC_CNT-1).
    @param[in]  delta       Новое значение приращения фазы на период вывода на ЦАП.
    @return                 [Код ошибки](@ref e_LTR35_ERROR_CODES).
 ******************************************************************************/
LTR35API_DllExport(INT) LTR35_SetArithSrcDelta(TLTR35 *hnd, BYTE gen_num, const TLTR35_ARITH_PHASE *delta);

/***************************************************************************//**
   @brief Изменение амплитуды и смещения арифметического сигнала.

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

    При успешном выполнении соответствующим образом обновляются поля
    @fieldref{TLTR35_CHANNEL_CONFIG,ArithAmp} и
    @fieldref{TLTR35_CHANNEL_CONFIG,ArithOffs} настроек соответствующего
    канала.

    @param[in]  hnd         Описатель модуля.
    @param[in]  ch_num      Номер канала ЦАП.
    @param[in]  amp         Новое значение амплитуды в Вольтах.
    @param[in]  offset      Новое значение смещения в Вольтах.
    @return                 [Код ошибки](@ref e_LTR35_ERROR_CODES).
 ******************************************************************************/
LTR35API_DllExport(INT) LTR35_SetArithAmp(TLTR35 *hnd, BYTE ch_num,
                                          double amp, double offset);



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

   Функция позволяет принять слова, передаваемые модулем, при разрешенном синхронном
   вводе. Формат принятых слов зависит от режима синхронного ввода и описан в разделе
   @ref sect_gen_stream_in_modes.

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


/** @} */

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

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

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

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

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

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

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

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

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

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

/***************************************************************************//**
   @brief Получение информации о состоянии модуля

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

   @param[in]  hnd      Описатель модуля.
   @param[out] status   Набор флагов из #e_LTR35_STATUS, объединенных по битовому "ИЛИ",
                        описывающих состояние модуля.
   @return              [Код ошибки](@ref e_LTR35_ERROR_CODES).
 ******************************************************************************/
LTR35API_DllExport(INT) LTR35_GetStatus(TLTR35 *hnd, DWORD *status);


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

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


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

/***************************************************************************//**
    @brief Сброс микросхемы ЦАП

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

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

/***************************************************************************//**
    @brief Асинхронное чтение состояния цифровых входов

    Функция выполняет чтения состояния входов DI1 и DI2. Синхронный ввод
    данных при этом не должен быть запущен.

    @param[in]  hnd       Описатель модуля.
    @param[out] di_state  При успешном выполнении в данной переменной возвращается
                          битовая маска состояний входов DI1 (младший бит) и
                          DI2 (второй бит).
    @return               [Код ошибки](@ref e_LTR35_ERROR_CODES).
 ******************************************************************************/
LTR35API_DllExport(INT) LTR35_DIAsyncIn(TLTR35 *hnd, BYTE *di_state);

/** @} */

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



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

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

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

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

   Функция записывает данные во flash-памяти модуля по заданному
   адресу. Запись может выполняться и в не стертые области.
   Однако в стертые заранее с помощью LTR35_FlashErase() области запись выполняется
   быстрее, если указан флаг #LTR35_FLASH_WRITE_ALREADY_ERASED.

   Пользователю выделяется область памяти с адреса
   #LTR35_FLASH_USERDATA_ADDR размером #LTR35_FLASH_USERDATA_SIZE байт.

   @param[in] hnd      Описатель модуля.
   @param[in] addr     Адрес памяти, начиная с которого необходимо выполнить запись
   @param[in] data     Массив из size байт с данными, которые будут записаны.
   @param[in] size     Количество данных в байтах, которое необходимо записать.
   @param[in] flags    Набор флагов из #e_LTR35_FLASH_WRITE_FLAGS, объединенных
                       по битовому "ИЛИ".
   @return             [Код ошибки](@ref e_LTR35_ERROR_CODES).
 ******************************************************************************/
LTR35API_DllExport(INT) LTR35_FlashWrite(TLTR35 *hnd, DWORD addr, const BYTE *data, DWORD size, DWORD flags);


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

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

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

/** @} */

#ifdef __cplusplus
}
#endif

#endif

