Общий подход к использованию интерфейсных функций{#sect_gen_descr}
==============================================================

  Общий алгоритм работы с модулем{#sect_gen_alg}
  ==============================================================

Данный раздел описывает типичную последовательность действий при работе с модулем LTR35. Более подробно каждый шаг будет описан в последующих разделах.

Типичная последовательность действий имеет следующий вид:
1. Создать экземпляр структуры TLTR35, представляющей собой описатель модуля. Описатель модуля содержит всю информацию о модуле и используется при вызове всех остальных функций.
2. Проинициализировать поля описателя с помощью LTR35_Init().
3. Установить соединение с интересующим модулем с помощью функции LTR35_Open().
4. Заполнить все необходимые настройки модуля в поле @fieldref{TLTR35,Cfg} [описателя модуля](@ref TLTR35) и вызвать LTR35_Configure() для записи настроек в модуль.
5. Подготовка и вывод сигналов в соответствии с установленным [режимом вывода модуля](@ref sect_gen_modes), как описано ниже.
8. По завершению работы выполнить останов генерации сигналов с помощью LTR35_Stop() или LTR35_StopWithTout().
9. Закрыть соединение с модулем, вызвав функцию LTR35_Close().
 
Вывод сигнала при режиме циклического автогенератора{#sect_gen_alg_cycle}
-------------------------------------------------------------------
Для вывода периодических сигналов в режиме [циклического автогенератора](@ref sect_gen_mode_cycle) нужно выполнить следующие шаги:
1. Подготовить данные для выдачи в нужном формате с помощью LTR35_PrepareData() или LTR35_PrepareDacData().
2. Передать подготовленные данные в модуль с помощью LTR35_Send().
3. При необходимости повторить пункты 1 и 2 нужное количество раз, чтобы передать в модуль все отсчеты, соответствующие одному периоду воспроизводимых сигналов.
4. Вызвать функцию LTR35_SwitchCyclePage() для начала выдачи периодически повторяемого сигнала на ЦАП/цифровые линии.
5. При необходимости выставить новый сигнал повторить пункты 1-4 для выдачи следующего набора сигналов.

Вывод сигнала при потоковом режиме{#sect_gen_alg_stream}
-------------------------------------------------------------
Для вывода сигналов в [потоковом режиме](@ref sect_gen_mode_stream) нужно выполнить следующие шаги
1. Подготовить блок данных для выдачи в нужном формате с помощью LTR35_PrepareData() или LTR35_PrepareDacData() и передать в модуль с помощью LTR35_Send().
2. Запустить выдачу данных в потоковом режиме с помощью LTR35_StreamStart().
3. По мере необходимости подготавливать и подгружать в буфер LTR35 новые данные по аналогии с пунктом 1.


Настройка модуля{#sect_gen_cfg}
=============================================================
Настройка модуля должна выполняться хотя бы один раз после установления связи с модулем до загрузки данных на выдачу.

Настройка модуля выполняется аналогично большинству других модулей LTR: вначале значения всех параметров модуля записываются в соответствующие поля [структуры описателя модуля](@ref TLTR35), затем вызывается функция LTR35_Configure(), которая значения этих полей передает модулю.

Следует отметить, что все поля, относящиеся к настройке модуля, объединены в структуру типа #TLTR35_CONFIG (поле  @fieldref{TLTR35,Cfg} [описателя модуля](@ref TLTR35)). Только эти поля пользователь должен изменять вручную в [описателе модуля](@ref TLTR35) при штатной работе и именно эти поля влияют на параметры, передаваемые функцией LTR35_Configure() в модуль.

При настройке модуля задаются следующие параметры:
- Частота генерации ЦАП и вывода на цифровые линии (раздел @ref sect_gen_cfg_dac_freq).
- Настройки каналов ЦАП (раздел @ref sect_gen_cfg_dac_ch).
- Настройка режима вывода. Задается полем  @fieldref{TLTR35_CONFIG,OutMode}. Режимы вывода описаны в разделе @ref sect_gen_modes.
- Настройка формата передаваемых данных (раздел @ref sect_gen_cfg_data_fmt).
- Настройка арифметических генераторов (раздел @ref sect_gen_cfg_arith).
- Настройка параметров синхронного ввода (раздел @ref sect_gen_cfg_in_stream).
- Настройка синхронизации старта нескольких модулей (раздел @ref sec_gen_cfg_sync_multimodules).
- При необходимости настройка дополнительных параметров, задаваемых флагами конфигурации из перечисления #e_LTR35_CFG_FLAGS в поле @fieldref{TLTR35_CONFIG,Flags}.


После выполнения LTR35_Configure() рассчитываются некоторые параметры, которые являются производными от настроек из #TLTR35_CONFIG. Эти параметры записываются в соответствующие поля структуры состояния модуля типа #TLTR35_STATE (поле @fieldref{TLTR35,State} [описателя модуля](@ref TLTR35)). 



Настройка частоты генерации ЦАП и вывода на цифровые линии{#sect_gen_cfg_dac_freq}
---------------------------------------------------------------

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

Частота генерации ЦАП определяется двумя параметрами:
   - Значение входной частота ЦАП.  Для гибкой настройки в модуле установлен синтезатор частоты, который из частоты  30 МГц от единого опорного генератора крейта LTR генерирует частоту (далее именуемую частотой синтезатора ---  \f$ f_{synt}\f$), определяемую его настройками, которая уже является входной частотой для ЦАП. Для настроек синтезатора используется поле @fieldref{TLTR35_CONFIG,FreqSynt} в [настройках модуля](@ref TLTR35::Cfg), которое представляет собой  структуру типа #TLTR35_FREQ_SYNT_CONFIG. В описании данной структуры указана формула для определения частоты синтезатора по значениям полей данной структуры. 
   - Скоростью выдачи отсчетов самого ЦАП. Данный параметр задается с помощью поля @fieldref{TLTR35_CONFIG,DacRate} в [настройках модуля](@ref TLTR35::Cfg) и может принимать одно из значений из перечисления  #e_LTR35_RATE.  Скорость выдачи отсчетов определяет количество периодов входной частоты ЦАП, соответствующее выдаче одного отсчета. Каждая скорость соответствует своему допустимому интервалу частот генерации ЦАП. Отношение входной частоты и  частоты генерации ЦАП, а также допустимый интервал частот генерации для каждой скорости приведены в описании значений перечисления #e_LTR35_RATE.
   
Как правило пользователю не обязательно заполнять эти настройки вручную. Для заполнения этих полей предназначена функция LTR35_FillOutFreq(), которая сама подбирает подходящие настройки так, чтобы результирующая частота генерации ЦАП (и вывода на цифровые линии) была наиболее близка к заданной пользователем.

В качестве стандартных частот генерации определены следующие три частоты:
   - 192 КГц  (скорость #LTR35_DAC_RATE_QUAD)
   - 96 КГц   (скорость #LTR35_DAC_RATE_DOUBLE)
   - 48 КГц  (скорость #LTR35_DAC_RATE_SINGLE)
   
При необходимости пользователь может настроить любую частоту генерации ЦАП в диапазоне от 36 КГц (#LTR35_DAC_FREQ_MIN) до 192 КГц (#LTR35_DAC_FREQ_MAX), однако только для трех указанных выше стандартных частот определяются метрологические характеристики модуля, поэтому без крайней необходимости рекомендуются использовать именно стандартные частоты.

Следует отметить, что для всех трех стандартных частот вывода используются одна и та же частота синтезатора, равная 36,864 МГц (#LTR35_SYNT_FREQ_STD).

После завершения конфигурации с помощью LTR35_Configure() полученное результирующее значение частоты синтезатора возвращается в поле @fieldref{TLTR35_STATE,SyntFreq} структуры [состояния модуля](@ref TLTR35::State), а результирующее значение частоты генерации ЦАП и цифрового вывода --- в поле @fieldref{TLTR35_STATE,OutFreq}.

Настройка каналов ЦАП{#sect_gen_cfg_dac_ch}
-------------------------------------------------------------
В модуле LTR35 может быть 8, 4 или 0 каналов ЦАП в зависимости от модификации модуля. Количество каналов можно узнать по полю  @fieldref{TLTR35_MODULE_INFO,DacChCnt} структуры с [информацией о модуле](@ref TLTR35::ModuleInfo) после установления связи с модулем. 

Настройки каждого канала объединены в структуре #TLTR35_CHANNEL_CONFIG. Массив структур, каждый элемент которого соответствует определенному каналу, является полем @fieldref{TLTR35_CONFIG,Ch} структуры с [настройками модуля](@ref TLTR35::Cfg). Для каждого канала может быть настроено:
 - Разрешена ли выдача данных по этому каналу. Задается полем @fieldref{TLTR35_CHANNEL_CONFIG,Enabled}.
 - Какой из выходов используется для данного канала. Задается полем @fieldref{TLTR35_CHANNEL_CONFIG,Output}. Для LTR35-1 каждому каналу  соответствует два выхода (1:1 и 1:10) с разным диапазоном амплитуд воспроизводимого сигнала, в то время как для LTR35-2 используется всегда только один выход на канал.  При этом максимальное и минимальное значения для каждого выхода доступны в описании выходов (массив  @fieldref{TLTR35_MODULE_INFO,DacOutDescr} структуры с [информацией о модуле](@ref TLTR35::ModuleInfo)). При этом сигнал воспроизводится всегда на всех выходах используемого канала, но уровень, соответствующий переданным значениям обеспечивается только на настроенном выходе (на другом уровень сигнала отличается на соотношение диапазонов выходов), а также только на настроенном выходе обеспечиваются метрологические характеристики, так как для каждого выхода используются свои калибровочные коэффициенты. 
 - Источник сигнала для данного канала ЦАП. Задается полем @fieldref{TLTR35_CHANNEL_CONFIG,Source}. Источником могут быть как  отсчеты, загруженные в буфер модуля (#LTR35_CH_SRC_SDRAM), так и отсчеты, генерируемые внутри модуля арифметическими генераторами. Настройки арифметических генераторов описаны в разделе @ref sect_gen_cfg_arith.
 
 
Настройка арифметических генераторов{#sect_gen_cfg_arith}
----------------------------------------------------------------
В модуле LTR35 присутствует 4 (#LTR35_ARITH_SRC_CNT) синусоидальных арифметических генератора. У каждого генератора есть два выхода --- синус и косинус. Любой выход любого генератора можно подать на любой канал ЦАП, задав в настройках этого канала в поле @fieldref{TLTR35_CHANNEL_CONFIG,Source} соответствующее значение (при этом один выход арифметического генератора может быть подан на несколько каналов ЦАП). 

В случае, если на один или несколько каналов ЦАП нужно вывести синусоидальный сигнал заданной частоты, фазы, амплитуды и смещения, то использование арифметических генераторов позволяет сделать это не формируя сигнал в памяти и не загружая его в буфер модуля. Это в частности позволяет:
- Уменьшить время загрузки сигнала. При этом смену частоты, амплитуды и смещения можно выполнять посылкой минимального количества команд (функции LTR35_SetArithSrcDelta() и LTR35_SetArithAmp()), не влияя на остальные каналы при запущенной генерации сигналов.
- Уменьшить поток данных в модуль, что позволяет использовать больше каналов в [потоковом режиме](@ref sect_gen_mode_stream).
- Избежать занимаемого места в странице памяти в режиме [циклического автогенератора](@ref sect_gen_mode_cycle). Смена страниц и смена параметров сигнала от арифметического сигнала выполняются независимо, смена страниц не требует загрузки отсчетов для каналов с данными от арифметического генератора, а для смены частоты и амплитуды сигналов арифметического генератора не требуется смена страниц памяти.

Структура #TLTR35_ARITH_SRC_CONFIG содержит настройки одного арифметического генератора. Массив структур, каждый элемент которого соответствует определенному арифметическому генератору, является полем @fieldref{TLTR35_CONFIG,ArithSrc} структуры с [настройками модуля](@ref TLTR35::Cfg). Для каждого арифметического генератора может быть настроена частота и начальная фаза (поле @fieldref{TLTR35_ARITH_SRC_CONFIG,Phase}) сигнала. Частота задается с помощью поля @fieldref{TLTR35_ARITH_SRC_CONFIG,Delta}, которое задает значение приращения фазы для каждого последующего отсчета.
Для вычисления фазы в ПЛИС модуля LTR35 используются 32-битные целые положительные коды, вес каждого разряда которого равен \f$2\pi/2^{32}\f$. Для задания кода фазы используется структура #TLTR35_ARITH_PHASE, поле @fieldref{#TLTR35_ARITH_PHASE,CodeH} которой задает данный 32-битный код (также структура имеет резервное поле для возможности увеличения разрядности кода в будущем). Для заполнения этой структуры значениями, соответствующими заданной фазе в градусах, можно использовать функцию LTR35_FillArithPhaseDegree().

При этом частота выходного сигнала будет равна (Delta - фаза, соответствующая заданному коду приращения):
\f[ f_{sig} = \frac{f_{dac}*Delta}{360} \f]


Амплитуда и смещение сигнала задаются в Вольтах непосредственно в настройках канала #TLTR35_CHANNEL_CONFIG полями @fieldref{TLTR35_CHANNEL_CONFIG,ArithAmp} и @fieldref{TLTR35_CHANNEL_CONFIG,ArithOffs} соответственно. Эти настройки являются свойством канала, а не настройками генератора, т.е. для вывода на разные каналы синусоидальных сигналов с одинаковой частотой и фазой, но разными амплитудами и/или смещением можно использовать один и тот же генератор.

Два выхода каждого генератора (синус и косинус) могут быть использованы для получения с помощью одного генератора одинаковых сигналов (возможно с разными амплитудами), сдвинутых по фазе на 90 градусов (\f$\pi/2\f$).

Следует также отметить, что в [потоковом режиме](@ref sect_gen_mode_stream) генерация сигнала на каналах, выдающих сигнал с одного из арифметических генераторов, не зависит от состояния буфера подгружаемых потоковых данных, т.е. если происходит опустошение очереди, то генерация синусоидальных сигналов все равно выполняется непрерывно. В режиме [циклического автогенератора](@ref sect_gen_mode_cycle) 20-битный ражим позволяет только увеличить скорость загрузки страницы из ПК за счет сокращения передаваемых слов.


Настройка формата передаваемых данных{#sect_gen_cfg_data_fmt}
------------------------------------------------------------
Поле @fieldref{TLTR35_CONFIG,OutDataFmt} задает формат отсчетов при передаче от ПК в буфер модуля. Использование 20-битного формата (#LTR35_OUTDATA_FORMAT_20) приводит к потере младших 4-х бит отсчетов ЦАП по сравнению c 24-х битным (#LTR35_OUTDATA_FORMAT_24), но позволяет в 2 раза уменьшить объем данных, передаваемых в модуль, так как в этом формате каждый отсчет занимает одно 32-битное слово LTR, а не два. При этом формат влияет только на формат передаваемых слов, а не на формат отсчетов, хранящихся в самом буфере модуля --- в буфере модуля может хранится одинаковое количество отсчетов вне зависимости от настроенного формата передаваемых данных.

Таким образом, использование 20-битного формата может быть полезно в первую очередь в [потоковом режиме](@ref sect_gen_mode_stream), что позволяет задействовать больше каналов на большей частоте. 


Настройка синхронного ввода{#sect_gen_cfg_in_stream}
-----------------------------------------------------------
Помимо генерации сигналов на ЦАП и цифровых выходах модуль LTR35 также может осуществлять синхронный потоковый ввод, запуск и останов которого строго привязан к запуску и останову генерации сигналов. На момент написания данного документа эта возможность доступна только для [потокового режима](@ref sect_gen_mode_stream).

Все параметры синхронного ввода задаются с помощью поля @fieldref{TLTR35_CONFIG,InStream} в  [настройках модуля](@ref TLTR35::Cfg) и описаны с помощью структуры #TLTR35_IN_STREAM_CONFIG.

Существует два различных режима синхронного ввода, определяемых полем  @fieldref{TLTR35_IN_STREAM_CONFIG,InStreamMode}:
1. Режим эхо-канала (#LTR35_IN_STREAM_MODE_CH_ECHO). В данном режиме после запуска генерации модуль непосредственно в момент вывода нового отсчета передает в ПК слово с кодом, который записывается в заданный канал ЦАП в этот момент. Основные особенности данного режима:
 - Эхо-коды могут возвращаться только для одного канала. Номер этого канала задается с помощью поля @fieldref{TLTR35_IN_STREAM_CONFIG,EchoChannel}.
 - Частота слов в потоке синхронного ввода всегда равна частоте генерации данных на ЦАП вне зависимости от формата данных или количества разрешенных каналов.
 - Возвращаемые в эхо-данных коды ЦАП отличаются от передаваемых в модуль, так как передаются значения кодов, непосредственно записываемые в ЦАП, к которым уже были применены калибровочные коэффициенты и которые были пропущены через фильтр коррекции АЧХ внутри модуля.
 - В [потоковом режиме](@ref sect_gen_mode_stream), если происходит опустошение буфера, из-за чего один и тот же отсчет выводится повторно, то в ПК будет выслано по эхо-слову на каждый вывод отсчета, включая повторные. Т.е. частота эхо слов всегда соответствует частоте генерации ЦАП и не зависит от наличия данных в буфере модуля. Таким образом, при опустошении буфера количество высланных слов с эхо-данными может не совпадать с количеством переданных отсчетов по данному каналу в модуль и при использовании данного канала для контроля заполненности очереди следует не допускать опустошения.
 - На генерацию эхо-данных может быть настроен не только канал, отсчеты которого соответствуют переданным из ПК данным, но и канал, данные для которого генерируются одним из [арифметических генераторов](@ref sect_gen_cfg_arith).
 - Количество переданных слов с эхо-данными и их формат не зависят от настроенного [формата посылаемых данных](@ref sect_gen_cfg_data_fmt). Модуль всегда высылает только одно  слово LTR с записанным 24-битным кодом ЦАП на один период генерации ЦАП. 
 
2. Режим синхронного ввода состояний цифровых входов модуля (#LTR35_IN_STREAM_MODE_DI). В данном режиме реализуется синхронный цифровой ввод с одного или двух цифровых каналов с точной привязкой по времени к одновременно выполняемому выводу данных на ЦАП и цифровые выходы. Основные особенности данного режима:
   - Список цифровых входов, которые будут опрашиваться, задается с помощью поля @fieldref{TLTR35_IN_STREAM_CONFIG,DIChEnMask}. LTR35 имеет 2 цифровых входа: DI1 и DI2. Опрос может производится как одного выбранного цифрового входа, так и сразу обоих, однако при опросе обоих входов максимальная частота ввода каждого входа в два раза меньше, чем при опросе только одного.
   - Частота ввода получается на основе частоты синтезатора, также как и частота вывода (раздел @ref sect_gen_cfg_dac_freq), что позволяет обеспечить точное соответствие моментов ввода и вывода данных.
   - Частота ввода задается с помощью поля @fieldref{TLTR35_IN_STREAM_CONFIG,DIFreqDivPow} и определяется по формуле: \f[  f_{din\_acq}=\frac{f_{synt}}{4 * 2^{DIFreqDivPow}} \f] Фиксированный делитель равный 4 из приведенной формулы  определен константой #LTR35\_DIN\_SYNT\_FREQ\_DIV. При вводе с одного цифрового входа минимальное значение @fieldref{TLTR35_IN_STREAM_CONFIG,DIFreqDivPow} равно нулю и при стандартных частотах генерации максимальная частота ввода достигает 9,216 МГц. В случае ввода состояний обоих входов минимальное значение @fieldref{TLTR35_IN_STREAM_CONFIG,DIFreqDivPow} начинается с 1, что соответствует частоте 4,608 МГц на каждый вход для тех же условий. Для подбора значения поля @fieldref{TLTR35_IN_STREAM_CONFIG,DIFreqDivPow} так, чтобы частота ввода была наиболее близка к заданной, можно также использовать функцию LTR35_FillDIAcqFreq().
   - Из модуля передаются слова, каждое из которых содержит 24 измеренных значений состояний входов (12 с одного входа и 12 с другого при опросе обоих входов). Таким образом, частота слов в потоке ввода соответствует  \f$ f_{din\_word} = (f_{din\_acq} * N_{din\_en})/24 \f$, где \f$ N_{din\_en} \f$ --- количество опрашиваемых каналов.
   - После завершения конфигурации с помощью LTR35_Configure() полученное результирующее значение частоты опроса цифровых входов возвращается в поле @fieldref{TLTR35_STATE,InStreamDIAcqFreq} структуры [состояния модуля](@ref TLTR35::State), а результирующее значение частоты слов в потоке на ввод --- в поле @fieldref{TLTR35_STATE,InStreamWordFreq}.
   
   
 Прием и интерпретация данных при включенном синхронном вводе описаны в разделе @ref sect_gen_stream_in_modes.
 
 Настройка синхронизации нескольких модулей {#sec_gen_cfg_sync_multimodules}
 -----------------------------------------------------
  В модуле LTR35 реализована возможность запуска генерации (а также возможного ввода данных) по внешнему сигналу, что в частности позволяет выполнять одновременный синхронный запуск для нескольких модулей по принципу ведущий-ведомые. На момент написания данного документа эта возможность доступна только для [потокового режима](@ref sect_gen_mode_stream). Следует также учитывать общее ограничение скорости вывода на модули из одного крейта в [потоковом режиме](@ref sect_gen_mode_stream).

  Все параметры синхронного запуска задаются с помощью поля @fieldref{TLTR35_CONFIG,Sync} в  [настройках модуля](@ref TLTR35::Cfg) и описаны с помощью структуры #TLTR35_SYNC_CONFIG:
   - поле @fieldref{TLTR35_SYNC_CONFIG,SyncMode} задает режим синхронного запуска, что определяет роль модуля при многомодульном синхронном старте. Один модуль как правило настраивается как ведущий (#LTR35_SYNC_MODE_MASTER), который генерирует импульс старта на выходе DO8, а остальные модули настраиваются как ведомые (#LTR35_SYNC_MODE_SLAVE) --- на их вход DI2 подается внешний сигнал запуска генерации от мастера. Вместо мастера также может быть использован внешний сигнал запуска модулей, тогда все модули настраиваются как ведомые. 
   - поле @fieldref{TLTR35_SYNC_CONFIG,SlaveSrc} задает условие запуска генерации для ведомого модуля. В случае, если источником сигнала запуска является ведущий модуль LTR35 в режиме #LTR35_SYNC_MODE_MASTER, данное поле должно быть равным #LTR35_SYNC_SLAVE_SRC_DI2_RISE. Остальные значения могут быть полезны при использовании внешним образом генерируемого сигнала общего запуска.
   
   Последовательность вызовов для запуска модулей при при многомодульном синхронном старте описана в разделе @ref sect_gen_sync_multimodules.
     
Режимы вывода {#sect_gen_modes}
============================================

Режим вывода модуля устанавливается с помощью поля @fieldref{TLTR35_CONFIG,OutMode} структуры с [настройками модуля](@ref TLTR35::Cfg) и влияет на то, как используется внутренний буфер модуля с отсчетами для генерации сигналов. Т.е. режим влияет на каналы, данные для которых загружаются в буфер модуля --- то есть, каналы ЦАП с источником @fieldref{TLTR35_CHANNEL_CONFIG,Source} = #LTR35_CH_SRC_SDRAM и на вывод на цифровые линии. При этом в любом режиме часть каналов ЦАП может быть также настроена на работу от одного из [арифметических генераторов](@ref sect_gen_cfg_arith). 

Потоковый режим вывода{#sect_gen_mode_stream}
-------------------------------------------------

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

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

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

Следует иметь ввиду, что максимальная скорость потока вывода не должна превышать значения максимальной скорости интерфейса между крейтом и модулем, равной 500 КСлов/с. Для уменьшения размера потока в данном режиме вывода может быть использован 20-битный формат передаваемых отсчетов (раздел @ref sect_gen_cfg_data_fmt), что позволяет увеличить допустимое количество каналов в два раза. Для 20-битного режима для частоты генерации 192 КГц можно одновременно использовать два канала для потокового вывода, для частоты 96 КГц -- 5 каналов, для 48 КГц -- все каналы, включая вывод на цифровые линии.

Также важно отметить, что при использовании потокового вывода одновременно для нескольких модулей,  общая скорость потокового вывода в текущей реализации ПО и крейта также ограничена 500 КСлов/c на крейт, из-за того, что на вывод в крейте используется общая очередь, а слова на вывод в общем случае могут приходить блоками для одного модуля, что приводит к последовательной передачи блоков.

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

При попытке передать слово в модуль, буфер которого полностью заполнен, записываемое слово будет отброшено и будет установлен соответствующий флаг в следующем высланном периодическом статусе.
Чтобы гарантировать, что буфер модуля не будет переполнен, независимо от количества передаваемых данных, в службе ltrd реализована логика контроля заполненности очереди модуля. Для реализации этой логики модуль высылает специальные статусные слова, которые предназначены для ltrd и не видны на уровне ltr35api (ltrd обрабатывает эти слова сам и не передает клиентам):
- При настройке модуля через LTR35_Configure() модуль высылает статус с настройками, необходимыми для отслеживания заполненности буфера. Также этот специальный статус сообщает ltrd, что буфер  был очищен.
- При чтении каждых @fieldref{TLTR35_CONFIG,StreamStatusPeriod} (значение 0 означает, что используется значение по-умолчанию) отсчетов из буфера модуль высылает периодический статус, в котором также содержатся признаки, были ли за это время события опустошения буфера или были ли отброшены слова из-за заполненности буфера.

По приему этих слов ltrd определяет количество переданных, но не выведенных слов и обновляет статистику по заполненности очереди, возникновению событий опустошения или переполнения очереди.

При вызове LTR35_Send() слова передаются через буфер сокета канала обмена программы с ltrd в буфер ltrd. Из этого буфера, если в очереди модуля есть место, слова с максимальной скоростью интерфейса будут передаваться через буфер крейта в буфер модуля. При этом скорость будет ограничиваться сперва скоростью интерфейса ПК с крейтом, затем по заполнению буфера крейта --- скоростью интерфейса между крейтом и модулями. При заполнении буфера LTR35, ltrd будет ограничивать скорость передачи слов и поток передачи будет соответствовать скорости вывода отсчетов на ЦАП.

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

Для поддержки данного контроля переполнения необходимо, чтобы версия ltrd была не ниже 2.1.3.0.

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


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


Режим циклического автогенератора{#sect_gen_mode_cycle}
-------------------------------------
Данный режим может использоваться для вывода периодического сигнала произвольной формы. В этом режиме набор сигналов (по одному сигналу на каждый канал) сперва загружается в страницу буфер модуля, после чего по вызову функции LTR35_SwitchCyclePage() модуль начинает выдавать загруженные данные данной страницы. При этом чтение станицы идет циклически (после вывода всей страницы начинается повторный вывод тех же сигналов с начала страницы) и не требует дальнейшей подкачки данных. 

При выводе на несколько каналов сигналов с разными периодами нужно найти общий период всех сигналов как наименьшее общее кратное периодов каждого сигнала. При этом суммарное полученное число отсчетов не должно превышать #LTR35_MAX_POINTS_PER_PAGE.

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

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


Прием данных при синхронном вводе{#sect_gen_stream_in_modes}
============================================
В случае, если в настройках модуля был разрешен синхронный ввод (задан режим, отличный от  #LTR35_IN_STREAM_MODE_OFF), одновременно с запуском генерации данных модуль начинает передавать поток данных в ПК. Скорость и содержимое этих данных зависят от настроек, описанных в разделе @ref sect_gen_cfg_in_stream. Скорость потока данных (частота передаваемых слов) устанавливается в поле @fieldref{TLTR35_STATE,InStreamWordFreq} структуры [состояния модуля](@ref TLTR35::State).

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

Формат слов зависит от режима:
    - В  режиме эхо-канала для каждого слова младшие 24 бита точно равны записываемому в заданный канал ЦАП коду при соответствующем цикле вывода, а старшие 8 бит содержат расширение знака (дублируют старший бит кода ЦАП), что позволяет интерпретировать код как 32-битное целое знаковое число (INT).
    - В режиме ввода состояния цифровых линий старшие 8 бит 32-битного слова всегда равны нулю, а младшие 24 бита содержат состояния входов при соответствующем цикле опроса в зависимости от количества опрашиваемых каналов:
        - при опросе одного канала все 24 бита соответствуют последовательным 24-м измерениям состояния входа DI1 или DI2, при этом старший бит соответствует первому измерению, а младший --- последнему.
        - при опросе обоих каналов старшие 12 бит соответствуют опросу состояния входа DI2, а младшие 12 бит --- DI1. Аналогично в каждой последовательности из 12 бит старший бит соответствуют первому измерению, а младший --- последнему.

        
 Хотя функции библиотеки ltr35api сами по себе не являются потокобезопасными и пользователь должен гарантировать, что что вызовы функций для работы с одним и тем же модулем выполняется последовательно (работа с разными модулями LTR35,  как и для других типов модулей, может выполняться из разных потоков). Однако для возможности реализации одновременного ввода и вывода из разных потоков сделано исключение: после запуска генерации возможен одновременный вызов из одного потока функций LTR35_PrepareData() / LTR35_PrepareDacData() и LTR35_Send(), а из другого --- вызов LTR35_RecvInStreamData(). Таким образом, одновременный ввод-вывод из разных потоков может быть организован следующим образом:
    1. Начальная подкачка данных с помощью LTR35_PrepareData() / LTR35_PrepareDacData() и LTR35_Send().
    2. Запуск генерации данных с помощью LTR35_StreamStart().
    3. Запуск второго потока.
    4. Подкачка новых данных  потока с помощью LTR35_PrepareData() / LTR35_PrepareDacData() из одного и прием данных с помощью LTR35_RecvInStreamData() из другого.
    5. Повтор пункта 4 до завершения вывода.
    6. Останов второго потока.
    7. Останов генерации с помощью LTR35_Stop() / LTR35_StopWithTout().
 
Также можно организовать ввод и вывод из одного потока, используя тот факт, что частоты ввода и вывода основаны на одной частоте с выхода синтезатора и их соотношение явно известно для текущей конфигурации (соотношение значений в полях @fieldref{TLTR35_STATE,InStreamWordFreq} и @fieldref{TLTR35_STATE,OutFreq} соответственно). В этом случае запись и чтение должны выполняться блоками, точно соответствующими выбранному интервалу блока (\f$T_b\f$). Одновременный ввод и вывод может быть организован следующим образом:

1. Начальная подкачка данных с помощью LTR35_PrepareData() / LTR35_PrepareDacData() и LTR35_Send().
2. Запуск генерации данных с помощью LTR35_StreamStart().
3. Подкачка \f$ OutFreq * T_b\f$ новых точек на каждый разрешенный канал вывода с помощью LTR35_PrepareData() / LTR35_PrepareDacData(). 
4. Прием \f$ InStreamWordFreq * T_b\f$ слов данных с помощью функции  LTR35_RecvInStreamData().
5. Повтор пунктов 3 и 4 до завершения вывода.
6. Останов генерации с помощью LTR35_Stop() / LTR35_StopWithTout().

  
Синхронизация запуска нескольких модулей{#sect_gen_sync_multimodules}
=====================================

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

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

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

Ведомые модули по команде запуска генерации переходят в режим ожидания заданного с помощью поля @fieldref{TLTR35_SYNC_CONFIG,SlaveSrc} условия. В ответ на команду (начиная с прошивки FPGA версии 25) запуска ведущий отвечает два раза:
 - Первый ответ модуль возвращает когда уже запущено отслеживание условия запуска, т.е. именно после этого ответа можно выполнять генерацию сигнала запуска
 - Второй ответ возвращается ведомым уже после обнаружения условия запуска перед непосредственным началом ввода-вывода и может служить признаком успешного запуска по внешнему условию. 

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

Последовательность вызова функций для синхронного запуска выглядит следующим образом:
1. Конфигурация одного модуля ведущим,  остальных --- ведомыми 
2. Предзагрузка данных и запуск генерации без подтверждения для всех ведомых модулей с помощью LTR35_StreamStartRequest().
3. Ожидание готовности к внешнему старту каждого ведомого модуля с помощью LTR35_StreamStartWaitSlaveReady().
4. Предзагрузка данных и запуск ведущего модуля с помощью LTR35_StreamStart().
5. Ожидание завершения запуска генерации каждого ведомого модуля с помощью LTR35_StreamStartWaitDone(). В случае возвращения  функцией кода ошибки LTR\_ERROR\_OP\_DONE\_WAIT\_TOUT возможно продолжение ожидания повторным вызовом LTR35_StreamStartWaitDone() или прекращение ожидания с помощью LTR35_Stop().

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

Особенности калибровки данных{#sect_gen_cbr}
===========================================================
Следует отметить, что калибровка данных выполняется аппаратно внутри модуля, а не программно. В связи с этим в LTR35_PrepareData() и LTR35_PrepareDacData() нет никаких указаний о выполнении калибровки. Самой библиотекой при открытии связи с модулем через LTR35_Open() выполняется чтение калибровочных коэффициентов из Flash-памяти модуля, сохранение их в полях массива @fieldref{TLTR35_MODULE_INFO,CbrCoef} в [структуре с информацией о модуле](@ref TLTR35::ModuleInfo). При конфигурации модуля с помощью LTR35_Configure() выполняется запись нужных коэффициентов (в зависимости от настроенного выхода для каждого канала) в ПЛИС.

ПЛИС налету выполняет калибровку по формуле \f$ Y = (X + Offset)*Scale \f$, где X --- 24-битный отсчет, передаваемый в модуль (или генерируемый одним из [арифметических генераторов](@ref sect_gen_cfg_arith)), Y --- калиброванный отсчет, который непосредственно записывается в ЦАП, Offset --- смещение шкалы (24-битный код), а Scale --- коэффициент шкалы для настроенного выхода соответствующего канала. 


Если пользователю необходимо установить свои калибровочные коэффициенты, то он должен изменить значение полей @fieldref{TLTR35_MODULE_INFO,CbrCoef} в [структуре с информацией о модуле](@ref TLTR35::ModuleInfo) перед вызовом LTR35_Configure().

Также в ПЛИС модуля реализована коррекция АЧХ модуля с помощью КИХ-фильтра второго порядка в соответствии с методом, описанным в статье [Метод тонкой коррекции наклона АЧХ с помощью простого цифрового фильтра](http://www.lcard.ru/download/simple_fir_filter.pdf). 

Коэффициенты коррекции также загружаются из полей @fieldref{TLTR35_MODULE_INFO,CbrAfcCoef} в [структуре с информацией о модуле](@ref TLTR35::ModuleInfo)  во время вызова LTR35_Configure(). При необходимости данную коррекцию можно отключить на этапе конфигурации модуля, установив флаг #LTR35_CFG_FLAG_DISABLE_AFC_COR в поле @fieldref{TLTR35_CONFIG,Flags} в [настройках модуля](@ref TLTR35::Cfg).

