#ifndef X502API_H
#define X502API_H



#include "lcard_pstdint.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifdef _WIN32
    #ifndef WIN32_LEAN_AND_MEAN
        #define WIN32_LEAN_AND_MEAN
    #endif
    #include "Windows.h"

    #define X502_EXPORT(type) type APIENTRY
#else
    #ifndef APIENTRY
        #define APIENTRY
    #endif

    #if __GNUC__ >= 4
        #define X502_EXPORT(type) __attribute__ ((visibility("default"))) type
    #else
        #define X502_EXPORT(type) type
    #endif
#endif


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


/** Максимальное количество логических каналов в таблице*/
#define X502_LTABLE_MAX_CH_CNT      256
/** Количество диапазонов для измерения напряжений */
#define X502_ADC_RANGE_CNT            6

/** Количество каналов АЦП в режиме с общей землей */
#define X502_ADC_COMM_CH_CNT        32

/** Количество каналов АЦП в дифференциальном режиме */
#define X502_ADC_DIFF_CH_CNT        16


/** Максимальное значение для аппаратного усреднения по логическому каналу */
#define X502_LCH_AVG_SIZE_MAX       128
/** Максимальное значения делителя частоты АЦП */
#define X502_ADC_FREQ_DIV_MAX       (1024*1024)
/** Максимальное значение делителя частоты синхронного цифрового ввода */
#define X502_DIN_FREQ_DIV_MAX       (1024*1024)



/** Минимальное значение делителя частоты синхронного вывода */
#define X502_OUT_FREQ_DIV_MIN       2
/** Максимальное значение делителя частоты синхронного вывода */
#define X502_OUT_FREQ_DIV_MAX       1024
/** Значение делителя частоты вывода по умолчанию (которое также всегда
   используется в L-502 с версией прошивки ПЛИС ниже 0.5) */
#define X502_OUT_FREQ_DIV_DEFAULT   2

/** Минимальное значение делителя частоты синхронного вывода
    при внешней опорной частоте ниже #X502_OUT_FREQ_REF_LF_VAL */
#define X502_OUT_FREQ_DIV_MIN_REF_LF 1
/** Значение внешней опорной частоты, ниже которой разрешено устанавливать
    значение делителя частоты генерации до #X502_OUT_FREQ_DIV_MIN_REF_LF */
#define X502_OUT_FREQ_REF_LF_VAL     700000


/** Максимальное значение межкадровой задержки для АЦП */
#define X502_ADC_INTERFRAME_DELAY_MAX  (0x1FFFFF)

/** Таймаут по умолчанию для выполнения команды к BlackFin*/
#define X502_BF_CMD_DEFAULT_TOUT    500

/** Код АЦП, соответствующий максимальному значению шкалы */
#define X502_ADC_SCALE_CODE_MAX     6000000
/** Код ЦАП, соответствующий максимальному значению шкалы */
#define X502_DAC_SCALE_CODE_MAX     30000

/** Максимальное количество символов в строке с названием устройства */
#define X502_DEVNAME_SIZE      32
/** Максимальное количество символов в строке с серийным номером */
#define X502_SERIAL_SIZE       32
/** Максимальное количество символов в строке с описанием подключения */
#define X502_LOCATION_STR_SIZE 64
/** Размер MAC-адреса для Ethernet интерфейса */
#define X502_MAC_ADDR_SIZE     6
/** Размер строки с описанием экземпляра устройства */
#define X502_INSTANCE_NAME_SIZE   64
/** Максимальный размер строки с паролем на настройки */
#define X502_PASSWORD_SIZE        32

/** Максимально возможное значение внешней опорной частоты */
#define X502_EXT_REF_FREQ_MAX  1500000


/** Размер пользовательской области Flash-памяти */
#define X502_FLASH_USER_SIZE   0x100000

/** Стандартный таймаут на выполнение запроса к BlackFin в мс */
#define X502_BF_REQ_TOUT  500


/** Диапазон ЦАП в вольтах */
#define X502_DAC_RANGE  5.

/** Количество каналов ЦАП */
#define X502_DAC_CH_CNT  2

/** Количество цифровых выходов у модуля */
#define X502_DOUT_LINES_CNT  16


/** слово в потоке, означающее, что произошло переполнение */
#define X502_STREAM_IN_MSG_OVERFLOW  0x01010000


/** Значение поля сигнатуры в записи о устройстве #t_x502_devrec. Признак,
    что запись действительна (устанавливается функциями по получению записей
    о устройствах) */
#define X502_DEVREC_SIGN       0x4C524543


/** Коды ошибок библиотеки */
typedef enum {
    /** Функция выполнена без ошибок */
    X502_ERR_OK                           = 0,
    /** В функцию передан недействительный описатель модуля */
    X502_ERR_INVALID_HANDLE               = -1,
    /** Ошибка выделения памяти */
    X502_ERR_MEMORY_ALLOC                 = -2,
    /** Попытка открыть уже открытое устройство */
    X502_ERR_ALREADY_OPENED               = -3,
    /** Устройство с заданными параметрами не найдено в системе */
    X502_ERR_DEVICE_NOT_FOUND             = -4,
    /** Доступ к устройству запрещен (Как правило из-за того, что устройство
        уже открыто в другой программе) */
    X502_ERR_DEVICE_ACCESS_DENIED         = -5,
    /** Ошибка открытия устройства */
    X502_ERR_DEVICE_OPEN                  = -6,
    /** В функцию передан недействительный указатель */
    X502_ERR_INVALID_POINTER              = -7,
    /** Функция не может быть выполнена при запущенном потоке сбора данных */
    X502_ERR_STREAM_IS_RUNNING            = -8,
    /** Ошибка чтения данных синхронного ввода */
    X502_ERR_RECV                         = -9,
    /** Ошибка записи данных для синхронного вывода */
    X502_ERR_SEND                         = -10,
    /** Произошло переполнение внутреннего буфера для потока синхронного ввода */
    X502_ERR_STREAM_OVERFLOW              = -11,
    /** Неизвестное сообщение в потоке синхронного ввода */
    X502_ERR_UNSUP_STREAM_MSG             = -12,
    /** Ошибка создания системного мьютекса */
    X502_ERR_MUTEX_CREATE                 = -13,
    /** Неверный описатель мьютекса */
    X502_ERR_MUTEX_INVALID_HANDLE         = -14,
    /** Истекло время ожидания освобождения мьютекса */
    X502_ERR_MUTEX_LOCK_TOUT              = -15,
    /** Ошибка освобождения мьютекса */
    X502_ERR_MUTEX_RELEASE                = -16,
    /** Недостаточно системных ресурсов */
    X502_ERR_INSUFFICIENT_SYSTEM_RESOURCES= -17,
    /** Данная возможность еще не реализована */
    X502_ERR_NOT_IMPLEMENTED              = -18,
    /** Недостаточный размер массива */
    X502_ERR_INSUFFICIENT_ARRAY_SIZE      = -19,
    /** Ошибка чтения регистра FPGA */
    X502_ERR_FPGA_REG_READ                = -20,
    /** Ошибка записи регистра FPGA */
    X502_ERR_FPGA_REG_WRITE               = -21,
    /** Сбор данных уже остановлен */
    X502_ERR_STREAM_IS_NOT_RUNNING        = -22,
    /** Ошибка освобождения интерфейса */
    X502_ERR_INTERFACE_RELEASE            = -23,
    /** Ошибка запуска потока */
    X502_ERR_THREAD_START                 = -24,
    /** Ошибка останова потока */
    X502_ERR_THREAD_STOP                  = -25,
    /** Устройство было отключено */
    X502_ERR_DEVICE_DISCONNECTED          = -26,
    /** Неверный размер ответа на управляющий запрос */
    X502_ERR_IOCTL_INVALID_RESP_SIZE      = -27,
    /** Неверный тип устройства */
    X502_ERR_INVALID_DEVICE               = -28,
    /** Недействительная запись о устройстве */
    X502_ERR_INVALID_DEVICE_RECORD        = -29,
    /** Неверный описатель конфигурации модуля */
    X502_ERR_INVALID_CONFIG_HANDLE        = -30,
    /** Связь с устройством закрыта или не была установлена */
    X502_ERR_DEVICE_NOT_OPENED            = -31,
    /** Данная операция не доступна для текущего интерфейса связи с устройством */
    X502_ERR_INVALID_OP_FOR_IFACE         = -32,
    /** Не загружен ПЛИС модуля */
    X502_ERR_FPGA_NOT_LOADED              = -33,
    /** Неверная конфигурация USB-устройства */
    X502_ERR_INVALID_USB_CONFIGURATION    = -34,    
    /** Неверный описатель контекста поиска устройств в сети */
    X502_ERR_INVALID_SVC_BROWSE_HANDLE    = -35,
    /** Неверный описатель записи о сервисе */
    X502_ERR_INVALID_SVC_RECORD_HANDLE    = -36,
    /** Не запущена программа обнаружения устройств в локальной сети */
    X502_ERR_DNSSD_NOT_RUNNING            = -37,
    /** Ошибка при обращении к программе обнаружения устройств в локальной сети */
    X502_ERR_DNSSD_COMMUNICATION          = -38,
    /** Превышен таймаут запроса параметров автообнаруженного сетевого устройства */
    X502_ERR_SVC_RESOLVE_TIMEOUT          = -39,
    /** Ошибка в кодировке имени экземпляра устройства */
    X502_ERR_INSTANCE_NAME_ENCODING       = -40,
    /** Экземпляры модулей не совпадают */
    X502_ERR_INSTANCE_MISMATCH            = -41,
    /** Возможность не поддерживается текущей версией прошивки устройства */
    X502_ERR_NOT_SUP_BY_FIRMWARE          = -42,
    /** Возможность не поддерживается текущей версией драйвера устройства */
    X502_ERR_NOT_SUP_BY_DRIVER            = -43,
    /** Превышено время ожидания установления циклического сигнала на вывод */
    X502_ERR_OUT_CYCLE_SETUP_TOUT         = -44,
    /** Неизвестный код поддерживаемой возможности */
    X502_ERR_UNKNOWN_FEATURE_CODE         = -45,


    /** Задан неверный размер логической таблицы */
    X502_ERR_INVALID_LTABLE_SIZE          = -102,
    /** Задан неверный номер логического канала */
    X502_ERR_INVALID_LCH_NUMBER           = -103,
    /** Неверно задано значение диапазона АЦП */
    X502_ERR_INVALID_LCH_RANGE            = -104,
    /** Неверно задан режим измерения для логического канала */
    X502_ERR_INVALID_LCH_MODE             = -105,
    /** Неверно задан номер физического канала при настройке логического */
    X502_ERR_INVALID_LCH_PHY_NUMBER       = -106,
    /** Неверно задан размер усреднения для логического канала */
    X502_ERR_INVALID_LCH_AVG_SIZE         = -107,
    /** Неверно задан делитель частоты сбора данных АЦП */
    X502_ERR_INVALID_ADC_FREQ_DIV         = -108,
    /** Неверно задан делитель частоты синхронного ввода цифровых линий */
    X502_ERR_INVALID_DIN_FREQ_DIV         = -109,
    /** Неверно задан режим работы модуля */
    X502_ERR_INVALID_MODE                 = -110,
    /** Неверный номер канала ЦАП */
    X502_ERR_INVALID_DAC_CHANNEL          = -111,
    /** Неверный код выбора опорной частоты синхронизации */
    X502_ERR_INVALID_REF_FREQ             = -112,
    /** Неверно задано значение межкадровой задержки */
    X502_ERR_INVALID_INTERFRAME_DELAY     = -113,
    /** Неверно задан режим синхронизации */
    X502_ERR_INVALID_SYNC_MODE            = -114,
    /** Неверно задан номер потока данных */
    X502_ERR_INVALID_STREAM_CH            = -115,
    /** Неверно задан делитель частоты синхронного вывода */
    X502_ERR_INVALID_OUT_FREQ_DIV         = -116,

    /** Ошибка захвата опорной частоты синхронизации */
    X502_ERR_REF_FREQ_NOT_LOCKED          = -131,
    /** Управляющий запрос к драйверу завершен с ошибкой */
    X502_ERR_IOCTL_FAILD                  = -132,
    /** Истек таймаут ожидания завершения выполнения управляющего запроса к драйверу */
    X502_ERR_IOCTL_TIMEOUT                = -133,
    /** Ошибка получения информации о устройстве от драйвера */
    X502_ERR_GET_INFO                     = -134,
    /** За время ожидания не было считано новое слово с цифровых линий */
    X502_ERR_DIG_IN_NOT_RDY               = -135,
    /** Принято недостаточно слов от модуля */
    X502_ERR_RECV_INSUFFICIENT_WORDS      = -136,
    /** Попытка выполнить операцию, требующую наличие ЦАП, при его отсутствии */
    X502_ERR_DAC_NOT_PRESENT              = -137,
    /** Передано недостаточно слов в модуль */
    X502_ERR_SEND_INSUFFICIENT_WORDS      = -138,
    /** Не пришло ответа на переданную команду */
    X502_ERR_NO_CMD_RESPONSE              = -139,

    /** Неверный номер канала в обрабатываемом потоке синхронного ввода */
    X502_ERR_PROC_INVALID_CH_NUM          = -140,
    /** Неверный код диапазона в обрабатываемом потоке синхронного ввода */
    X502_ERR_PROC_INVALID_CH_RANGE        = -141,
    /** Задан неверный адрес во Flash-памяти */
    X502_ERR_FLASH_INVALID_ADDR           = -142,
    /** Задан неверный размер блока данных при работе с Flash-памятью */
    X502_ERR_FLASH_INVALID_SIZE           = -143,
    /** Истек таймаут ожидания завершения записи во Flash-память */
    X502_ERR_FLASH_WRITE_TOUT             = -144,
    /** Истек таймаут ожидания завершения стирания блока Flash-памяти */
    X502_ERR_FLASH_ERASE_TOUT             = -145,
    /** Заданная область для стирания Flash-памяти нарушает границу блока в 4 Кбайт */
    X502_ERR_FLASH_SECTOR_BOUNDARY        = -146,

    /** Не удалось открыть сокет для соединения */
    X502_ERR_SOCKET_OPEN                  = -147,
    /** Превышено время подключения */
    X502_ERR_CONNECTION_TOUT              = -148,
    /** Соединение закрыто другой устройством */
    X502_ERR_CONNECTION_CLOSED_BY_DEV     = -149,
    /** Не удалось установить заданный размер буфера сокета */
    X502_ERR_SOCKET_SET_BUF_SIZE          = -150,
    /** Соединение для передачи данных не установлено */
    X502_ERR_NO_DATA_CONNECTION           = -151,
    /** Не удалось дождаться сообщения о завершении потока */
    X502_ERR_NO_STREAM_END_MSG            = -152,
    /** Соединение было сброшено другой стороной */
    X502_ERR_CONNECTION_RESET             = -153,
    /** Не удалось найти хост с указанным адресом */
    X502_ERR_HOST_UNREACHABLE             = -154,
    /** Ошибка установления TCP-соединения */
    X502_ERR_TCP_CONNECTION_ERROR         = -155,




    /** Не удалось открыть файл прошивки BlackFin */
    X502_ERR_LDR_FILE_OPEN                = -180,
    /** Ошибка чтения из фала прошивки BlackFin */
    X502_ERR_LDR_FILE_READ                = -181,
    /** Неверный формат файла прошивки BlackFin */
    X502_ERR_LDR_FILE_FORMAT              = -182,
    /** Используются возможность LDR-файла, недоступные при записи прошивки
        BlackFin по HDMA */
    X502_ERR_LDR_FILE_UNSUP_FEATURE       = -183,
    /** Неверный стартовый адрес программы в прошивке BlackFin */
    X502_ERR_LDR_FILE_UNSUP_STARTUP_ADDR  = -184,
    /** Истек таймаут выполнения запроса на чтения/запись памяти BlackFin */
    X502_ERR_BF_REQ_TIMEOUT               = -185,
    /** Команда для BlackFin все еще находится в процессе обработки */
    X502_ERR_BF_CMD_IN_PROGRESS           = -186,
    /** Истекло время выполнения управляющей команды процессором BlackFin */
    X502_ERR_BF_CMD_TIMEOUT               = -187,
    /** Возвращено недостаточно данных в ответ на команду к BlackFin */
    X502_ERR_BF_CMD_RETURN_INSUF_DATA     = -188,
    /** Истек таймаут ожидания готовности процессора BlackFin к записи прошивки */
    X502_ERR_BF_LOAD_RDY_TOUT             = -189,
    /** Попытка выполнить операцию для которой нужен сигнальный процессор при
        отсутствии сигнального процессора в модуле */
    X502_ERR_BF_NOT_PRESENT               = -190,
    /** Неверный адрес памяти BlackFin при записи или чтении по HDMA */
    X502_ERR_BF_INVALID_ADDR              = -191,
    /** Неверный размер данных, передаваемых с управляющей командой в BlackFin */
    X502_ERR_BF_INVALID_CMD_DATA_SIZE     = -192
} t_x502_errs;


/** Интерфейс соединения с модулем */
typedef enum {
    X502_IFACE_UNKNOWN = 0, /**< Неизвестный интерфейс */    
    X502_IFACE_USB     = 1, /**< Устройство подключено по USB */
    X502_IFACE_ETH     = 2, /**< Устройство подключено по Ethernet через TCP/IP */
    X502_IFACE_PCI     = 3  /**< Устройство подключено по PCI/PCIe */
} t_x502_iface;

/** Флаги, управляющие поиском присутствующих модулей */
typedef enum {
    /** Признак, что нужно вернуть серийные номера только тех устройств,
        которые еще не открыты */
    X502_GETDEVS_FLAGS_ONLY_NOT_OPENED = 1
} t_x502_getdevs_flags;



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

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


/** Константы для выбора опорной частоты */
typedef enum {
    X502_REF_FREQ_2000KHZ  = 2000000, /**< Частота 2МГц */
    X502_REF_FREQ_1500KHZ  = 1500000 /**< Частота 1.5МГц */
} t_x502_ref_freq;


/** Диапазоны измерения для канала АЦП */
typedef enum {
    X502_ADC_RANGE_10 = 0, /**< Диапазон +/-10V */
    X502_ADC_RANGE_5  = 1, /**< Диапазон +/-5V */
    X502_ADC_RANGE_2  = 2, /**< Диапазон +/-2V */
    X502_ADC_RANGE_1  = 3, /**< Диапазон +/-1V */
    X502_ADC_RANGE_05 = 4, /**< Диапазон +/-0.5V */
    X502_ADC_RANGE_02 = 5  /**< Диапазон +/-0.2V */
} t_x502_adc_range;

/** Режим измерения для логического канала */
typedef enum {
    X502_LCH_MODE_COMM = 0, /**< Измерение напряжения относительно общей земли */
    X502_LCH_MODE_DIFF = 1, /**< Дифференциальное измерение напряжения */
    X502_LCH_MODE_ZERO = 2  /**< Измерение собственного нуля */
} t_x502_lch_mode;

/** @brief Режимы синхронизации

    Режимы задания источника частоты синхронизации и признака начала
    синхронного ввода-вывода */
typedef enum {
    X502_SYNC_INTERNAL        = 0, /**< Внутренний сигнал */
    X502_SYNC_EXTERNAL_MASTER = 1, /**< От внешнего мастера по разъему межмодульной синхронизации */
    X502_SYNC_DI_SYN1_RISE    = 2, /**< По фронту сигнала DI_SYN1 */
    X502_SYNC_DI_SYN1_FALL    = 3, /**< По спаду сигнала DI_SYN1 */
    X502_SYNC_DI_SYN2_RISE    = 6, /**< По фронту сигнала DI_SYN2 */
    X502_SYNC_DI_SYN2_FALL    = 7  /**< По спаду сигнала DI_SYN2 */
} t_x502_sync_mode;

/** Флаги, управляющие обработкой принятых данных */
typedef enum {
    /** Признак, что нужно преобразовать значения АЦП в вольты */
    X502_PROC_FLAGS_VOLT            = 0x00000001,
    /** Признак, что не нужно проверять совпадение номеров каналов
        в принятых данных с каналами из логической таблицы.
        Может использоваться при нестандартной прошивке BlackFin
        при передаче в ПК не всех данных. */
    X502_PROC_FLAGS_DONT_CHECK_CH   = 0x00010000
} t_x502_proc_flags;


/** Флаги для обозначения синхронных потоков данных */
typedef enum {
    X502_STREAM_ADC  = 0x01, /**< Поток данных от АЦП */
    X502_STREAM_DIN  = 0x02, /**< Поток данных с цифровых входов */
    X502_STREAM_DAC1 = 0x10, /**< Поток данных первого канала ЦАП */
    X502_STREAM_DAC2 = 0x20, /**< Поток данных второго канала ЦАП */
    X502_STREAM_DOUT = 0x40, /**< Поток данных на цифровые выводы */
    /** Объединение всех флагов, обозначающих потоки данных на ввод */
    X502_STREAM_ALL_IN = X502_STREAM_ADC | X502_STREAM_DIN,
    /** Объединение всех флагов, обозначающих потоки данных на вывод */
    X502_STREAM_ALL_OUT = X502_STREAM_DAC1 | X502_STREAM_DAC2 | X502_STREAM_DOUT
} t_x502_streams;

/** Константы, определяющие тип передаваемого отсчета из ПК в модуль */
typedef enum {
    X502_STREAM_OUT_WORD_TYPE_DOUT   = 0x0, /**< Цифровой вывод */
    X502_STREAM_OUT_WORD_TYPE_DAC1   = 0x40000000, /**< Код для 1-го канала ЦАП */
    X502_STREAM_OUT_WORD_TYPE_DAC2   = 0x80000000  /**< Код для 2-го канала ЦАП */
} t_x502_stream_out_wrd_type;

/** Режим работы модуля */
typedef enum {
    X502_MODE_FPGA  = 0, /**< Все потоки данных передаются через ПЛИС минуя
                              сигнальный процессор BlackFin */
    X502_MODE_DSP   = 1, /**< Все потоки данных передаются через сигнальный
                              процессор, который должен быть загружен
                              прошивкой для обработки этих потоков */
    X502_MODE_DEBUG = 2  /**< Отладочный режим */
} t_x502_mode;

/** @brief Номера каналов ЦАП

    Номер каналов ЦАП для указания в X502_AsyncOutDac() */
typedef enum {
    X502_DAC_CH1 = 0, /**< Первый канал ЦАП */
    X502_DAC_CH2 = 1  /**< Второй канал ЦАП */
} t_x502_dac_ch;

/** @brief Флаги, используемые при выводе данных на ЦАП

    Флаги, комбинацию которых можно передать в X502_AsyncOutDac() или
    X502_PrepareData(), чтобы определить действия, которые должны выполнить
    эти функции с переданным значением перед выводом их на ЦАП */
typedef enum {
    /** Указывает, что значение задано в Вольтах и при выводе его нужно
        перевести его в коды ЦАП. Если флаг не указан, то считается, что значение
        изначально в кодах */
    X502_DAC_FLAGS_VOLT    = 0x0001,
    /** Указывает, что нужно применить калибровочные коэффициенты перед
        выводом значения на ЦАП. */
    X502_DAC_FLAGS_CALIBR  = 0x0002
} t_x502_dacout_flags;



/** Номера каналов для передачи потоков данных */
typedef enum {
    X502_STREAM_CH_IN  = 0, /**< Общий канал на ввод */
    X502_STREAM_CH_OUT = 1  /**< Общий канал на вывод */
} t_x502_stream_ch;


/** @brief Цифровые линии, на которых можно включить подтягивающие резисторы

    Флаги, определяющие на каких цифровых входах должны быть включены
    подтягивающие резисторы. Для разных модулей доступны разные наборы флагов. */
typedef enum {
    X502_PULLUPS_DI_H      = 0x01, /**< Старшая половина цифровых входов (только для L502) */
    X502_PULLUPS_DI_L      = 0x02, /**< Младшая половина цифровых входов (только для L502) */
    X502_PULLUPS_DI_SYN1   = 0x04, /**< Линия SYN1 */
    X502_PULLUPS_DI_SYN2   = 0x08, /**< Линия SYN2 */
    X502_PULLDOWN_CONV_IN  = 0x10, /**< Подтяжка к 0 линии межмодульной
                                        синхронизации CONV_IN (только для E502) */
    X502_PULLDOWN_START_IN = 0x20, /**< Подтяжка к 0 линии межмодульной
                                        синхронизации START_IN (только для E502) */
} t_x502_pullups;


/** Флаги, определяющие наличие опций в модуле и наличие необходимых параметров */
typedef enum {
    /** Признак наличия двухканального канального ЦАП */
    X502_DEVFLAGS_DAC_PRESENT           = 0x00000001,
    /** Признак наличия гальваноразвязки */
    X502_DEVFLAGS_GAL_PRESENT           = 0x00000002,
    /** Признак наличия сигнального процессора BlackFin */
    X502_DEVFLAGS_BF_PRESENT            = 0x00000004,
    /** 3 бита, отвечающие за тип использумого процессора/контроллера (0 --- ADSP-BF523) */
    X502_DEVFLAGS_PROC_TYPE             = 0x00000038,
    /** 2 бита, отвечающие за тип используемого ЦАП (0 --- AD5542AARUZ, 1 --- DAC8581IPW) */
    X502_DEVFLAGS_DAC_TYPE              = 0x000000C0,

    /** Признак, что устройство поддерживает интерфейс USB */
    X502_DEVFLAGS_IFACE_SUPPORT_USB     = 0x00000100,
    /** Признак, что устройство поддерживает Ethernet */
    X502_DEVFLAGS_IFACE_SUPPORT_ETH     = 0x00000200,
    /** Признак, что устройство поддерживает интерфейс PCI/PCI-Express */
    X502_DEVFLAGS_IFACE_SUPPORT_PCI     = 0x00000400,

    /** Признак, что устройство выполнено в индустриалном исполнении */
    X502_DEVFLAGS_INDUSTRIAL            = 0x00008000,

    /** Признак, что во Flash-памяти присутствует информация о модуле */
    X502_DEVFLAGS_FLASH_DATA_VALID      = 0x00010000,
    /** Признак, что во Flash-памяти присутствуют действительные калибровочные
        коэффициенты АЦП */
    X502_DEVFLAGS_FLASH_ADC_CALIBR_VALID = 0x00020000,
    /** Признак, что во Flash-памяти присутствуют действительные калибровочные
        коэффициенты ЦАП */
    X502_DEVFLAGS_FLASH_DAC_CALIBR_VALID = 0x00040000,

    /** Признак, что присутствует прошивка ПЛИС и она успешно была загружена */
    X502_DEVFLAGS_FPGA_LOADED            = 0x00800000,
    /** Признак, что устройство уже открыто (действителен только внутри t_x502_devrec) */
    X502_DEVFLAGS_DEVREC_OPENED          = 0x01000000
} t_x502_dev_flags;

/** @brief Тип содержимого строки с расположением устройства

    Данное поле определяет содержимое поля location в структуре #t_x502_devrec */
typedef enum {
    /** В поле расположения устройства не содержится информации */
    X502_LOCATION_TYPE_NONE             = 0,
    /** В поле расположения устройства содержится строка с адресом устройства */
    X502_LOCATION_TYPE_ADDR             = 1,
    /** В поле расположения устройства содержится строка с именем экземпляра */
    X502_LOCATION_TYPE_INSTANCE_NAME    = 2
} t_x502_location_type;


/** @brief Флаги для режима циклического вывода

    Данные флаги могут быть переданы в X502_OutCycleSetup() и X502_OutCycleStop() */
typedef enum {
    /** Флаг указывает, что останов или смена сигнала могут произойти без ожидания
        конца цикла предыдущего сигнала. Это позволяет выполнить переключение
        быстрее (однако все равно может быть поставлено на передачу до 256 КСемплов,
        которые должны будут быть переданы), но точка смены или останова
        может быть в любом месте периода */
    X502_OUT_CYCLE_FLAGS_FORCE         = 0x01,
    /** Флаг указывает, что функция должна дождаться полной загрузки сигнала
        и установки сигнала на вывод (для X502_OutCycleSetup()) или завершения
        генерации циклического сигнала (для X502_OutCycleStop()). Без него
        функции только посылают команду модулю, возвращая сразу управление.
        
        Данное ожидание может занимать значительное время в зависимости от размера сигнала 
        (а также размера предыдущего сигнала в случае смены или останова генерации без
        #X502_OUT_CYCLE_FLAGS_FORCE).  Данную проверку можно сделать и
        отдельной функций X502_OutCycleCheckSetupDone().
        Данный флаг имеет значения только в тех случаях, когда поддерживается
        функция X502_OutCycleCheckSetupDone(), в противном случае он игнорируется. */
    X502_OUT_CYCLE_FLAGS_WAIT_DONE = 0x02
} t_x502_out_cycle_flags;



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

   Коды возможностей модуля, которые могут поддерживаться или нет в зависимости
   от типа модуля, версий прошивок и т.п. */
typedef enum {
    /** Поддержка установки делителя частоты вывода, отличного от #X502_OUT_FREQ_DIV_DEFAULT */
    X502_FEATURE_OUT_FREQ_DIV       = 1,
    /** Возможность чтения флагов состояния вывода с помощью X502_OutGetStatusFlags() */
    X502_FEATURE_OUT_STATUS_FLAGS   = 2
} t_x502_features;

/** Флаги состояния для синхронного вывода */
typedef enum {
     /** Флаг указывает, что в настоящее время буфер в модуле на передачу пуст */
    X502_OUT_STATUS_FLAG_BUF_IS_EMPTY = 0x01,
    /** Флаг указывает, что было опустошение буфера на вывод с начала старта синхронного
        ввода-вывода или с момента последнего чтения статуса с помощью
        X502_OutGetStatusFlags() (в зависимости от того, что было последним) */
    X502_OUT_STATUS_FLAG_BUF_WAS_EMPTY = 0x02
} t_x502_out_status_flags;


/** @} */


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

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

    Непрозрачная структура с информацией, достаточной для установления
    с ним связи. Зависит от типа устройства, интерфейса подключения и не
    доступна пользователю напрямую, а используется библиотекой в
    X502_OpenByDevRecord() */
typedef struct st_x502_devrec_inptr t_x502_devrec_inptr;

/** @brief Запись о устройстве

   Структура, описывающая устройство, по которой с ним можно установить соединение */
typedef struct {
    uint32_t sign;  /**< Признак действительной структуры.
                         Если запись действительна (соответствует какому-либо устройству),
                         то должен быть равен #X502_DEVREC_SIGN) */
    char devname[X502_DEVNAME_SIZE]; /**< Название устройства */
    char serial[X502_SERIAL_SIZE]; /**< Серийный номер */
    char location[X502_LOCATION_STR_SIZE]; /**< Описание подключения (если есть) */
    uint32_t flags; /**< Флаги из #t_x502_dev_flags, описывающие устройство */
    uint8_t  iface; /**< Интерфейс, по которому подключено устройство */
    uint8_t  location_type; /**< Определяет, что именно сохранено в поле location
                                 (одно значение из #t_x502_location_type) */
    char res[122];  /**< Резерв */
    t_x502_devrec_inptr* internal; /**< Непрозрачный указатель на структуру с
                                        дополнительной информацией, необходимой
                                        для открытия устройства */
} t_x502_devrec;


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

    Непрозрачный указатель на структуру,
    содержащую информацию о настройках модуля и текущем соединении с ним.
    Пользовательской программе не доступны поля структуры напрямую, а только
    через функции библиотеки.
    Функции управления модулем принимают описатель модуля своим первым параметром.
    Описатель модуля создается с помощью X502_Create() и в конце работы
    освобождается с помощью X502_Free(). */
typedef struct st_x502* t_x502_hnd;

/** @brief Список серийный номеров

    Тип определяет массив серийных номеров для количества модулей, определяемого
    на этапе работы программы. */
typedef char (*t_x502_serial_list)[X502_SERIAL_SIZE];

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

    Структура содержит калибровочные значения смещения нуля и коэффициента
    шкалы для одного диапазона АЦП или ЦАП.Результирующее значение АЦП
    вычисляется как (val - offs) * k, где val - неоткалиброванное значение */
typedef struct {
    double offs; /**< смещение нуля */
    double k; /**< коэффициент шкалы */
} t_x502_cbr_coef;


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

    Структура, содержащая все калибровочные коэффициенты, которые
    используются модулем L-502/E-502 */
typedef struct {
    /** Калибровочные коэффициенты АЦП */
    t_x502_cbr_coef adc[X502_ADC_RANGE_CNT];
    uint32_t res1[64]; /**< Резерв */
    /** Калибровочные коэффициенты ЦАП */
    t_x502_cbr_coef dac[X502_DAC_CH_CNT];
    uint32_t res2[20]; /**< Резерв */
} t_x502_cbr;

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

    Структура, содержащая постоянную информация о модуле L-502/E-502, которая как правило
    не изменяется после открытия */
typedef struct {
    char name[X502_DEVNAME_SIZE]; /**< Название устройства ("L502" или "E502") */
    char serial[X502_SERIAL_SIZE]; /**< Серийный номер */
    uint32_t devflags; /**< Флаги из #t_x502_dev_flags, описывающие наличие
                            в модуле определенных опций */
    uint16_t fpga_ver; /**< Версия ПЛИС (старший байт - мажорная, младший - минорная) */
    uint8_t  plda_ver; /**< Версия ПЛИС, управляющего аналоговой частью */
    uint8_t  board_rev; /**< Ревизия платы */
    uint32_t mcu_firmware_ver; /**< Версия прошивки контроллера Cortex-M4. Действительна только для модуля E-502 */
    uint8_t  factory_mac[X502_MAC_ADDR_SIZE]; /**< Заводской MAC-адрес --- действителен только для
                                                    устройств с Ethernet-интерфейсом */
    uint8_t res[110]; /**< Резерв */
    t_x502_cbr cbr; /**< Заводские калибровочные коэффициенты (из Flash-памяти) */
} t_x502_info;

/** @} */


/** @addtogroup func_list Функции
    @{  **/

/***************************************************************************//**
    @addtogroup func_hnd Функции для создания и освобождения описателя модуля
    @{
*******************************************************************************/

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

    Создание описателя модуля, для последующей работы с модулем E-502 или L-502.
    В случае успешного выделения памяти инициализирует поля описателя
    значениями по умолчанию.
    @return NULL в случае ошибки, иначе - описатель модуля
*******************************************************************************/
X502_EXPORT(t_x502_hnd) X502_Create(void);

/***************************************************************************//**
    @brief Освобождение описателя модуля

    Освобождение памяти, выделенной под описатель модуля с помощью X502_Create().
    После этого описатель уже использовать нельзя, независимо от возвращенного
    значения!
    @param[in] hnd     Описатель устройства
    @return            Код ошибки
*******************************************************************************/
X502_EXPORT(int32_t) X502_Free(t_x502_hnd hnd);
/** @} */







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

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

    Функция устанавливает соединение с модулем E-502 или L-502 по записи об этом устройстве.
    Необходимые действия зависят от того, на какое устройство подключенное по
    какому интерфейсу ссылается запись. Сами записи создаются специальными
    функциями (свои для каждого типа модуля и интерфейса подключения) и не
    должны изменяться пользователем вручную.

    @param[in] hnd     Описатель модуля.
    @param[in] devrec  Запись о устройстве, содержащая необходимую информацию
                       для установления с ним связи
    @return            Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_OpenByDevRecord(t_x502_hnd hnd, const t_x502_devrec *devrec);

/***************************************************************************//**
    @brief Освобождение записей об устройствах

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

    @param[in] list    Массив записей о устройстве или указатель на единственную
                        запись, ресурсы которой (которых) нужно освободить.
    @param[in] size    Количество записей в массиве
    @return            Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_FreeDevRecordList(t_x502_devrec *list, uint32_t size);

/** @} */


/***************************************************************************//**
    @addtogroup func_open Функции для открытия и получения информации о модуле
    @{
*******************************************************************************/

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

    Функция разрывает соединение с модулем E-502/L-502, если оно было ранее установлено
    (в противном случае ничего не делает).
    Описатель модуля не освобождается.
    Память под описатель модуля должна быть освобождена вызовом X502_Free().
    @param[in] hnd     Описатель модуля.
    @return            Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_Close(t_x502_hnd hnd);


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

    Функция проверяет, открыто ли в данный момент соединение с модулем. Если
    соединение открыто, то функция возвращает #X502_ERR_OK. Если же закрыто, то
    функция возвращает ошибку #X502_ERR_DEVICE_NOT_OPENED.

    @param[in] hnd     Описатель модуля.
    @return            Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_IsOpened(t_x502_hnd hnd);



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

    Получение информации о модуле L-502/E-502, с которым установлена связь.
    @param[in]  hnd     Описатель модуля.
    @param[out] info    Информация о модуле (смотри описание типа #t_x502_info).
    @return             Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_GetDevInfo(t_x502_hnd hnd, t_x502_info* info);


/** @} */

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

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

    Функция выполняет запись текущих настроек (которые были установлены
    с помощью функций X502_SetXXX) в модуль.
    Должна вызываться перед запуском потока данных.
    @param[in] hnd     Описатель модуля.
    @param[in] flags   Флаги (резерв - должно быть равно 0).
    @return            Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_Configure(t_x502_hnd hnd, uint32_t flags);


/***************************************************************************//**
    @brief Установка параметров логического канала

    Функция устанавливает параметры заданного логического канала в логической
    таблице АЦП.
    @param[in] hnd        Описатель модуля.
    @param[in] lch        Номер логического канала.
                          (от 0 до #X502_LTABLE_MAX_CH_CNT-1)
    @param[in] phy_ch     Номер физического канала АЦП, начиная с 0
                          (0-15 для дифференциального режима,
                          0-31 для режима с общей землей)
    @param[in] mode       Режим измерения канал АЦП (значение типа #t_x502_lch_mode)
    @param[in] range      Диапазон измерения канала (значение типа #t_x502_adc_range)
    @param[in] avg        Коэффициент усреднения по каналу. Нулевое значение
                          соответствует значению коэффициента, определенного
                          библиотекой. Для явного задания коэффициента усреднения
                          нужно перед значение от 1 (отсутствие усреднения) до
                          #X502_LCH_AVG_SIZE_MAX.
                          В случае если значение усреднения превышает делитель
                          частоты, то это значение будет скорректировано
    @return               Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_SetLChannel(t_x502_hnd hnd, uint32_t lch, uint32_t phy_ch,
                                       uint32_t mode, uint32_t range, uint32_t avg);


/***************************************************************************//**
    @brief Установка количества логических каналов

    Функция устанавливает количество логических каналов в логической таблице АЦП.
    @param[in] hnd      Описатель модуля
    @param[in] lch_cnt  Количество логических каналов
                        (от 1 до #X502_LTABLE_MAX_CH_CNT)
    @return             Код ошибки
*******************************************************************************/
X502_EXPORT(int32_t) X502_SetLChannelCount(t_x502_hnd hnd, uint32_t lch_cnt);


/***************************************************************************//**
    @brief Получение количества логических каналов

    Функция возвращает установленное ранее с помощью X502_SetLChannelCount()
    количество логических каналов в управляющей таблице АЦП.
    @param[in] hnd       Описатель модуля
    @param[out] lch_cnt  Количество логических каналов
    @return              Код ошибки
*******************************************************************************/
X502_EXPORT(int32_t) X502_GetLChannelCount(t_x502_hnd hnd, uint32_t* lch_cnt);

/***************************************************************************//**
    @brief Установка делителя частоты сбора для АЦП

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

    Альтернативой этой функции служит X502_SetAdcFreq(), которая рассчитывает
    этот делитель на основании переданной требуемой частоты сбора АЦП.

    @param[in] hnd           Описатель модуля.
    @param[in] adc_freq_div  Делитель частоты АЦП (от 1 до #X502_ADC_FREQ_DIV_MAX).
    @return                  Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_SetAdcFreqDivider(t_x502_hnd hnd, uint32_t adc_freq_div);

/***************************************************************************//**
    @brief Установка значения межкадровой задержки для АЦП

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

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

    @param[in] hnd      Описатель модуля.
    @param[in] delay    Значение межкадровой задержки (от 0 до
                        #X502_ADC_INTERFRAME_DELAY_MAX)
    @return             Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_SetAdcInterframeDelay(t_x502_hnd hnd, uint32_t delay);

/***************************************************************************//**
    @brief Установка делителя частоты синхронного ввода с цифровых линий.

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

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

    @param[in] hnd           Описатель модуля.
    @param[in] din_freq_div  Делитель частоты синхронного ввода с цифровых линий
                             (от 1 до #X502_DIN_FREQ_DIV_MAX).
    @return                  Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_SetDinFreqDivider(t_x502_hnd hnd, uint32_t din_freq_div);



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

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

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

    @note Для модуля L-502, чтобы была возможность установить делитель, отличный от
    #X502_OUT_FREQ_DIV_DEFAULT, необходимо обновить прошивку ПЛИС до версии 0.5 или выше.
    Для модуля E-502 возможность всегда поддерживается. Проверить программно наличие
    данной возможности можно с помощью функции X502_CheckFeature().

    @param[in] hnd           Описатель модуля.
    @param[in] out_freq_div  Делитель частоты синхронного вывода
                             (от #X502_OUT_FREQ_DIV_MIN до #X502_OUT_FREQ_DIV_MAX).
    @return                  Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_SetOutFreqDivider(t_x502_hnd hnd, uint32_t out_freq_div);



/***************************************************************************//**
    @brief Установка частоты сбора АЦП

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

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

    Если необходимо изменить значение опорной частоты, то данная функция должна
    быть вызвана после X502_SetSyncMode() и X502_SetRefFreq() / X502_SetExtRefFreqValue(),
    в противном случае полученные делители будут давать неверное значение частоты.

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

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


    @param[in]     hnd      Описатель модуля.
    @param[in,out] f_acq    На входе принимает требуемое значения частоты сбора
                              АЦП в Герцах. На выходе возвращает реально
                              установленное значение частоты.
    @param[in,out] f_frame  На входе принимает требуемое значение частоты сбора
                              кадров (частоты сбора на логический канал) АЦП
                              в Герцах. На выходе возвращает реально
                              установленное значение. Если передан нулевой
                              указатель, то устанавливает максимальную частоту
                              сбора кадров (нулевую межкадровую задержку).
    @return                Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_SetAdcFreq(t_x502_hnd hnd, double *f_acq, double *f_frame);


/***************************************************************************//**
    @brief Установка частоты синхронного ввода с цифровых входов

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

    Если необходимо изменить значение опорной частоты синхронизации, то данная
    функция должна  быть вызвана после X502_SetSyncMode() и
    X502_SetRefFreq()/ X502_SetExtRefFreqValue(), в противном случае полученный
    делитель будет давать неверное значение частоты.

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

    @param[in]     hnd     Описатель модуля.
    @param[in,out] f_din   На входе принимает требуемое значения частоты ввода
                           с цифровых входов в Герцах. На выходе возвращает
                           реально установленное значение частоты.
    @return                Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_SetDinFreq(t_x502_hnd hnd, double *f_din);



/***************************************************************************//**
    @brief Установка частоты синхронного вывода

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

    Если необходимо изменить значение опорной частоты синхронизации, то данная
    функция должна быть вызвана после X502_SetSyncMode() и
    X502_SetRefFreq() / X502_SetExtRefFreqValue(), в противном случае
    полученный делитель будет давать неверное значение частоты.

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

    @note Для модуля L-502, чтобы была возможность установить частоту, отличную от
    опорной частоты, деленной на #X502_OUT_FREQ_DIV_DEFAULT, необходимо обновить
    прошивку ПЛИС до версии 0.5 или выше.
    Для модуля E-502 возможность всегда поддерживается.
    Проверить программно наличие данной возможности можно с помощью
    функции X502_CheckFeature().


    @param[in]     hnd     Описатель модуля.
    @param[in,out] f_dout  На входе принимает требуемое значения частоты
                           синхронного вывода в Герцах. На выходе возвращает
                           реально установленное значение частоты.
    @return                Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_SetOutFreq(t_x502_hnd hnd, double *f_dout);



/***************************************************************************//**
    @brief Получить текущие значения частот сбора АЦП

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

    @param[in]  hnd      Описатель модуля.
    @param[out] f_acq    Если не NULL, то на выходе возвращается текущее
                         значение частоты сбора АЦП.
    @param[out] f_frame  Если не NULL, то на выходе возвращается текущее
                         значение частоты кадров АЦП.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_GetAdcFreq(t_x502_hnd hnd, double *f_acq, double *f_frame);


/***************************************************************************//**
    @brief Установка значения внутренней опорной частоты синхронизации

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

    Данная функция при внутренней опорной частете выбирает одну из двух доступных
    частот в 2МГц или 1.5 МГц(2МГц является значением по умолчанию), для задания
    которых можно введены константы из #t_x502_ref_freq.

    При использовании внешней опорной частоты следует использовать
    X502_SetExtRefFreqValue().

    Для модуля E-502 вывод на ЦАП при опорной частоте 1.5 МГц работает только
    для версии прошивки PLDA 1 или выше.

    @param[in] hnd          Описатель модуля.
    @param[in] freq         Значение из #t_x502_ref_freq, которое задает
                            выбранную опорную частоту.
    @return                 Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_SetRefFreq(t_x502_hnd hnd, uint32_t freq);

/***************************************************************************//**
    @brief Установка значения внешней опорной частоты синхронизации

    При установке внешней опорной частоты (вызов X502_SetSyncMode() со занчением,
    отличным от #X502_SYNC_INTERNAL) данная функция позволяет задать
    частоту внешней опорной частоты, котороя может быть любая, но не превышать
    1.5 МГц.

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

    Данная функция доступна в библиотеке версии 1.1.4 или выше.

    @param[in] hnd          Описатель модуля.
    @param[in] freq         Значение внешней опорной частоты в Гц.
    @return                 Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_SetExtRefFreqValue(t_x502_hnd hnd, double freq);


/***************************************************************************//**
    @brief Получение значения опорной частоты синхронизации

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

    При внутренней опорной частоте используется значение, установленное
    X502_SetRefFreq() (1.5 или 2 Мгц), при внешней --- частота, установленная
    с помощью функции X502_SetExtRefFreqValue().

    Данная функция доступна в библиотеке версии 1.1.4 или выше.

    @param[in] hnd          Описатель модуля.
    @param[in] freq         Значение внешней опорной частоты в Гц.
    @return                 Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_GetRefFreqValue(t_x502_hnd hnd, double *freq);




/***************************************************************************//**
    @brief Установка режима генерации частоты синхронизации

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

    В режиме #X502_SYNC_INTERNAL модуль сам будет генерировать для себя
    частоту синхронизации с частотой, заданной X502_SetRefFreq().
    При этом запуск генерации будет осуществлен по вызову X502_StreamsStart()
    или по условию, заданому в X502_SetSyncStartMode(), а останов
    по X502_StreamsStop().

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

    @param[in] hnd          Описатель модуля.
    @param[in] sync_mode    Значение из #t_x502_sync_mode, определяющее кто
                            будет источником частоты синхронизации.
    @return                 Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_SetSyncMode(t_x502_hnd hnd, uint32_t sync_mode);

/***************************************************************************//**
    @brief Установка режима запуска частоты синхронизации

    Функция устанавливает условие запуска синхронного ввода/вывода данных.

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

    Режимы задания условия запуска синхронизации имеют те же значения,
    что и режимы задания самой частоты (см. тип #t_x502_sync_mode).
    В случае #X502_SYNC_INTERNAL запуск осуществляется при выполнении функции
    X502_StreamsStart(), в противном случае - после выполнения
    X502_StreamsStart() модуль начинает ожидать заданного данной функцией условия.
    Т.е. даже при задании внешних источников синхронизации, все равно необходимо
    вызывать X502_StreamsStart().

    @param[in] hnd              Описатель модуля.
    @param[in] sync_start_mode  Значение из #t_x502_sync_mode, определяющее
                                условие запуска частоты синхронизации.
    @return                     Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_SetSyncStartMode(t_x502_hnd hnd, uint32_t sync_start_mode);


/***************************************************************************//**
    @brief Установить режим работы модуля

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

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

    @param[in] hnd          Описатель модуля.
    @param[in] mode         Режим работы модуля из #t_x502_mode.
    @return                 Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_SetMode(t_x502_hnd hnd, uint32_t mode);
/***************************************************************************//**
    @brief Получение текущего режима работы модуля

    Функция возвращает текущий режим работы модуля.
    @param[in] hnd          Описатель модуля.
    @param[out] mode        В данном параметре возвращается текущий режим
                            работы модуля (из #t_x502_mode).
    @return                 Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_GetMode(t_x502_hnd hnd, uint32_t* mode);
/***************************************************************************//**
    @brief Установить коэффициенты для калибровки значений АЦП

    Функция записывает в ПЛИС коэффициенты для калибровки значений АЦП.
    При открытии модуля, библиотека считывает калибровочные коэффициенты из
    защищенной области Flash-памяти модуля и записывает их в ПЛИС для
    выполнения калибровки на лету.

    Результирующее значение АЦП вычисляется по формуле (val - offs) * k, где val ---
    некалиброванное значение.

    Данная функция позволяет изменить используемые коэффициенты в то время, пока
    не запущен синхронный сбор данных. При этом изменяются только текущие
    коэффициенты, а заводские калибровочные коэффициенты из Flash-памяти
    сохраняют свое значение и при следующем открытии будут восстановлены.

    @param[in] hnd          Описатель модуля.
    @param[in] range        Диапазон АЦП (из #t_x502_adc_range).
    @param[in] k            Устанавливаемое значение коэффициента шкалы.
    @param[in] offs         Устанавливаемое значение смещения нуля.
    @return                 Код ошибки.
    ***************************************************************************/
X502_EXPORT(int32_t) X502_SetAdcCoef(t_x502_hnd hnd, uint32_t range, double k, double offs);

/***************************************************************************//**
    @brief Получение текущих калибровочных коэффициентов АЦП

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

    @param[in] hnd          Описатель модуля.
    @param[in] range        Диапазон АЦП (из #t_x502_adc_range).
    @param[in] k            В данной переменной возвращается текущий коэффициент
                            шкалы.
    @param[in] offs         В данной переменной возвращается текущее смещение нуля.
    @return                 Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_GetAdcCoef(t_x502_hnd hnd, uint32_t range, double* k, double* offs);



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

    Функция устанавливает калибровочные коэффициенты для заданного канала АЦП,
    которые будут использоваться функциями x502api для калибровки выводимых
    значений ЦАП, если указан фалаг #X502_DAC_FLAGS_CALIBR.

    Откалиброванное значение ЦАП в кодах получается как
    (val + offs) * k, где val --- некалиброванное значение (в кодах).

    При открытии модуля, библиотека считывает калибровочные коэффициенты из
    защищенной области Flash-памяти модуля и использует их.

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

    @param[in] hnd          Описатель модуля.
    @param[in] ch           Канал ЦАП (из #t_x502_dac_ch).
    @param[in] k            Устанавливаемое значение коэффициента шкалы.
    @param[in] offs         Устанавливаемое значение смещения нуля.
    @return                 Код ошибки.
    ***************************************************************************/
X502_EXPORT(int32_t) X502_SetDacCoef(t_x502_hnd hnd, uint32_t ch, double k, double offs);


/***************************************************************************//**
    @brief Получение текущих калибровочных коэффициентов ЦАП

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

    @param[in] hnd          Описатель модуля.
    @param[in] ch           Канал ЦАП (из #t_x502_dac_ch).
    @param[in] k            В данной переменной возвращается текущий коэффициент
                            шкалы.
    @param[in] offs         В данной переменной возвращается текущее смещение нуля.
    @return                 Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_GetDacCoef(t_x502_hnd hnd, uint32_t ch, double* k, double* offs);



/***************************************************************************//**
    @brief Рассчет частоты сбора АЦП

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

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


    @param[in]     ref_freq Значение опорной частоты в Гц (внешней или внутренней)
    @param[in]     lch_cnt  Количество логических каналов, которое будет использовано.
                            Необходимо для расчета межкадровой задержки. Если
                            в качестве f_frame передан нулевой указатель, то
                            может быть равно 0.
    @param[in,out] f_acq    На входе принимает требуемое значения частоты сбора
                            АЦП в Герцах. На выходе возвращает рассчитанное
                            значение частоты, которая может быть установлена.
    @param[in,out] f_frame  На входе принимает требуемое значение частоты сбора
                            кадров (частоты сбора на логический канал) АЦП
                            в Герцах. На выходе возвращает рассчитанное значение.
                            Если передан нулевой указатель, то задержка
                            рассчитана не будет.
                            Если передано значение меньше или равное нуля, то
                            будет рассчитана максимальная частота кадров
                            (с нулевой межкадровой задержкой).
    @param[out]    result_freq_div В данном параметре возвращается рассчитанное
                            значения делителя частоты АЦП. Может быть передан
                            нулевой указатель, если это значение явно знать
                            не требуется.
    @param[out]    result_frame_delay В данном параметре возвращается рассчитанное
                            значение межкадровой задержки. Может быть передан
                            нулевой указатель, если это значение явно знать
                            не требуется.
    @return                 Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_CalcAdcFreq(double ref_freq, uint32_t lch_cnt, double *f_acq,
                                      double *f_frame, uint32_t *result_freq_div, uint32_t *result_frame_delay);

/***************************************************************************//**
    @brief Рассчет частоты синхронного ввода с цифровых входов

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

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


    @param[in]     ref_freq Значение опорной частоты в Гц (внешней или внутренней)
    @param[in,out] f_din   На входе принимает требуемое значения частоты ввода
                           с цифровых входов в Герцах. На выходе возвращает
                           рассчитанное значение частоты, которое может быть
                           установлено.
    @param[out]    result_freq_div В данном параметре возвращается рассчитанное
                              значения делителя частоты синхронного ввода цифровых
                              линий.
                              Может быть передан нулевой указатель,
                              если это значение явно знать не требуется.
    @return                Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_CalcDinFreq(double ref_freq, double *f_din, uint32_t *result_freq_div);


/***************************************************************************//**
    @brief Рассчет частоты синхронного вывода

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

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

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


    @param[in]     ref_freq Значение опорной частоты в Гц (внешней или внутренней)
    @param[in,out] f_dout  На входе принимает требуемое значения частоты
                           синхронного вывода в Герцах. На выходе возвращает
                           рассчитанное значение частоты, которое может быть
                           установлено.
    @param[out]    result_freq_div В данном параметре возвращается рассчитанное
                              значения делителя частоты синхронного вывода.
                              Может быть передан нулевой указатель,
                              если это значение явно знать не требуется.
    @return                Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_CalcOutFreq(double ref_freq, double *f_dout, uint32_t *result_freq_div);

/** @} */


/***************************************************************************//**
    @addtogroup func_async Функции асинхронного ввода-вывода
    @{
*******************************************************************************/

/***************************************************************************//**
    @brief Асинхронный вывод данных на канал ЦАП

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

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

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

    @param[in] hnd          Описатель модуля.
    @param[in] ch           Номер канала ЦАП (из #t_x502_dac_ch).
    @param[in] data         Выводимое значение на ЦАП (в кодах или вольтах)
    @param[in] flags        Флаги из #t_x502_dacout_flags.
    @return                 Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_AsyncOutDac(t_x502_hnd hnd, uint32_t ch, double data, uint32_t flags);

/***************************************************************************//**
    @brief Асинхронный вывод данных на цифровые выходы

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

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

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

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

    @param[in] hnd          Описатель модуля.
    @param[in] val          Младшая половина - выводимое значение, старшая -
                            флаги из #t_x502_digout_word_flags.
    @param[in] msk          Маска - указанные в маске биты не будут изменяться
                            с предыдущего выведенного состояния (распространяется
                            и на старшую половину val).
    @return                 Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_AsyncOutDig(t_x502_hnd hnd, uint32_t val, uint32_t msk);


/***************************************************************************//**
    @brief Асинхронный ввод значений с цифровых входов

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

    Так как модули E-502/L-502 не поддерживают аппаратно асинхронный ввод, то если на
    момент вызова этой функции не запущен синхронный ввод/вывод с помощью
    X502_StreamsStart(), то данная функция на время выполнения запускает
    синхронный сбор и останавливает его как только будет получено одно новое
    значение цифровых входов.

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

    @param[in]  hnd         Описатель модуля.
    @param[out] din         При успешном выполнении в этой переменной
                            возвращается текущее состояние цифровых входов.
                            Действительны младшие 18 бит, старшие 14 - резерв.
                            Часть битов при этом объединены с линиями синхронизации,
                            при этом это объединение зависит от типа модуля.
                            Подробнее описано в разделе с различиями модулей
                            E-502 и L-502.
                            Резервные биты могут быть использованы в последующих
                            версиях, не следует считать, что они всегда будут
                            равны нулю!
    @return                 Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_AsyncInDig(t_x502_hnd hnd, uint32_t* din);


/***************************************************************************//**
    @brief Асинхронный ввод одного кадра АЦП

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

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

    Для работы этой функции не должен быть разрешен синхронный ввод АЦП
    и цифровых линий.

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

    @param[in]  hnd         Описатель модуля.
    @param[in]  flags       Флаги из t_x502_proc_flags
    @param[in]  tout        Таймаут на выполнение функции в мс
    @param[out] data        Массив, в котором в случае успеха будут возвращены
                            отсчеты кадра АЦП. Должен быть размером, достаточным
                            для хранения отсчетов типа double в количестве,
                            равном количеству установленных логических каналов
                            в управляющей таблице АЦП.
    @return                 Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_AsyncGetAdcFrame(t_x502_hnd hnd, uint32_t flags,
                                       uint32_t tout, double* data);

/** @} */





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

/***************************************************************************//**
    @brief Разрешение синхронных потоков на ввод/вывод

    Функция разрешает прием/передачу для указанных потоков
    Не указанные потоки сохраняют свое разрешенное или запрещенное состояние.
    Может вызываться как до X502_Configure(), так и после.
    Разрешенные потоки устанавливаются как правило до вызова X502_StreamsStart().

    При желании в некоторых ситуациях можно изменять состав разрешенных потоков
    во время запущенного сбора данных, однако если эти потоки сильно различаются
    в частоте, то рассчитанные библиотекой значения буфера и шага прерывания
    могут не подходить для изменившихся значений (см. @ref sect_sync_mode_buf)
    @param[in] hnd     Описатель модуля.
    @param[in] streams Набор флагов #t_x502_streams, указывающих, какие потоки
                       должны быть разрешены.
    @return            Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_StreamsEnable(t_x502_hnd hnd, uint32_t streams);
/****************************************************************************//**
    @brief Запрещение синхронных потоков на ввод/вывод

    Функция запрещает передачу синхронных данных для указанных потоков.
    Не указанные потоки сохраняют свое разрешенное или запрещенное состояние.
    Функция, противоположная по смыслу X502_StreamsEnable().
    @param[in] hnd     Описатель модуля.
    @param[in] streams Набор флагов #t_x502_streams, указывающих, какие потоки
                       должны быть запрещены.
    @return            Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_StreamsDisable(t_x502_hnd hnd, uint32_t streams);

/****************************************************************************//**
    @brief Получить значение, какие синхронные потоки разрешены

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

    @param[in] hnd      Описатель модуля.
    @param[out] streams Набор флагов #t_x502_streams, указывающих, какие потоки
                        сейчас разрешены.
    @return             Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_GetEnabledStreams(t_x502_hnd hnd, uint32_t* streams);

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

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

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

    @param[in] hnd     Описатель модуля.
    @return            Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_StreamsStart(t_x502_hnd hnd);

/***************************************************************************//**
    @brief Останов синхронных потоков ввода/вывода

    Функция останова синхронных потоков ввода/вывода данных. После выполнению
    этой функции модуль завершает генерацию опорной частоты синхронизации (или
    использовать внешнюю частоту синхронизации) и останавливает синхронную
    передачу данных.
    @param[in] hnd     Описатель модуля.
    @return            Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_StreamsStop(t_x502_hnd hnd);


/***************************************************************************//**
    @brief Проверка, запущен ли синхронный ввод/вывод

    Функция проверяет запущен ли синхронный ввод вывод с помощью X502_StreamsStart()
    или какой-либо внутренней логикой в прошивки BlackFin.
    Если сбор данных не запущен, то функция возвращает ошибку
    #X502_ERR_STREAM_IS_NOT_RUNNING, если запущен, то нулевой код ошибки

    @param[in] hnd     Описатель модуля.
    @return            Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_IsRunning(t_x502_hnd hnd);



/***************************************************************************//**
    @brief Чтение данных АЦП и цифровых входов из модуля

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

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

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

    До вызовов X502_Recv() синхронный поток сбора данных должен быть уже запущен
    с помощью X502_StreamsStart().

    @param[in]  hnd     Описатель модуля.
    @param[out] buf     Буфер, в которые будут сохранены отсчеты.
    @param[in]  size    Количество считываемых отсчетов (32-битных слов).
    @param[in]  tout    Таймаут на прием данных в мс.
    @return             Если < 0 - код ошибки.
                        Если >= 0 - количество считанных слов.
*******************************************************************************/
X502_EXPORT(int32_t) X502_Recv(t_x502_hnd hnd, uint32_t* buf, uint32_t size, uint32_t tout);


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

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

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

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

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

    @param[in]  hnd     Описатель модуля.
    @param[in]  buf     Буфер со словами, которые необходимо передать модулю
    @param[in]  size    Количество передаваемых отсчетов (32-битных слов).
    @param[in]  tout    Таймаут на передачу (в буфер драйвера) данных в мс.
    @return             Если < 0 - код ошибки.
                        Если >= 0 - количество записанных слов.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_Send(t_x502_hnd hnd, const uint32_t* buf, uint32_t size, uint32_t tout);



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

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

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

    Если запущен синхронный ввод с цифровых линий, то следует использовать
    X502_ProcessData(), которая выделяет данные с цифровых линий в отдельный
    массив.

    @param[in]  hnd      Описатель модуля.
    @param[in]  src      Входной массив отсчетов, принятых с помощью X502_Recv().
    @param[out] dest     Массив, в который будут сохранены преобразованные данные
                         от АЦП.
    @param[in,out] size  На входе - количество слов в массиве src, на выходе -
                         количество сохраненных преобразованных значений в
                         массиве dest
    @param[in]  flags    Набор флагов из #t_x502_proc_flags
    @return               Код ошибки.
   ****************************************************************************/
X502_EXPORT(int32_t) X502_ProcessAdcData(t_x502_hnd hnd, const uint32_t* src,
                                          double *dest, uint32_t *size, uint32_t flags);

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

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

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

    Кроме того, функция разбирает сообщения, передаваемые в потоке данных
    (например, сообщение о переполнении буфера).
    @param[in]  hnd      Описатель модуля.
    @param[in]  src      Входной массив отсчетов, принятый с помощью X502_Recv().
    @param[in]  size     Количество отсчетов (32-битных слов) в массиве src.
    @param[in]  flags    Набор флагов из #t_x502_proc_flags, управляющих
                         поведением функции. Может быть указано несколько флагов
                         через логическое "ИЛИ".
    @param[out] adc_data Массив, в который будут сохранены данные от АЦП,
                         преобразованные в соответствии с указанными флагами.
                         Может быть NULL, если не нужно сохранять данные от АЦП
                         (тогда adc_data_size должен быть тоже NULL, или в
                         переменной передан размер 0).
    @param[in,out] adc_data_size На входе в данном параметре передается резмер
                          буфера adc_data. Если данных от АЦП во входном массиве
                          будет больше adc_data_size, то в adc_data  будет
                          сохранено только первые adc_data_size отсчетов.
                          На выходе при успешном завершении функции в данную
                          переменную записывается количество сохранных отсчетов
                          АЦП.
                          Указатель может быть равен NULL, если adc_data = NULL
    @param[out] din_data  Массив, в который будут сохранены отчеты с синхронного
                          цифрового ввода. Каждое слово соответствуют состоянию
                          всех цифровых входов в формате, описанном в функции
                          X502_AsyncInDig().
    @param[in,out] din_data_size Аналогично параметру adc_data_size в этом
                          параметре передается размер буфера din_data в отсчетах,
                          а на выходе сохраняется количество реально сохраненных
                          отсчетов цифрового ввода. Может быть NULL, если
                          din_data = NULL.
    @return               Код ошибки.
   ****************************************************************************/
X502_EXPORT(int32_t) X502_ProcessData(t_x502_hnd hnd, const uint32_t* src, uint32_t size,
                     uint32_t flags, double *adc_data, uint32_t *adc_data_size,
                     uint32_t *din_data, uint32_t *din_data_size);

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

    Функция аналогична X502_ProcessData(), но позволяет также выделить
    пользовательские данные из потока. Пользовательскими данными считаются все
    отсчеты, которые не являются данными АЦП, данными цифрового ввода
    или сообщениями.
    Пользовательские данные складываются без изменений в массив usr_data
    (если он не равен нулю).
    Данная функция предназначена в первую очередь для программистов, которые
    будут использовать модифицированную прошивку сигнального процессора BlackFin.
    @param[in]  hnd              Описатель модуля.
    @param[in]  src              Входной массив отсчетов, принятый с помощью
                                 X502_Recv().
    @param[in]  size             Количество отсчетов (32-битных слов) в массиве src.
    @param[in]  flags            Набор флагов из #t_x502_proc_flags.
    @param[out] adc_data         Массив, в который будут сохранены данные от АЦП
                                 (см. X502_ProcessData()).
    @param[in,out] adc_data_size  см. X502_ProcessData()
    @param[out] din_data         Массив, в который будут сохранены отчеты с
                                 синхронного цифрового ввода. См. X502_ProcessData().
    @param[in,out] din_data_size  см. X502_ProcessData().
    @param[out] usr_data         Массив, в который будут сохранены пользовательские
                                данные без изменения их формата.
    @param[in,out] usr_data_size  В этом параметре передается размер буфера usr_data
                                а на выходе сохраняется количество реально сохраненных
                                отсчетов пользовательских данных.
                                Может быть NULL только если usr_data = NULL.
    @return                     Код ошибки.
   ****************************************************************************/
X502_EXPORT(int32_t) X502_ProcessDataWithUserExt(t_x502_hnd hnd, const uint32_t* src, uint32_t size,
                                   uint32_t flags, double *adc_data,
                                   uint32_t *adc_data_size, uint32_t *din_data,
                                   uint32_t *din_data_size,
                                   uint32_t *usr_data, uint32_t *usr_data_size);



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

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

    Выходной массив должен будет содержать n*size отсчетов, где n - количество
    используемых входных массивов (от 1 до 3).

    Значения цифровых выходов представляют собой 32-битные слова, младшие 16-бит
    которых определяют значения выводов, а старшие - флаги из
    #t_x502_digout_word_flags, которые могут использоваться в частности для
    перевода одной (или обеих) из половин выводов в третье состояние.

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

    @param[in]  hnd             Описатель модуля.
    @param[in]  dac1            Входной массив отсчетов первого канала ЦАП или
                                NULL, если не используется.
    @param[in]  dac2            Входной массив отсчетов второго канала ЦАП или
                                NULL, если не используется.
    @param[in]  digout          Входной массив со значениями цифровых выводов
                                или NULL, если не используется.
    @param[in]  size            Размер каждого из используемых входных массивов.
    @param[in]  flags           Флаги, управляющие работой функции, из
                                #t_x502_dacout_flags.
    @param[out] out_buf         Выходной массив, в который будут сохранены
                                сформированные отсчеты. Должен быть размера
                                n*size (n - количество используемых входных
                                массивов)
    @return                     Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_PrepareData(t_x502_hnd hnd, const double* dac1, const double* dac2,
                            const uint32_t* digout, uint32_t size, int32_t flags,
                            uint32_t* out_buf);

/***************************************************************************//**
    @brief Получить количество отсчетов в буфере потока на ввод

    Функция возвращает количество отсчетов, которые были приняты из модуля
    во внутренний буфер и готовы для считывания с помощью X502_Recv().
    То есть если в X502_Recv() передать значение, которое вернула данная функция,
    то X502_Recv() вернет это количество данных без ожидания (так как они уже
    в буфере).
    При работе по Ethernet данная функция возвращает корректное значение только
    для ОС Windows.
    @param[in]  hnd              Описатель модуля.
    @param[out] rdy_cnt          Количество готовых к приему отсчетов.
    @return                      Код ошибки.
    ***************************************************************************/
X502_EXPORT(int32_t) X502_GetRecvReadyCount(t_x502_hnd hnd, uint32_t *rdy_cnt);


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

    Функция возвращает количество отсчетов, соответствующее свободному месту
    в буфере на передачу в модуль.
    Это количество отсчетов гарантированно может быть передано с помощью
    X502_Send() без  ожидания.
    Данная функция не реализована при работе по интерфейсу Ethernet (TCP).
    @param[in]  hnd              Описатель модуля.
    @param[out] rdy_cnt          Количество слов, которому соответствует
                                 свободное место в буфере на передачу.
    @return                      Код ошибки.
    ***************************************************************************/
X502_EXPORT(int32_t) X502_GetSendReadyCount(t_x502_hnd hnd, uint32_t *rdy_cnt);

/***************************************************************************//**
    @brief Получить номер следующего ожидаемого логического канала АЦП для
           обработки

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

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

    Например, если установлено 7 логических каналов, а в X502_ProcessData()
    передано для обработки кратное 7 количество отсчетов, то последующий вызов
    X502_GetNextExpectedLchNum() вернет номер канала равный 0 (так как обработано
    целое число кадров и ожидается снова начало кадра).
    Если в X502_ProcessData() передан массив с 7*n + 5 отсчетами АЦП, то следующим
    ожидаемым каналом будет логический канал с номером 5 (обработаны каналы
    0,1,2,3,4 из неполного кадра).

    @param[in]  hnd              Описатель модуля.
    @param[out] lch              Номер логического канала (начиная с нуля).
    @return                      Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_GetNextExpectedLchNum(t_x502_hnd hnd, uint32_t *lch);



/***************************************************************************//**
    @brief Начало подготовки вывода синхронных данных

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

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

    @param[in] hnd        Описатель модуля.
    @return               Код ошибки.
    ***************************************************************************/
X502_EXPORT(int32_t) X502_PreloadStart(t_x502_hnd hnd);



/***************************************************************************//**
    @brief Начало загрузки циклического сигнала на вывод

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

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

    Для L-502 размер максимальный размер буфера определяется только размером,
    который позволяет выделить система на уровне драйвера.
    Для E-502 размер ограничен памятью встроенного контроллера.
    Подробнее смотри в описании различий E-502 и L-502.

    @param[in] hnd        Описатель модуля.
    @param[in] size       Количество отсчетов в выводимом циклическом сигнале
                          суммарно для всех используемых каналов вывода.
    @return               Код ошибки.
    ***************************************************************************/
X502_EXPORT(int32_t) X502_OutCycleLoadStart(t_x502_hnd hnd, uint32_t size);

/***************************************************************************//**
    @brief Установка ранее загруженного циклического сигнала на вывод

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

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

    Данная функция должна быть вызвана только после вызова X502_OutCycleLoadStart()
    и загрузки указанного в ней количества отсчетов в буфер!

    @param[in] hnd        Описатель модуля.
    @param[in] flags      Флаги из #t_x502_out_cycle_flags.
    @return               Код ошибки.
    ***************************************************************************/
X502_EXPORT(int32_t) X502_OutCycleSetup(t_x502_hnd hnd, uint32_t flags);


/***************************************************************************//**
    @brief Останов вывода циклического сигнала

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

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

    @param[in] hnd        Описатель модуля.
    @param[in] flags      Флаги из #t_x502_out_cycle_flags.
    @return               Код ошибки.
    ***************************************************************************/
X502_EXPORT(int32_t) X502_OutCycleStop(t_x502_hnd hnd, uint32_t flags);


/***************************************************************************//**
    @brief Проверка, завершена ли установка или останов циклического сигнала

    Функция проверяет, завершена ли установка циклического сигнала после вызова
    X502_OutCycleSetup() или завершена ли остановка генерации циклического
    сигнала после вызова X502_OutCycleStop(). По своему назначению аналогична флагу
    #X502_OUT_CYCLE_FLAGS_WAIT_DONE в описанных выше функциях, но позволяет
    выполнить ожидание вручную (с проверкой других условий).
   
    Функция доступна в библиотеки, начиная с версии 1.1.2, при этом для работы
    функции необходима версия прошивки ARM не ниже 1.0.2 для модуля E-502 или
    версия драйвера не ниже 1.0.9 для L-502. В отличие от флага, если данные условия
    не выполняются, то функция явно вернет ошибку #X502_ERR_NOT_SUP_BY_FIRMWARE
    или #X502_ERR_NOT_SUP_BY_DRIVER.

    Ожидание завершения может быть необходимо при вызове X502_OutCycleSetup()
    при загрузке первого сигнала до вызова X502_StreamsStart(), если требуется,
    чтобы выдача первых отсчетов на ЦАП совпала по времени с моментом запуска ввода,
    т.к. иначе загрузка сигнала в модуль может  не завершиться к моменту запуска
    и выдача сигнала начнется с задержкой (актуально для E502).

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

    При вызове X502_OutCycleStop() ожидание завершения может использоваться
    перед вызовом X502_StreamsStop(), чтобы убедится (если это необходимо), что
    генерация была завершена именно на последней точке загруженного циклического
    сигнала.
  
    @param[in]  hnd       Описатель модуля.
    @param[out] done      0, если есть незавершенный запрос на установку или останов
                          циклического сигнала, 1 --- в противном случае (включая
                          случай, когда выдача циклического сигнала вообще не ведется)
    @return               Код ошибки.
    ****************************************************************************/
X502_EXPORT(int32_t) X502_OutCycleCheckSetupDone(t_x502_hnd hnd, uint32_t *done);



/***************************************************************************//**
    @brief Чтение флагов статуса вывода

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

    @param[in]  hnd        Описатель модуля.
    @param[out] status     Флаги статуса --- набор битов из #t_x502_out_status_flags,
                           объединенных через логическое “ИЛИ”.
    @return                Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_OutGetStatusFlags(t_x502_hnd hnd, uint32_t *status);


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

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

    @param[in] hnd        Описатель модуля.
    @param[in] ch         Определяет, устанавливается размер буфера на ввод
                          или на вывод (значение из #t_x502_stream_ch).
    @param[in] size       Размер буфера в 32-битных отсчетах
    @return               Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_SetStreamBufSize(t_x502_hnd hnd, uint32_t ch, uint32_t size);

/***************************************************************************//**
    @brief Установка шага при передаче потока на ввод или вывод

    Функция устанавливает шаг передачи данных (шаг генерации прерываний
    для PCI-Express или размер запроса для USB) при передаче синхронного
    потока данных на ввод или на вывод.
    Данная функция предназначена для пользователей, которых не устроит
    автоматически рассчитываемое библиотекой значение.

    @param[in] hnd        Описатель модуля.
    @param[in] dma_ch     Определяет, шаг передачи устанавливается на ввод
                          или на вывод (значение из #t_x502_stream_ch).
    @param[in] step       Шаг прерывания в 32-битных отсчетах
    @return               Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_SetStreamStep(t_x502_hnd hnd, uint32_t dma_ch, uint32_t step);

/** @} */



/***************************************************************************//**
    @addtogroup func_dsp Функции для работы с сигнальным процессором
    @{
*******************************************************************************/
/***************************************************************************//**
    @brief Загрузка прошивки сигнального процессора BlackFin

    Функция загружает прошивку сигнального процессора из указанного файла в
    процессор и запускает ее, проверяет правильность загрузки путем получения
    версии прошивки (через специальную команду).
    Прошивка должна быть в бинарном формате LDR.
    @param[in] hnd           Описатель модуля.
    @param[in] filename      Имя файла с загружаемой прошивкой.
    @return                  Код ошибки.
  *****************************************************************************/
X502_EXPORT(int32_t) X502_BfLoadFirmware(t_x502_hnd hnd, const char* filename);



/***************************************************************************//**
    @brief Проверка, загружена ли прошивка BlackFin

    Функция передает команды процессору BlackFin для получения версии прошивки и
    ее состояния. Успешное выполнение команд свидетельствует о том, что в
    BlackFin загружена действительная прошивка.
    Кроме того прошивке передается информация о модуле (наличие опций, версия
    ПЛИС и т.д.) для внутреннего использования.
    В случае успеха модуль переводится в режим DSP.

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

    @param[in]  hnd          Описатель модуля.
    @param[out] version      Если указатель не нулевой, то в данной переменной
                             возвращается версия прошивки BlackFin в случае
                             успешной проверки.
    @return                  Код ошибки.
  *****************************************************************************/
X502_EXPORT(int32_t) X502_BfCheckFirmwareIsLoaded(t_x502_hnd hnd, uint32_t *version);

/***************************************************************************//**
    @brief Чтение блока данных из памяти сигнального процессора

    Функция считывает блок данных напрямую из памяти процессора. Может быть
    прочитаны данные, как из внутренней памяти (L1), так и из внешней SDRAM.
    Для выполнения этой функции в BlackFin должна быть загружена его прошивка.

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

    @param[in] hnd           Описатель модуля.
    @param[in] addr          Адрес памяти, начиная с которого будет считан блок
                             данных.
    @param[out] regs         Массив, в который будут сохранено прочитанное
                             содержимое памяти.
    @param[in] size          Количество считываемых 32-битных слов.
    @return                  Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_BfMemRead(t_x502_hnd hnd, uint32_t addr, uint32_t* regs,
                                      uint32_t size);

/***************************************************************************//**
    @brief Запись блока данных в память сигнального процессора

    Функция записывает блок данных напрямую в памяти процессора BlackFin. Блок
    данных должен быть всегда кратен 8 32-битным словам (32 байтам).
    Запись может осуществляться как во внутреннюю память (L1), так и во внешнюю SDRAM.
    Для выполнения этой функции в BlackFin должна быть загружена его прошивка.

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

    @note Следует быть осторожным, т.к. запись в область данных, используемую
    программой может привести к ее неработоспособности.

    @param[in] hnd           Описатель модуля.
    @param[in] addr          Адрес памяти, начиная с которого будет записан блок
                             данных.
    @param[out] regs         Массив с данными для записи в сигнальный процессор.
    @param[in] size          Количество записываемых данных в 32-битных словах
                             (должно быть кратно 8).
    @return                  Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) X502_BfMemWrite(t_x502_hnd hnd, uint32_t addr,
                                      const uint32_t* regs, uint32_t size);


/***************************************************************************//**
    @brief Передача управляющей команды сигнальному процессору

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

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

    Команды деляться на стандартные, которые используются библиотекой x502api и
    реализованы в штатной прошивке сигнального процессора и пользовательские,
    которые пользователь может определять по своему усмотрению.
    Пользовательские команды начинаются с кода X502_BF_CMD_CODE_USER (0x8000).

    @param[in] hnd           Описатель модуля.
    @param[in] cmd_code      Код команды - определяет, что за команда выполняется.
    @param[in] par           Параметр, передаваемый с командой (значение зависит
                             от кода команды).
    @param[in] snd_data      Опциональные данные, передаваемые вместе с командой.
                             Если данные не передаются, то должен передаваться
                             нулевой указатель и snd_size = 0.
    @param[in] snd_size      Количество 32-битных слов, передаваемых в snd_data
    @param[out] rcv_data     Массив, в который будут переданы данные, возвращенные
                             процессором по завершению команды. Если данные не
                             должны возвращаться, то должен передаваться нулевой
                             указатель, а rcv_size = 0.
    @param[in] rcv_size      Количество 32-битных слов, которое ожидается, что
                             вернет процессор по выполнению команды. Массив
                             rcv_data должен быть рассчитан на данное количество
                             слов.
    @param[in] tout          Таймаут в течении которого будет ожидаться, когда
                             процессор завершит выполнение команды. Функция
                             возвратит управление либо по завершению команды,
                             либо по таймауту.
    @param[out] recvd_size   Если не является нулевым указателем, то в эту
                             переменную будет сохранено количество 32-битных слов,
                             которое реально вернул процессор после выполнения
                             команды (процессор имеет право вернуть меньше данных,
                             чем запрашивалось в rcv_size).
    @return                  Код ошибки. Если процессор выполнил команду с ненулевым
                             кодом завершения, то этот код и будет возвращен
                             функцией.
*******************************************************************************/
X502_EXPORT(int32_t) X502_BfExecCmd(t_x502_hnd hnd, uint16_t cmd_code, uint32_t par,
                                    const uint32_t* snd_data, uint32_t snd_size,
                                    uint32_t* rcv_data, uint32_t rcv_size,
                                    uint32_t tout, uint32_t* recvd_size);
/** @} */






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

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

    Функция считывает массив данных из Flash-памяти модуля в массив, переданный
    пользователем. Для считывания не нужно специальное разрешение - оно доступно
    всегда.
    @param[in]  hnd     Описатель модуля.
    @param[in]  addr    Адрес начала блока.
    @param[out] data    Массив, куда будут сохранены считанные данные
                          (должен быть не меньше size байт).
    @param[in]  size    Количество байт для чтения.
    @return             Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_FlashRead(t_x502_hnd hnd, uint32_t addr, uint8_t* data,
                                    uint32_t size);
/***************************************************************************//**
    @brief Запись блока данных во Flash-память модуля

    Функция записывает переданный массив данных во Flash-память модуля.
    Эта область должна быть предварительно стерта с помощью X502_FlashErase() и
    до начала изменения должна быть вызвана функция X502_FlashWriteEnable(),
    чтобы разрешить любое изменение содержимого Flash-памяти.
    Пользователю для записи доступны только первые #X502_FLASH_USER_SIZE байт
    Flash-памяти.
    @param[in]  hnd     Описатель модуля.
    @param[in]  addr    Адрес начала блока.
    @param[in]  data    Массив с записываемыми данными (должен быть не меньше
                        size байт).
    @param[in]  size    Количество байт для записи.
    @return             Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_FlashWrite(t_x502_hnd hnd, uint32_t addr,
                                     const uint8_t* data, uint32_t size);
/***************************************************************************//**
    @brief Стирание блока во Flash-памяти

    Функция стирает блок во Flash-памяти модуля (все ячейки будут читаться как
    0xFF). Адрес и размер должны быть кратны 4096 байт!
    Перед вызовом этой функции должна быть разрешена запись
    в пользовательскую область с помощью X502_FlashWriteEnable().
    @param[in]  hnd     Описатель модуля.
    @param[in]  addr    Адрес начала блока (должен быть кратен 4K).
    @param[in]  size    Количество байт для стирания (кратно 4K).
    @return             Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_FlashErase(t_x502_hnd hnd, uint32_t addr, uint32_t size);
/***************************************************************************//**
    @brief Разрешение записи в пользовательскую область Flash-памяти

    Функция разрешает запись в пользовательскую область Flash-памяти (первые
    #X502_FLASH_USER_SIZE байт). Должна быть вызвана до того, как
    можно будет использовать X502_FlashErase() и X502_FlashWrite() для изменения
    содержимого пользовательской области памяти. После завершения изменений
    следует вызвать X502_FlashWriteDisable().
    @param[in]  hnd     Описатель модуля.
    @return             Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_FlashWriteEnable(t_x502_hnd hnd);
/***************************************************************************//**
    @brief Запрет записи в пользовательскую область Flash-памяти

    Функция запрещает запись в пользовательскую область Flash-памяти модуля
    (первые #X502_FLASH_USER_SIZE байт). Должна быть вызвана после того, как
    нужные данные в пользовательской области были изменены с помощью
    X502_FlashErase() и X502_FlashWrite(), чтобы защитить пользовательскую
    область от случайной изменения в дальнейшем.
    @param[in]  hnd     Описатель модуля.
    @return             Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_FlashWriteDisable(t_x502_hnd hnd);

/** @} */





/***************************************************************************//**
    @addtogroup func_misc Дополнительные вспомогательные функции
    @{
*******************************************************************************/
/**************************************************************************//**
  @brief Получить версию библиотеки

  Функция возвращает версию библиотеки x502api.
  Версия возвращается в виде 32-битного числа.
  Строковое представление возвращенной версии --- четыре числа,
  старшее соответствует старшему байту, младшее --- младшему.

  Старший байт --- мажорная версия, второй по старшинству байт --- минорная,
  третий --- ревизия, четвертый --- номер сборки (не используется --- всегда 0)

  @return 32-битное число, представляющее собой версию библиотеки
  *****************************************************************************/
X502_EXPORT(uint32_t) X502_GetLibraryVersion(void);

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

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

    @note Следует учесть, что в ОС Windows строка возвращается в
    стандартной для Windows кодировке CP1251, в то время как в Linux
    используется кодировка UTF-8.
    @param[in] err   Код ошибки, для которого нужно вернуть строку.
    @return          Указатель на строку, соответствующую коду ошибки
 ******************************************************************************/
X502_EXPORT(const char*) X502_GetErrorString(int32_t err);

/***************************************************************************//**
   @brief Моргание светодиодом

    При вызове этой функции, если не запущен синхронный ввод/вывод, происходит
    кратковременное затухание красного цвета светодиода на передней панели
    L-502 или светодиода LED1 модуля E-502.
    Может быть использована для визуальной идентификации модуля после его
    открытия.

    При запущенном синхронном вводе/выводе данный светодиод всегда
    горит зеленым цветом и данная функция не влияет на его состояние.

    @param[in]  hnd     Описатель модуля.
    @return             Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_LedBlink(t_x502_hnd hnd);


/***************************************************************************//**
   @brief Установка подтягивающих резисторов на входных линиях

    Функция может использоваться для включения подтягивающих резисторов на
    цифровых входах. Для разных модулей подтягивающие резисторы реализованы
    на разных входах. Для всех модулей можно включать их на линиях SYN1 и SYN2.
    Для L-502 можно отдельно задавать включены или отключены подтяжки
    на младшей или старшей половине цифровых линий. Для E-502 можно включить
    подтягивающие к нулю резисторы на входах межмодульной синхронизации.

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

    При включении питания все подтягивающие резисторы отключены.

    @param[in] hnd      Описатель модуля.
    @param[in] pullups  Флаги (из #t_x502_pullups), определяющие, на каких
                        линиях включены подтягивающие резисторы.
    @return             Код ошибки.
 ******************************************************************************/
X502_EXPORT(int32_t) X502_SetDigInPullup(t_x502_hnd hnd, uint32_t pullups);


/***************************************************************************//**
   @brief Проверка поддержки модулем заданной возможности

    Функция используется для проверки, поддерживается ли определенная возможность
    из #t_x502_features для данного модуля с текущими версиями прошивок.

    Если возможность поддерживается, то будет возвращен код #X502_ERR_OK.

    Данная функция доступна в библиотеке версии 1.1.6 или выше.

    @param[in] hnd      Описатель модуля.
    @param[in] feature  Значение из #t_x502_features, определяющие, какую
                        возможность необходимо проверить.
    @return             Если возможность поддерживается, то возвращается
                        #X502_ERR_OK, иначе --- код ошибки
 ******************************************************************************/
X502_EXPORT(int32_t) X502_CheckFeature(t_x502_hnd hnd, uint32_t feature);

/** @} */
/** @} */

#ifdef __cplusplus
}
#endif


#endif // X502API_H
