moved libs to the lib directory
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
# Данный файл описывает проект для системы сборки cmake.
|
||||
# С помощью cmake из этого файла можно получить нужный make-файл
|
||||
# для нужно родной системы сборки или проект для нужной среды.
|
||||
#
|
||||
# Для этого, из созданной директории для сборки нужно вызвать:
|
||||
#
|
||||
# cmake -DX502API_INCLUDE_DIR=<путь к заголовочным файлам x502api> -DX502API_LIBRARIES_DIR=<путь к файлу линкера x502api (.lib, .a или .so)> -G <имя генератора проекта> <путь к исходникам (данному файлу)>
|
||||
#
|
||||
# списко поддерживаемых генераторов можно получить вызвав cmake без аргументов
|
||||
#
|
||||
# Если заголовки и библиотека/файл линкера лежат в стандартных директориях,
|
||||
# то -DX502API_INCLUDE_DIR и -DX502API_LIBRARIES_DIR можно соответственно не указывать
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
set(PROJECT e502_eth_svc_browse)
|
||||
|
||||
project(${PROJECT} C)
|
||||
|
||||
set(SOURCES main.c)
|
||||
set(HEADERS )
|
||||
|
||||
include_directories(${X502API_INCLUDE_DIR})
|
||||
link_directories(${X502API_LIBRARIES_DIR})
|
||||
|
||||
add_executable(${PROJECT} ${HEADERS} ${SOURCES})
|
||||
|
||||
target_link_libraries(${PROJECT} x502api e502api)
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "e502_eth_svc_browse", "e502_eth_svc_browse.vcproj", "{D9460CE1-B571-4A69-A4C1-0676BF57EB04}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{D9460CE1-B571-4A69-A4C1-0676BF57EB04}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{D9460CE1-B571-4A69-A4C1-0676BF57EB04}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{D9460CE1-B571-4A69-A4C1-0676BF57EB04}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{D9460CE1-B571-4A69-A4C1-0676BF57EB04}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,199 @@
|
||||
<?xml version="1.0" encoding="windows-1251"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="e502_eth_svc_browse"
|
||||
ProjectGUID="{D9460CE1-B571-4A69-A4C1-0676BF57EB04}"
|
||||
RootNamespace="e502_eth_svc_browse"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="c:\Program Files (x86)\L-Card\lpcie\include\"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="x502api.lib e502api.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="c:\Program Files (x86)\L-Card\lpcie\lib\msvc"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="c:\Program Files (x86)\L-Card\lpcie\include\"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="x502api.lib e502api.lib"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="c:\Program Files (x86)\L-Card\lpcie\lib\msvc"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Ôàéëû èñõîäíîãî êîäà"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\main.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Çàãîëîâî÷íûå ôàéëû"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Ôàéëû ðåñóðñîâ"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -0,0 +1,205 @@
|
||||
/* Данный пример представляет из себя консольную программу на языке C,
|
||||
демонстрирующую, как можно выполнить поиск устройств E502 в локальной сети.
|
||||
|
||||
Пример запускается и непрерывно отслеживает появление (или исчезновение)
|
||||
устройств в локальной сети, выводя информацию на консоль.
|
||||
|
||||
Поиск выполняется до нажатия любой клавиши на Windows или CTRL+C на Linux.
|
||||
|
||||
Данный пример содержит проект для Visual Studio 2008, а также может быть собран
|
||||
gcc в Linux или mingw в Windows через makefile или с помощью cmake (подробнее
|
||||
в комментариях в соответствующих файлах).
|
||||
|
||||
Для того чтобы собрать проект в Visual Studio, измените путь к заголовочным файлам
|
||||
(Проект (Project) -> Свойства (Properties) -> Свойства конфигурации (Configuration Properties)
|
||||
-> С/С++ -> Общие (General) -> Дополнительные каталоги включения (Additional Include Directories))
|
||||
на тот, где у вас лежат заголовочный файлы x502api.h и e502api.h и измените путь к библиотекам
|
||||
(Проект (Project) -> Свойства (Properties) -> Свойства конфигурации (Configuration Properties) ->
|
||||
Компановщик (Linker) -> Общие (General) -> Дополнительные катологи библиотек (Additional Library Directories)).
|
||||
|
||||
Внимание!!: Если Вы собираете проект под Visual Studio и взяли проект с сайта (а не из SDK),
|
||||
то для корректного отображения русских букв в программе нужно изменить кодировку
|
||||
или указать сохранение с сигнатурой кодировки для UTF-8:
|
||||
выберите Файл (File) -> Дополнительные параметры сохранения (Advanced Save Options)...
|
||||
и в поле Кодировка (Encoding) выберите Юникод (UTF8, с сигнатурой)/Unicode (UTF-8 with signature)
|
||||
и сохраните изменения в файле.
|
||||
|
||||
*/
|
||||
|
||||
#include "e502api.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <locale.h>
|
||||
#include <conio.h>
|
||||
#else
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#define INST_NAME_PRINT_FMT "%ls"
|
||||
#else
|
||||
#define INST_NAME_PRINT_FMT "%s"
|
||||
#endif
|
||||
|
||||
/* признак необходимости завершить сбор данных */
|
||||
static int f_out = 0;
|
||||
|
||||
#ifndef _WIN32
|
||||
/* Обработчик сигнала завершения для Linux */
|
||||
static void f_abort_handler(int sig) {
|
||||
f_out = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int32_t err = X502_ERR_OK;
|
||||
int32_t stop_err;
|
||||
uint32_t ver;
|
||||
t_e502_eth_svc_browse_hnd browse_hnd;
|
||||
#ifndef _WIN32
|
||||
struct sigaction sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
/* В ОС Linux устанавливаем свой обработчик на сигнал закрытия,
|
||||
чтобы завершить сбор корректно */
|
||||
sa.sa_handler = f_abort_handler;
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
sigaction(SIGINT, &sa, NULL);
|
||||
sigaction(SIGABRT, &sa, NULL);
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
/* для вывода русских букв в консоль для ОС Windows в CP1251 без перевода в OEM */
|
||||
setlocale(LC_CTYPE, "");
|
||||
#endif
|
||||
/* получаем версию библиотеки */
|
||||
ver = X502_GetLibraryVersion();
|
||||
printf("Версия библиотеки: %d.%d.%d\n", (ver >> 24)&0xFF, (ver>>16)&0xFF, (ver>>8)&0xFF);
|
||||
|
||||
|
||||
/* Начинаем процесс поиска устройств в локальной сети */
|
||||
err = E502_EthSvcBrowseStart(&browse_hnd, 0);
|
||||
if (err != X502_ERR_OK) {
|
||||
fprintf(stderr, "Ошибка запуска поиска устройств в сети (%d): %s\n",
|
||||
err, X502_GetErrorString(err));
|
||||
} else {
|
||||
printf("Запущен поиск устройств в локальной сети. Для останова нажмите %s\n",
|
||||
#ifdef _WIN32
|
||||
"любую клавишу"
|
||||
#else
|
||||
"CTRL+C"
|
||||
#endif
|
||||
);
|
||||
while (!f_out && (err == X502_ERR_OK)) {
|
||||
t_e502_eth_svc_record_hnd svc_rec;
|
||||
uint32_t event;
|
||||
/* пробуем получить запись, сообщающую о изменении информации о подулюенных
|
||||
* устройтсвах */
|
||||
err = E502_EthSvcBrowseGetEvent(browse_hnd, &svc_rec, &event, NULL, 300);
|
||||
if (err != X502_ERR_OK) {
|
||||
fprintf(stderr, "Ошибка получения записи о найденном устройстве (%d): %s\n",
|
||||
err, X502_GetErrorString(err));
|
||||
} else if (event != E502_ETH_SVC_EVENT_NONE) {
|
||||
char inst_name[X502_INSTANCE_NAME_SIZE];
|
||||
char dev_serial[X502_SERIAL_SIZE];
|
||||
uint32_t addr;
|
||||
int32_t cur_err;
|
||||
#ifdef _WIN32
|
||||
WCHAR inst_name_w[X502_INSTANCE_NAME_SIZE];
|
||||
#endif
|
||||
|
||||
/* значение события, отличное от E502_ETH_SVC_EVENT_NONE, говорит
|
||||
* о том, что изменение произошло. Для каждого события мы можем
|
||||
* получить имя экземпляра и сер. номер устройства, для которого
|
||||
* произошло событие */
|
||||
cur_err = E502_EthSvcRecordGetInstanceName(svc_rec, inst_name);
|
||||
if (cur_err == X502_ERR_OK)
|
||||
cur_err = E502_EthSvcRecordGetDevSerial(svc_rec, dev_serial);
|
||||
#ifdef _WIN32
|
||||
if (cur_err == X502_ERR_OK) {
|
||||
/* Имя устройства всегда в кодировке UTF-8. В Windows для
|
||||
* представления юникодных строк используется формат UTF16
|
||||
* и строка представляется в виде массива WCHAR.
|
||||
* Для перевода используем функцию преобразования */
|
||||
if (MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, inst_name,
|
||||
-1, inst_name_w, X502_INSTANCE_NAME_SIZE)==0) {
|
||||
cur_err = X502_ERR_INSTANCE_NAME_ENCODING;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cur_err != X502_ERR_OK) {
|
||||
fprintf(stderr, "Ошибка получения параметров устройства (%d): %s\n",
|
||||
cur_err, X502_GetErrorString(cur_err));
|
||||
} else {
|
||||
if ((event == E502_ETH_SVC_EVENT_ADD) ||
|
||||
(event == E502_ETH_SVC_EVENT_CHANGED)) {
|
||||
/* События ADD и CHANGE означают, что устройство присутствует,
|
||||
* и мы можем получить IP-адрес устройства */
|
||||
cur_err = E502_EthSvcRecordResolveIPv4Addr(svc_rec, &addr, 4000);
|
||||
|
||||
if (cur_err == X502_ERR_OK) {
|
||||
printf("%s: " INST_NAME_PRINT_FMT ", S/N: %s, Адрес = %d.%d.%d.%d\n",
|
||||
event == E502_ETH_SVC_EVENT_ADD ? "Новое устройтсво" : "Изм. параметров",
|
||||
#ifdef _WIN32
|
||||
inst_name_w,
|
||||
#else
|
||||
inst_name,
|
||||
#endif
|
||||
dev_serial,
|
||||
(addr >> 24) & 0xFF, (addr >> 16) & 0xFF,
|
||||
(addr >> 8) & 0xFF, addr & 0xFF
|
||||
);
|
||||
|
||||
fflush(stdout);
|
||||
} else {
|
||||
fprintf(stderr, "Ошибка получения адреса устройства (%d): %s\n",
|
||||
cur_err, X502_GetErrorString(cur_err));
|
||||
}
|
||||
} else if (event == E502_ETH_SVC_EVENT_REMOVE) {
|
||||
printf("Устройство отключено: " INST_NAME_PRINT_FMT ", S/N: %s\n",
|
||||
#ifdef _WIN32
|
||||
inst_name_w,
|
||||
#else
|
||||
inst_name,
|
||||
#endif
|
||||
dev_serial);
|
||||
}
|
||||
}
|
||||
|
||||
/* Для всех событий, кроме NONE, выделяется запись, которую
|
||||
* нужно освободить вручную */
|
||||
E502_EthSvcRecordFree(svc_rec);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/* проверка нажатия клавиши для выхода */
|
||||
if (err == X502_ERR_OK) {
|
||||
if (_kbhit())
|
||||
f_out = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
stop_err = E502_EthSvcBrowseStop(browse_hnd);
|
||||
if (stop_err != X502_ERR_OK) {
|
||||
fprintf(stderr, "Ошибка останова поиска сервисов (%d): %s\n",
|
||||
stop_err, X502_GetErrorString(stop_err));
|
||||
if (err == X502_ERR_OK)
|
||||
err = stop_err;
|
||||
} else {
|
||||
printf("Останов поиска сервисов выполнен успешно!\n");
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
# makefile для сборки примера с помощью компиляторов mingw (под Windows)
|
||||
# или GCC (под Linux). Необходимо определить 3 переменные:
|
||||
#
|
||||
# CC - имя команды для вызова компилятора
|
||||
# X502API_LIBRARIES_DIR - путь к файлм .a или .so библиотек l502api, e502api, x502api (если не стандартный)
|
||||
# X502API_INCLUDE_DIR - путь к заголовочным файлам l502api.h, e502api.h, x502api.h
|
||||
#
|
||||
# Ниже приведено несколько примеров в закоментированном виде
|
||||
|
||||
#--- Linux с заголовками и библиотекой в стандартных директориях: компилятор GCC
|
||||
#CC = gcc
|
||||
|
||||
#--- Вариант запуска из MSYS со стандартным 32-битным mingw
|
||||
#CC = gcc
|
||||
#X502API_LIBRARIES_DIR = "/c/Program Files/L-Card/lpcie/lib/mingw"
|
||||
#X502API_INCLUDE_DIR = "/c/Program Files/L-Card/lpcie/include"
|
||||
|
||||
|
||||
#--- 64-битный вариант mingw w64, идущий вместе с cygwin --------
|
||||
#CC = x86_64-w64-mingw32-gcc
|
||||
#X502API_LIBRARIES_DIR = "/cygdrive/c/Program Files (x86)/L-Card/lpcie/lib/mingw64"
|
||||
#X502API_INCLUDE_DIR = "/cygdrive/c/Program Files (x86)/L-Card/lpcie/include"
|
||||
|
||||
#--- 32-битный вариант mingw w64, идущий вместе с cygwin --------
|
||||
#CC = i686-w64-mingw32-gcc
|
||||
#X502API_LIBRARIES_DIR = "/cygdrive/c/Program Files (x86)/L-Card/lpcie/lib/mingw"
|
||||
#X502API_INCLUDE_DIR = "/cygdrive/c/Program Files (x86)/L-Card/lpcie/include"
|
||||
|
||||
#--- 32-битный вариант mingw, идущий вместе с cygwin --------
|
||||
#CC = i686-pc-mingw32-gcc
|
||||
#X502API_LIBRARIES_DIR = "/cygdrive/c/Program Files (x86)/L-Card/lpcie/lib/mingw"
|
||||
#X502API_INCLUDE_DIR = "/cygdrive/c/Program Files (x86)/L-Card/lpcie/include"
|
||||
|
||||
|
||||
FLAGS =
|
||||
|
||||
ifdef X502API_LIBRARIES_DIR
|
||||
FLAGS += -L $(X502API_LIBRARIES_DIR)
|
||||
endif
|
||||
|
||||
ifdef X502API_INCLUDE_DIR
|
||||
FLAGS += -I $(X502API_INCLUDE_DIR)
|
||||
endif
|
||||
|
||||
|
||||
|
||||
all:
|
||||
$(CC) main.c $(FLAGS) -lx502api -le502api -o e502_eth_svc_browse
|
||||
@@ -0,0 +1,29 @@
|
||||
# Данный файл описывает проект для системы сборки cmake.
|
||||
# С помощью cmake из этого файла можно получить нужный make-файл
|
||||
# для нужно родной системы сборки или проект для нужной среды.
|
||||
#
|
||||
# Для этого, из созданной директории для сборки нужно вызвать:
|
||||
#
|
||||
# cmake -DX502API_INCLUDE_DIR=<путь к заголовочным файлам x502api> -DX502API_LIBRARIES_DIR=<путь к файлу линкера x502api (.lib, .a или .so)> -G <имя генератора проекта> <путь к исходникам (данному файлу)>
|
||||
#
|
||||
# списко поддерживаемых генераторов можно получить вызвав cmake без аргументов
|
||||
#
|
||||
# Если заголовки и библиотека/файл линкера лежат в стандартных директориях,
|
||||
# то -DX502API_INCLUDE_DIR и -DX502API_LIBRARIES_DIR можно соответственно не указывать
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
set(PROJECT e502_timestamp_stream)
|
||||
|
||||
project(${PROJECT} C)
|
||||
|
||||
set(SOURCES main.c)
|
||||
set(HEADERS )
|
||||
|
||||
include_directories(${X502API_INCLUDE_DIR})
|
||||
link_directories(${X502API_LIBRARIES_DIR})
|
||||
|
||||
add_executable(${PROJECT} ${HEADERS} ${SOURCES})
|
||||
|
||||
target_link_libraries(${PROJECT} x502api l502api e502api)
|
||||
@@ -0,0 +1,681 @@
|
||||
/*
|
||||
Пример работы с модулями E502-P1 поддерживающими механизм синхронизации времени по протоколу PTP.
|
||||
|
||||
Данный пример представляет из себя консольную программу на языке C,
|
||||
демонстрирующую работу синхронного
|
||||
ввода данных с АЦП и цифровых линий, а также работу с потоком данных включающим в себя метки времени.
|
||||
|
||||
Перед сбором в примере идет поиск модулей, подключенных по интерфейсам USB,
|
||||
и предоставляется список для выбора модуля, с которым нужно работать.
|
||||
Для подключения по Ethernet нужно указать IP-адреса интересующих модулей
|
||||
в качестве аргументов командной строки при вызове примера, тогда эти адреса
|
||||
будут добавлены в конец списка выбора модуля.
|
||||
Например, если интересуют модули с адресами 192.168.1.5 и 192.168.1.6,
|
||||
то пример можно вызвать:
|
||||
x502_stream_read 192.168.1.5 192.168.1.6
|
||||
и две дополнительные строки с этими адресами появятся в списке выбора.
|
||||
|
||||
Настройки частот, количества принимаемых данных и т.д. задаются с помощью макросов в
|
||||
начале программы.
|
||||
Настройки логических каналов - с помощью таблиц f_channels/f_ch_modes/f_ch_ranges.
|
||||
|
||||
Пример выполняет прием блоков данных заданного размера.
|
||||
Сбор идет до нажатия любой клавиши на Windows или CTRL+C на Linux.
|
||||
|
||||
Пример также показывает как выполнять обработку данных и определять начало кадра,
|
||||
в случае если в X502_ProcessData() передается не целое число кадров.
|
||||
|
||||
Данный пример содержит проект для Visual Studio 2008, а также может быть собран
|
||||
gcc в Linux или mingw в Windows через makefile или с помощью cmake (подробнее
|
||||
в комментариях в соответствующих файлах).
|
||||
|
||||
Для того чтобы собрать проект в Visual Studio, измените путь к заголовочным файлам
|
||||
(Проект (Project) -> Свойства (Properties) -> Свойства конфигурации (Configuration Properties)
|
||||
-> С/С++ -> Общие (General) -> Дополнительные каталоги включения (Additional Include Directories))
|
||||
на тот, где у вас лежат заголовочный файлы x502api.h, l502api.h и e502api.h и измените путь к библиотекам
|
||||
(Проект (Project) -> Свойства (Properties) -> Свойства конфигурации (Configuration Properties) ->
|
||||
Компановщик (Linker) -> Общие (General) -> Дополнительные катологи библиотек (Additional Library Directories)).
|
||||
|
||||
Внимание!!: Если Вы собираете проект под Visual Studio и взяли проект с сайта (а не из SDK),
|
||||
то для корректного отображения русских букв в программе нужно изменить кодировку
|
||||
или указать сохранение с сигнатурой кодировки для UTF-8:
|
||||
выберите Файл (File) -> Дополнительные параметры сохранения (Advanced Save Options)...
|
||||
и в поле Кодировка (Encoding) выберите Юникод (UTF8, с сигнатурой)/Unicode (UTF-8 with signature)
|
||||
и сохраните изменения в файле.
|
||||
|
||||
*/
|
||||
|
||||
#include "l502api.h"
|
||||
#include "e502api.h"
|
||||
#include "x502tstp.h"
|
||||
|
||||
#include "../../devs/e502/e502_fpga_regs.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <locale.h>
|
||||
#include <conio.h>
|
||||
|
||||
#else
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "x502api_private.h"
|
||||
|
||||
#define STREAM_IN_WRD_TYPE(wrd) wrd & 0x80000000 ? STREAM_IN_WRD_ADC : \
|
||||
(wrd & 0xFF000000) == 0x0 ? STREAM_IN_WRD_DIN : \
|
||||
(wrd & 0xF0000000) == 0x40000000 ? STREAM_IN_WRD_TSP : \
|
||||
((wrd & 0xFF000000)>>24) == 0x01 ? STREAM_IN_WRD_MSG : STREAM_IN_WRD_USR
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define CLOCK_MONOTONIC 1
|
||||
|
||||
int clock_gettime(int a, struct timespec *spec) {
|
||||
__int64 wintime; GetSystemTimeAsFileTime((FILETIME*)&wintime);
|
||||
wintime -=116444736000000000i64; //1jan1601 to 1jan1970
|
||||
spec->tv_sec =wintime / 10000000i64; //seconds
|
||||
spec->tv_nsec =wintime % 10000000i64 *100; //nano-seconds
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define NSEC_PER_SEC 1000000000
|
||||
|
||||
void timespec_diff(struct timespec *a, struct timespec *b,
|
||||
struct timespec *result) {
|
||||
result->tv_sec = a->tv_sec - b->tv_sec;
|
||||
result->tv_nsec = a->tv_nsec - b->tv_nsec;
|
||||
if (result->tv_nsec < 0) {
|
||||
--result->tv_sec;
|
||||
result->tv_nsec += NSEC_PER_SEC;
|
||||
}
|
||||
}
|
||||
|
||||
double timespec_to_double(struct timespec *ts)
|
||||
{
|
||||
return ((double)(ts->tv_sec) + ((double)(ts->tv_nsec) / NSEC_PER_SEC));
|
||||
}
|
||||
|
||||
|
||||
/* признак необходимости завершить сбор данных */
|
||||
static int f_out = 0;
|
||||
|
||||
/* количество используемых логических каналов */
|
||||
#define ADC_LCH_CNT 1
|
||||
|
||||
/* частота сбора АЦП в Гц*/
|
||||
#define ADC_FREQ 1000000
|
||||
#define ADC_FRAME_FREQ (ADC_FREQ/ADC_LCH_CNT)
|
||||
/* частота синхронного ввода в Гц*/
|
||||
#define DIN_FREQ 1000000
|
||||
|
||||
#define ENABLE_ADC
|
||||
#define ENABLE_DIN
|
||||
|
||||
// при ADC_FREQ==2000000 и DIN_FREQ==1000000 через Ethernet обязательно будет X502_STREAM_IN_MSG_OVERFLOW
|
||||
|
||||
|
||||
#define TCP_CONNECTION_TOUT 5000
|
||||
|
||||
|
||||
/* сколько отсчетов считываем за блок */
|
||||
#define READ_BLOCK_SIZE 4096*66*3
|
||||
/* таймаут на прием блока (мс) */
|
||||
#define READ_TIMEOUT 2000
|
||||
|
||||
|
||||
/* номера используемых физических каналов */
|
||||
static uint32_t f_channels[ADC_LCH_CNT] = {0};
|
||||
/* режимы измерения для каналов */
|
||||
static uint32_t f_ch_modes[ADC_LCH_CNT] = {X502_LCH_MODE_DIFF};
|
||||
/* диапазоны измерения для каналов */
|
||||
static uint32_t f_ch_ranges[ADC_LCH_CNT] = {X502_ADC_RANGE_10};
|
||||
|
||||
|
||||
t_x502_hnd g_hnd = NULL;
|
||||
|
||||
#ifndef _WIN32
|
||||
/* Обработчик сигнала завершения для Linux */
|
||||
static void f_abort_handler(int sig) {
|
||||
f_out = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Функция находит все подключенные модули по интерфейсам PCI-Express и USB и
|
||||
* сохраняет записи о этих устройствах в выделенный массив.
|
||||
* Также создаются записи по переданным IP-адресам модулей и добавляются в конец
|
||||
* массива.
|
||||
* Указатель на выделенный массив, который должен быть потом очищен, сохраняется
|
||||
* в pdevrec_list, а количество действительных элементов (память которых должна
|
||||
* быть в дальнейшем освобождена с помощью X502_FreeDevRecordList()) возвращается
|
||||
* как результат функции */
|
||||
static uint32_t f_get_all_devrec(t_x502_devrec **pdevrec_list, uint32_t *ip_addr_list, unsigned ip_cnt) {
|
||||
int32_t fnd_devcnt = 0;
|
||||
uint32_t pci_devcnt = 0;
|
||||
uint32_t usb_devcnt = 0;
|
||||
|
||||
t_x502_devrec *rec_list = NULL;
|
||||
|
||||
/* получаем количество подключенных устройств по интерфейсам PCI и USB */
|
||||
//L502_GetDevRecordsList(NULL, 0, 0, &pci_devcnt);
|
||||
E502_UsbGetDevRecordsList(NULL, 0, 0, &usb_devcnt);
|
||||
|
||||
if ((pci_devcnt + usb_devcnt + ip_cnt) != 0) {
|
||||
/* выделяем память для массива для сохранения найденного количества записей */
|
||||
rec_list = malloc((pci_devcnt + usb_devcnt + ip_cnt) * sizeof(t_x502_devrec));
|
||||
|
||||
if (rec_list != NULL) {
|
||||
unsigned i;
|
||||
/* получаем записи о модулях L502, но не больше pci_devcnt */
|
||||
if (pci_devcnt!=0) {
|
||||
int32_t res = L502_GetDevRecordsList(&rec_list[fnd_devcnt], pci_devcnt, 0, NULL);
|
||||
if (res >= 0) {
|
||||
fnd_devcnt += res;
|
||||
}
|
||||
}
|
||||
/* добавляем записи о модулях E502, подключенных по USB, в конец массива */
|
||||
if (usb_devcnt!=0) {
|
||||
int32_t res = E502_UsbGetDevRecordsList(&rec_list[fnd_devcnt], usb_devcnt, 0, NULL);
|
||||
if (res >= 0) {
|
||||
fnd_devcnt += res;
|
||||
}
|
||||
}
|
||||
|
||||
/* создаем записи для переданного массива ip-адресов */
|
||||
for (i=0; i < ip_cnt; i++) {
|
||||
if (E502_MakeDevRecordByIpAddr(&rec_list[fnd_devcnt], ip_addr_list[i],0, TCP_CONNECTION_TOUT) == X502_ERR_OK) {
|
||||
fnd_devcnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fnd_devcnt != 0) {
|
||||
/* если создана хотя бы одна запись, то сохраняем указатель на выделенный массив */
|
||||
*pdevrec_list = rec_list;
|
||||
} else {
|
||||
*pdevrec_list = NULL;
|
||||
free(rec_list);
|
||||
}
|
||||
|
||||
return fnd_devcnt;
|
||||
}
|
||||
|
||||
|
||||
static t_x502_hnd f_dev_select_open(int argc, char** argv) {
|
||||
uint32_t fnd_devcnt,i, dev_ind;
|
||||
t_x502_devrec *devrec_list = NULL;
|
||||
uint32_t *ip_addr_list = NULL;
|
||||
uint32_t ip_cnt = 0;
|
||||
t_x502_hnd hnd = NULL;
|
||||
|
||||
/* если есть аргументы командной строки, то предполагаем, что это могут быть
|
||||
ip-адреса интересующих устройств. */
|
||||
if (argc > 1) {
|
||||
ip_addr_list = malloc((argc-1) * sizeof(ip_addr_list[0]));
|
||||
if (ip_addr_list == NULL) {
|
||||
fprintf(stderr, "Ошибка выделения памяти!\n");
|
||||
} else {
|
||||
for (i=1; (int)i < argc; i++) {
|
||||
int a[4];
|
||||
if (sscanf(argv[i], "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3])==4) {
|
||||
ip_addr_list[ip_cnt++] = ((a[0] & 0xFF) << 24) |
|
||||
((a[1] & 0xFF) << 16) |
|
||||
((a[2] & 0xFF) << 8) |
|
||||
(a[3] & 0xFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* получаем список модулей для выбора */
|
||||
fnd_devcnt = f_get_all_devrec(&devrec_list, ip_addr_list, ip_cnt);
|
||||
|
||||
if (fnd_devcnt == 0) {
|
||||
printf("Не найдено ни одного модуля\n");
|
||||
} else {
|
||||
/* выводим информацию по списку модулей */
|
||||
printf("Доступны следующие модули:\n");
|
||||
for (i=0; i < fnd_devcnt; i++) {
|
||||
printf("Модуль № %d: %s, %-9s", i, devrec_list[i].devname,
|
||||
devrec_list[i].iface == X502_IFACE_PCI ? "PCI/PCIe" :
|
||||
devrec_list[i].iface == X502_IFACE_USB ? "USB" :
|
||||
devrec_list[i].iface == X502_IFACE_ETH ? "Ethernet" : "?");
|
||||
|
||||
/* при подключении по сети по IP-адресу серийный номер можно узнать
|
||||
только после открытия соединения. При этом поле location
|
||||
содержит строку с описанием адреса устройства */
|
||||
if (devrec_list[i].iface != X502_IFACE_ETH) {
|
||||
printf("Сер. номер: %s\n", devrec_list[i].serial);
|
||||
} else {
|
||||
printf("Адрес: %s\n", devrec_list[i].location);
|
||||
}
|
||||
}
|
||||
|
||||
/* выбираем нужный по введенному номеру модуля по порядку с клавиатуры */
|
||||
printf("Введите номер модуля, с которым хотите работать (от 0 до %d)\n", fnd_devcnt-1);
|
||||
fflush(stdout);
|
||||
scanf("%d", &dev_ind);
|
||||
|
||||
if (dev_ind >= fnd_devcnt) {
|
||||
printf("Неверно указан номер модуля...\n");
|
||||
} else {
|
||||
/* если ввели номер правильно - создаем описатель */
|
||||
hnd = X502_Create();
|
||||
if (hnd==NULL) {
|
||||
fprintf(stderr, "Ошибка создания описателя модуля!");
|
||||
} else {
|
||||
/* устанавливаем связь с модулем по записи */
|
||||
int32_t err = X502_OpenByDevRecord(hnd, &devrec_list[dev_ind]);
|
||||
if (err != X502_ERR_OK) {
|
||||
fprintf(stderr, "Ошибка установления связи с модулем: %s!", X502_GetErrorString(err));
|
||||
X502_Free(hnd);
|
||||
hnd = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* освобождение ресурсов действительных записей из списка */
|
||||
X502_FreeDevRecordList(devrec_list, fnd_devcnt);
|
||||
/* очистка памяти самого массива */
|
||||
free(devrec_list);
|
||||
}
|
||||
|
||||
/* освобождаем выделенный массив под IP-адреса (если был выделен) */
|
||||
free(ip_addr_list);
|
||||
|
||||
return hnd;
|
||||
}
|
||||
|
||||
/* настройка параметров модуля */
|
||||
int32_t f_setup_params(t_x502_hnd hnd) {
|
||||
int32_t err = X502_ERR_OK, i;
|
||||
|
||||
/* устанавливаем параметры логической таблицы АЦП */
|
||||
err = X502_SetLChannelCount(hnd, ADC_LCH_CNT);
|
||||
for (i=0; (i < ADC_LCH_CNT) && (err == X502_ERR_OK); i++)
|
||||
err = X502_SetLChannel(hnd, i, f_channels[i], f_ch_modes[i], f_ch_ranges[i], 0);
|
||||
|
||||
/* устанавливаем частоты ввода для АЦП и цифровых входов */
|
||||
if (err == X502_ERR_OK) {
|
||||
double f_adc = ADC_FREQ, f_frame = ADC_FRAME_FREQ, f_din = DIN_FREQ;
|
||||
|
||||
err = X502_SetAdcFreq(hnd, &f_adc, &f_frame);
|
||||
if (err == X502_ERR_OK)
|
||||
err = X502_SetDinFreq(hnd, &f_din);
|
||||
if (err == X502_ERR_OK) {
|
||||
/* выводим реально установленные значения - те что вернули функции */
|
||||
printf("Установлены частоты:\n Частота сбора АЦП = %0.0f\n"
|
||||
" Частота на лог. канал = %0.0f\n Частота цифрового ввода = %0.0f\n",
|
||||
f_adc, f_frame, f_din);
|
||||
}
|
||||
}
|
||||
|
||||
/* записываем настройки в модуль */
|
||||
if (err == X502_ERR_OK)
|
||||
err = X502_Configure(hnd, 0);
|
||||
|
||||
/* разрешаем синхронные потоки */
|
||||
if (err == X502_ERR_OK) {
|
||||
int streams = 0;
|
||||
#ifdef ENABLE_ADC
|
||||
streams |= X502_STREAM_ADC;
|
||||
#endif
|
||||
#ifdef ENABLE_DIN
|
||||
streams |= X502_STREAM_DIN;
|
||||
#endif
|
||||
err = X502_StreamsEnable(hnd, streams);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int32_t err = X502_ERR_OK;
|
||||
uint32_t ver;
|
||||
#ifndef _WIN32
|
||||
struct sigaction sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
/* В ОС Linux устанавливаем свой обработчик на сигнал закрытия,
|
||||
чтобы завершить сбор корректно */
|
||||
sa.sa_handler = f_abort_handler;
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
sigaction(SIGINT, &sa, NULL);
|
||||
sigaction(SIGABRT, &sa, NULL);
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
/* для вывода русских букв в консоль для ОС Windows в CP1251 без перевода в OEM */
|
||||
setlocale(LC_CTYPE, "");
|
||||
#endif
|
||||
/* получаем версию библиотеки */
|
||||
ver = X502_GetLibraryVersion();
|
||||
printf("Версия библиотеки: %d.%d.%d\n", (ver >> 24)&0xFF, (ver>>16)&0xFF, (ver>>8)&0xFF);
|
||||
|
||||
/********** Получение списка устройств и выбор, с каким будем работать ******************/
|
||||
g_hnd = f_dev_select_open(argc, argv);
|
||||
|
||||
/********************************** Работа с модулем **************************/
|
||||
/* если успешно выбрали модуль и установили с ним связь - продолжаем работу */
|
||||
if (g_hnd != NULL) {
|
||||
/* получаем информацию */
|
||||
t_x502_info info;
|
||||
err = X502_GetDevInfo(g_hnd, &info);
|
||||
if (err != X502_ERR_OK) {
|
||||
fprintf(stderr, "Ошибка получения серийного информации о модуле: %s!", X502_GetErrorString(err));
|
||||
} else {
|
||||
/* выводим полученную информацию */
|
||||
printf("Установлена связь со следующим модулем:\n");
|
||||
printf(" Серийный номер : %s\n", info.serial);
|
||||
printf(" Наличие ЦАП : %s\n", info.devflags & X502_DEVFLAGS_DAC_PRESENT ? "Да" : "Нет");
|
||||
printf(" Наличие BlackFin : %s\n", info.devflags & X502_DEVFLAGS_BF_PRESENT ? "Да" : "Нет");
|
||||
printf(" Наличие гальваноразвязки: %s\n", info.devflags & X502_DEVFLAGS_GAL_PRESENT ? "Да" : "Нет");
|
||||
printf(" Индустриальное исп. : %s\n", info.devflags & X502_DEVFLAGS_INDUSTRIAL ? "Да" : "Нет");
|
||||
printf(" Наличие интерф. PCI/PCIe: %s\n", info.devflags & X502_DEVFLAGS_IFACE_SUPPORT_PCI ? "Да" : "Нет");
|
||||
printf(" Наличие интерф. USB : %s\n", info.devflags & X502_DEVFLAGS_IFACE_SUPPORT_USB ? "Да" : "Нет");
|
||||
printf(" Наличие интерф. Ethernet: %s\n", info.devflags & X502_DEVFLAGS_IFACE_SUPPORT_ETH ? "Да" : "Нет");
|
||||
printf(" Версия ПЛИС : %d.%d\n", (info.fpga_ver >> 8) & 0xFF, info.fpga_ver & 0xFF);
|
||||
printf(" Версия PLDA : %d\n", info.plda_ver);
|
||||
if (info.mcu_firmware_ver != 0) {
|
||||
printf(" Версия прошивки ARM : %d.%d.%d.%d\n",
|
||||
(info.mcu_firmware_ver >> 24) & 0xFF,
|
||||
(info.mcu_firmware_ver >> 16) & 0xFF,
|
||||
(info.mcu_firmware_ver >> 8) & 0xFF,
|
||||
info.mcu_firmware_ver & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
if (err == X502_ERR_OK) {
|
||||
/* настраиваем параметры модуля */
|
||||
err = f_setup_params(g_hnd);
|
||||
if (err != X502_ERR_OK)
|
||||
fprintf(stderr, "Ошибка настройки модуля: %s!", X502_GetErrorString(err));
|
||||
}
|
||||
|
||||
/*err = X502_FpgaRegRead(g_hnd, E502_REGS_ARM_BLOCK, &val);
|
||||
if (err) {
|
||||
printf("X502_FpgaRegRead err=%d\n", err);
|
||||
} else {
|
||||
printf("X502_FpgaRegRead(E502_REGS_ARM_BLOCK) = %d\n", val);
|
||||
} */
|
||||
|
||||
// Включаем метки времени в потоке
|
||||
X502_FpgaRegWrite(g_hnd, E502_REGS_ARM_TIME_CTRL, 1);
|
||||
|
||||
X502_FpgaRegWrite(g_hnd, E502_REGS_IOHARD_GO_SYNC_IO, 0);
|
||||
X502_FpgaRegWrite(g_hnd, E502_REGS_BF_CTL, X502_REGBIT_BF_CTL_BF_RESET_Msk);
|
||||
|
||||
X502_SetSyncMode(g_hnd, X502_SYNC_INTERNAL);
|
||||
|
||||
/* запуск синхронного ввода-вывода */
|
||||
if (err == X502_ERR_OK) {
|
||||
err = X502_StreamsStart(g_hnd);
|
||||
if (err != X502_ERR_OK) {
|
||||
fprintf(stderr, "Ошибка запуска сбора данных: %s!\n", X502_GetErrorString(err));
|
||||
}
|
||||
}
|
||||
|
||||
if (err == X502_ERR_OK) {
|
||||
int block;
|
||||
int32_t stop_err;
|
||||
|
||||
printf("Сбор данных запущен. Для останова нажмите %s\n",
|
||||
#ifdef _WIN32
|
||||
"любую клавишу"
|
||||
#else
|
||||
"CTRL+C"
|
||||
#endif
|
||||
);
|
||||
fflush(stdout);
|
||||
|
||||
struct timespec start_time;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &start_time);
|
||||
|
||||
int32_t g_rcv_cnt = 0;
|
||||
int cntr = 0;
|
||||
int rcv_cntr = 0;
|
||||
|
||||
t_x502_tstp_state tstp_state;
|
||||
|
||||
X502_tstp_init(&tstp_state, ADC_FREQ, DIN_FREQ);
|
||||
|
||||
|
||||
for (block = 0; (err == X502_ERR_OK) && !f_out; block++) {
|
||||
int32_t rcv_size;
|
||||
uint32_t adc_size, din_size;
|
||||
uint32_t adc_wrd_num = 0;
|
||||
uint32_t din_wrd_num = 0;
|
||||
|
||||
/* массив для приема необработанных данных */
|
||||
static uint32_t rcv_buf[READ_BLOCK_SIZE];
|
||||
static uint32_t snd_buf[READ_BLOCK_SIZE];
|
||||
static double adc_data[READ_BLOCK_SIZE];
|
||||
static uint32_t din_data[READ_BLOCK_SIZE];
|
||||
|
||||
int i;
|
||||
|
||||
struct timespec cur_time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
||||
|
||||
/* принимаем данные (по таймауту) */
|
||||
rcv_size = X502_Recv(g_hnd, rcv_buf, READ_BLOCK_SIZE, READ_TIMEOUT);
|
||||
if (rcv_size < 0) {
|
||||
err = rcv_size;
|
||||
fprintf(stderr, "Ошибка приема данных: %s\n", X502_GetErrorString(err));
|
||||
continue;
|
||||
}
|
||||
adc_size = sizeof(adc_data)/sizeof(adc_data[0]);
|
||||
din_size = sizeof(din_data)/sizeof(din_data[0]);
|
||||
|
||||
/* обрабатываем принятые данные, распределяя их на данные АЦП и цифровых входов */
|
||||
err = X502_ProcessData(g_hnd, rcv_buf, rcv_size, X502_PROC_FLAGS_VOLT,
|
||||
adc_data, &adc_size, din_data, &din_size);
|
||||
if (err != X502_ERR_OK) {
|
||||
fprintf(stderr, "Ошибка обработки данных: %s\n", X502_GetErrorString(err));
|
||||
continue;
|
||||
}
|
||||
|
||||
g_rcv_cnt += rcv_size;
|
||||
int error = 0;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &cur_time);
|
||||
|
||||
if (cur_time.tv_sec - start_time.tv_sec >= 5) {
|
||||
//printf("rcv speed=%lld wrds/sec cntr=%x\n", (g_rcv_cnt) / (cur_time.tv_sec - start_time.tv_sec), rcv_cntr);
|
||||
start_time.tv_sec = cur_time.tv_sec;
|
||||
g_rcv_cnt = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < rcv_size; i++) {
|
||||
uint32_t cur_wrd = rcv_buf[i];
|
||||
uint64_t cur_wrd_time;
|
||||
t_stream_in_wrd_type type = STREAM_IN_WRD_TYPE(cur_wrd);
|
||||
|
||||
X502_tstp_process_wrd(&tstp_state, cur_wrd);
|
||||
X502_tstp_get_curwrd_time(&tstp_state, &cur_wrd_time) ;
|
||||
|
||||
/* проверяем - это данные от АЦП или цифровых входов */
|
||||
if (type == STREAM_IN_WRD_DIN) {
|
||||
uint16_t din_wrd;
|
||||
static bool last_din_wrd_initialized = false;
|
||||
static uint16_t last_din_wrd;
|
||||
|
||||
if (!tstp_state.tstp_mark_rcvd) {
|
||||
fprintf(stderr, "No timestamp received, DIN wrd unexpected!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
din_wrd = din_data[din_wrd_num];
|
||||
din_wrd_num++;
|
||||
|
||||
#define DIN_PPS_MASK 1
|
||||
|
||||
if (!last_din_wrd_initialized) {
|
||||
last_din_wrd = din_wrd;
|
||||
last_din_wrd_initialized = true;
|
||||
} else
|
||||
if ((din_wrd & DIN_PPS_MASK) != (last_din_wrd & DIN_PPS_MASK) && (din_wrd & DIN_PPS_MASK)) {
|
||||
// дождались положительный фронт сигнала PPS на ножке DI1
|
||||
static bool last_pps_edge_time_initialized = false;
|
||||
static uint64_t last_pps_edge_time = 0;
|
||||
|
||||
X502_tstp_get_curwrd_time(&tstp_state, &cur_wrd_time);
|
||||
|
||||
{
|
||||
static uint32_t nsec_max = 0;
|
||||
static uint32_t nsec_min = -1;
|
||||
uint64_t sec_time;
|
||||
uint64_t ns_time;
|
||||
sec_time = cur_wrd_time - TSTP_SEC_TO_SSEC(TSTP_SECSSEC_TO_SEC(cur_wrd_time));
|
||||
ns_time = TSTP_SSEC_TO_NSEC(sec_time);
|
||||
if (ns_time > 500000000) {
|
||||
ns_time = NSEC_PER_SEC - ns_time;
|
||||
}
|
||||
if (ns_time > nsec_max) {
|
||||
nsec_max = ns_time;
|
||||
}
|
||||
if (ns_time < nsec_min) {
|
||||
nsec_min = ns_time;
|
||||
}
|
||||
printf("DIN PPS positive edge: %ld ns (max - min = %d)\n", ns_time, nsec_max - nsec_min);
|
||||
}
|
||||
|
||||
if (last_pps_edge_time_initialized ) {
|
||||
uint64_t pps_period;
|
||||
pps_period = cur_wrd_time - last_pps_edge_time;
|
||||
printf("DIN PPS positive edge pediod = %d.%09d\n", TSTP_SECSSEC_TO_SEC(pps_period), TSTP_SSEC_TO_NSEC(pps_period));
|
||||
} else {
|
||||
last_pps_edge_time_initialized = true;
|
||||
}
|
||||
|
||||
last_pps_edge_time = cur_wrd_time;
|
||||
}
|
||||
last_din_wrd = din_wrd;
|
||||
} else
|
||||
if (type == STREAM_IN_WRD_ADC) {
|
||||
static uint16_t last_adc_wrd;
|
||||
register uint32_t wrd = rcv_buf[i];
|
||||
double adc_val;
|
||||
static bool adc_wait_for_edge = false;
|
||||
|
||||
if (!tstp_state.tstp_mark_rcvd) {
|
||||
fprintf(stderr, "No timestamp received, ADC wrd unexpected!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
adc_val = adc_data[adc_wrd_num];
|
||||
adc_wrd_num++;
|
||||
|
||||
X502_tstp_get_curwrd_time(&tstp_state, &cur_wrd_time);
|
||||
|
||||
if (adc_wait_for_edge) {
|
||||
if (adc_val > 2.4) {
|
||||
// дождались положительный фронт сигнала PPS на 1 канале ADC
|
||||
static bool last_pps_edge_time_initialized = false;
|
||||
static uint64_t last_pps_edge_time = 0;
|
||||
|
||||
adc_wait_for_edge = false;
|
||||
|
||||
{
|
||||
static uint32_t nsec_max = 0;
|
||||
static uint32_t nsec_min = -1;
|
||||
uint64_t sec_time;
|
||||
uint64_t ns_time;
|
||||
sec_time = cur_wrd_time - TSTP_SEC_TO_SSEC(TSTP_SECSSEC_TO_SEC(cur_wrd_time));
|
||||
ns_time = TSTP_SSEC_TO_NSEC(sec_time);
|
||||
if (ns_time > 500000000) {
|
||||
ns_time = NSEC_PER_SEC - ns_time;
|
||||
}
|
||||
if (ns_time > nsec_max) {
|
||||
nsec_max = ns_time;
|
||||
}
|
||||
if (ns_time < nsec_min) {
|
||||
nsec_min = ns_time;
|
||||
}
|
||||
printf("ADC PPS positive edge: %ld ns (max - min = %d)\n", ns_time, nsec_max - nsec_min);
|
||||
}
|
||||
|
||||
if (last_pps_edge_time_initialized ) {
|
||||
uint64_t pps_period;
|
||||
pps_period = cur_wrd_time - last_pps_edge_time;
|
||||
|
||||
printf("ADC PPS positive edge period = %d.%09d\n", TSTP_SECSSEC_TO_SEC(pps_period),
|
||||
TSTP_SSEC_TO_NSEC(pps_period));
|
||||
|
||||
} else {
|
||||
last_pps_edge_time_initialized = true;
|
||||
}
|
||||
|
||||
last_pps_edge_time = cur_wrd_time;
|
||||
}
|
||||
} else
|
||||
if (adc_val < 2.3) {
|
||||
adc_wait_for_edge = true;
|
||||
}
|
||||
}
|
||||
|
||||
rcv_cntr++;
|
||||
}
|
||||
#if 0
|
||||
adc_size = sizeof(adc_data)/sizeof(adc_data[0]);
|
||||
din_size = sizeof(din_data)/sizeof(din_data[0]);
|
||||
int adc_data_num = 0;
|
||||
|
||||
/* обрабатываем принятые данные, распределяя их на данные АЦП и цифровых входов */
|
||||
err = X502_ProcessData(g_hnd, rcv_buf, rcv_size, X502_PROC_FLAGS_VOLT,
|
||||
adc_data, &adc_size, din_data, &din_size);
|
||||
if (err != X502_ERR_OK) {
|
||||
fprintf(stderr, "Ошибка обработки данных: %s\n", X502_GetErrorString(err));
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((tstp_state.dinwrds_after_tstp / DIN_FREQ) > 2)
|
||||
{
|
||||
printf("Warning: timestamp mark undetected after %d seconds\n", tstp_state.dinwrds_after_tstp / DIN_FREQ);
|
||||
}
|
||||
if ((tstp_state.adcwrds_after_tstp / ADC_FREQ) > 2)
|
||||
{
|
||||
printf("Warning: timestamp mark undetected after %d seconds\n", tstp_state.adcwrds_after_tstp / ADC_FREQ);
|
||||
}
|
||||
|
||||
continue;
|
||||
|
||||
#ifdef _WIN32
|
||||
/* проверка нажатия клавиши для выхода */
|
||||
if (_kbhit())
|
||||
f_out = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* останавливаем поток сбора данных (независимо от того, была ли ошибка) */
|
||||
stop_err = X502_StreamsStop(g_hnd);
|
||||
if (stop_err != X502_ERR_OK) {
|
||||
fprintf(stderr, "Ошибка останова сбора данных: %s\n", X502_GetErrorString(err));
|
||||
if (err == X502_ERR_OK)
|
||||
err = stop_err;
|
||||
} else {
|
||||
printf("Сбор данных остановлен успешно\n");
|
||||
}
|
||||
|
||||
// Выключаем метки времени в потоке
|
||||
X502_FpgaRegWrite(g_hnd, E502_REGS_ARM_TIME_CTRL, 0);
|
||||
}
|
||||
|
||||
/* закрываем связь с модулем */
|
||||
X502_Close(g_hnd);
|
||||
/* освобождаем описатель */
|
||||
X502_Free(g_hnd);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
# Данный файл описывает проект для системы сборки cmake.
|
||||
# С помощью cmake из этого файла можно получить нужный make-файл
|
||||
# для нужно родной системы сборки или проект для нужной среды.
|
||||
#
|
||||
# Для этого, из созданной директории для сборки нужно вызвать:
|
||||
#
|
||||
# cmake -DL502API_INCLUDE_DIR=<путь к заголовочным файлам l502api> -DL502API_LIBRARIES_DIR=<путь к файлу линкера l502api (.lib, .a или .so)> -G <имя генератора проекта> <путь к исходникам (данному файлу)>
|
||||
#
|
||||
# списко поддерживаемых генераторов можно получить вызвав cmake без аргументов
|
||||
#
|
||||
# Если заголовки и библиотека/файл линкера лежат в стандартных директориях,
|
||||
# то -DL502API_INCLUDE_DIR и -DL502API_LIBRARIES_DIR можно соответственно не указывать
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
set(PROJECT x502_cycle_out)
|
||||
|
||||
project(${PROJECT} C)
|
||||
|
||||
set(SOURCES main.c ../common/dev_funcs.c)
|
||||
set(HEADERS )
|
||||
|
||||
include_directories(${X502API_INCLUDE_DIR} ../common)
|
||||
link_directories(${X502API_LIBRARIES_DIR})
|
||||
|
||||
add_executable(${PROJECT} ${HEADERS} ${SOURCES})
|
||||
|
||||
target_link_libraries(${PROJECT} x502api l502api e502api)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
target_link_libraries(${PROJECT} m)
|
||||
endif(CMAKE_COMPILER_IS_GNUCC)
|
||||
@@ -0,0 +1,296 @@
|
||||
/* Данный пример демонстрирует возможность установки циклического сигнала на
|
||||
вывод в модуль E16 / E502 / L502 (ввод не используется вообще).
|
||||
|
||||
В примере определена таблица сигналов, которая задает несколько
|
||||
комбинаций сигналов для примера. Каждый сигнал задается количеством точек
|
||||
на период (общее значение для всех трех сигналов), амплитудой для ЦАП'ов и
|
||||
функцией для генерации очередного отсчета по его номеру и полному размеру.
|
||||
|
||||
Пользовтель может ввести номер сигнала, которых он хочет выставить и нажать Enter - и этот
|
||||
сигнал будет выставлен на выходе.
|
||||
|
||||
Смена сигнала происходит по концу периода предыдущего.
|
||||
Надо также помнить, что хотя мы можем загружать новый сигнал на фоне вывода
|
||||
предыдущего, однако сразу после выполнения L502_OutCycleSetup() до того
|
||||
времени как реально произойдет смена старого сигнала на новый нельзя
|
||||
начинать загружать еще один новый сигнал.
|
||||
|
||||
|
||||
Данный пример содержит проект для Visual Studio 2008, а также может быть собран
|
||||
gcc в Linux или mingw в Windows через makefile или с помощью cmake (подробнее
|
||||
в коментариях в соответствующих файлах).
|
||||
|
||||
Для того чтобы собрать проект в Visual Studio, измените путь к заголовочным файлам
|
||||
(Проект (Project) -> Свойства (Properties) -> Свойства конфигурации (Configuration Properties)
|
||||
-> С/С++ -> Общие (General) -> Дополнительные каталоги включения (Additional Include Directories))
|
||||
на тот, где у вас лежат заголовочный файл l502api.h и измените путь к библиотекам
|
||||
(Проект (Project) -> Свойства (Properties) -> Свойства конфигурации (Configuration Properties) ->
|
||||
Компановщик (Linker) -> Общие (General) -> Дополнительные катологи библиотек (Additional Library Directories)).
|
||||
|
||||
Внимание!!: Если Вы собираете проект под Visual Studio и взяли проект с сайта (а не из SDK),
|
||||
то для корректного отображения русских букв в программе нужно изменить кодировку
|
||||
или указать сохранение с сигнатурой кодировки для UTF-8:
|
||||
выберите Файл (File) -> Доболнительные параметры сохранения (Advanced Save Options)...
|
||||
и в поле Кодировка (Encoding) выберите Юникод (UTF8, с сигнатурой)/Unicode (UTF-8 with signature)
|
||||
и сохраните изменения в файле.
|
||||
*/
|
||||
|
||||
#include "l502api.h"
|
||||
#include "e502api.h"
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "dev_funcs.h"
|
||||
|
||||
#define TCP_CONNECTION_TOUT 5000
|
||||
#define OUT_SIGNAL_SIZE 2000
|
||||
#define OUT_BLOCK_SIZE 256
|
||||
#define SEND_TOUT 500
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
typedef double (*f_gen_sig_word)(uint32_t cntr, uint32_t total_size, double amp);
|
||||
typedef uint32_t (*f_gen_dout_word)(uint32_t cntr, uint32_t total_size);
|
||||
/* структура, задающая сигналы на 2-х каналах ЦАП и/или1
|
||||
1на DOUT */
|
||||
typedef struct {
|
||||
uint32_t size; /* количество точек в сигнале */
|
||||
double amp_dac1; /* амплитуда сигнала для ЦАП1 */
|
||||
f_gen_sig_word gen_func_dac1; /* функция для генерации отсчета для ЦАП1 */
|
||||
double amp_dac2; /* амплитуда сигнала для ЦАП2 */
|
||||
f_gen_sig_word gen_func_dac2; /* функция для генерации отсчета для ЦАП2 */
|
||||
f_gen_dout_word gen_dout; /* функция для генерации слова на цифровой вывод */
|
||||
} t_sig_struct;
|
||||
|
||||
|
||||
/* генерация пилы на весь период */
|
||||
static double f_gen_saw(uint32_t cntr, uint32_t total_size, double amp) {
|
||||
return amp*( (int32_t)(cntr%total_size)-(int32_t)total_size/2)/(total_size/2);
|
||||
}
|
||||
|
||||
/* генерация синуса на весь период */
|
||||
static double f_gen_sin(uint32_t cntr, uint32_t total_size, double amp) {
|
||||
return amp*sin(2*M_PI*cntr/total_size);
|
||||
}
|
||||
|
||||
/* генерация тестового честчика */
|
||||
static double f_gen_cntr(uint32_t cntr, uint32_t total_size, double amp) {
|
||||
return cntr + 0x123;
|
||||
}
|
||||
|
||||
/* генерация синуса с периодом в два раза меньше периоду определяемому размером буфера */
|
||||
static double f_gen_sin2(uint32_t cntr, uint32_t total_size, double amp) {
|
||||
return amp*sin(2*2*M_PI*cntr/total_size);
|
||||
}
|
||||
|
||||
/* генерация меандра на всех выходах путем выдачи в первой половине на выходы 0xAA, а на второй 0x55 */
|
||||
static uint32_t f_gen_dout_meander(uint32_t cntr, uint32_t total_size) {
|
||||
return cntr < total_size/2 ? 0xAA : 0x55;
|
||||
}
|
||||
|
||||
/* генерация счетчика на цифроых выхоах*/
|
||||
static uint32_t f_gen_dout_cntr(uint32_t cntr, uint32_t total_size) {
|
||||
return cntr;
|
||||
}
|
||||
|
||||
|
||||
/* таблица, задающая сигналы для выдачи на вход */
|
||||
/* для модуля E16 частота выходного сигнала будет в 2 раза меньше, т.к. частота ЦАП 500КГц протип 1МГц у E502 */
|
||||
static t_sig_struct f_sig_tbl[] = {
|
||||
{100000, X502_DAC_RANGE, f_gen_saw, 0, NULL, NULL}, /* пила на одном канале с частотой 10 Гц */
|
||||
{2000, X502_DAC_RANGE, f_gen_sin, 0, NULL, NULL}, /* синусоидальный сигнал на одном канале с частотой 500 Гц */
|
||||
{100, X502_DAC_RANGE/2, f_gen_sin, X502_DAC_RANGE, f_gen_saw, NULL}, /* синус ампл. 2.5 и пила по 10 КГц */
|
||||
{50, 0, NULL, X502_DAC_RANGE, f_gen_sin, f_gen_dout_cntr}, /* синус только на втором канале с частотой 20 КГц */
|
||||
{2550, 1.5, f_gen_sin, 2.5, f_gen_sin2, f_gen_dout_meander}, /* на втором канале синус с частотой в 2 раза больше. меандр на цифровых линиях */
|
||||
};
|
||||
|
||||
|
||||
/* Запись в буфер драйвера блока данных от сигнала
|
||||
cntr - номер отчета, соответствующего первому отсчету блока
|
||||
size - количество отсчетов на канал (т.е. записывается ch_cnt*size отсчетов)
|
||||
sig - номер сигнала
|
||||
ch_cnt - кол-во используемых каналов (это кол-во можно определить по f_sig_tbl[sig],
|
||||
но так как мы его уже определили, то передаем сюда, чтобы опять не определять */
|
||||
static int32_t f_load_block(t_x502_hnd hnd, uint32_t cntr, uint32_t size, uint32_t sig, uint32_t ch_cnt) {
|
||||
static double dac_data1[OUT_BLOCK_SIZE], dac_data2[OUT_BLOCK_SIZE];
|
||||
static uint32_t dout_data[OUT_BLOCK_SIZE];
|
||||
/* массив слов на запись в модуль - содержит смешенные подготовленные данные
|
||||
для всех каналов (максимум для 3-х - 2 ЦАП + DOUT) */
|
||||
static uint32_t sbuf[3*OUT_BLOCK_SIZE];
|
||||
uint32_t i;
|
||||
int32_t err = 0;
|
||||
|
||||
/* заполняем массив на вывод */
|
||||
for (i=0; i < size; i++) {
|
||||
if (f_sig_tbl[sig].gen_func_dac1 != NULL) {
|
||||
dac_data1[i] = f_sig_tbl[sig].gen_func_dac1(cntr+i, f_sig_tbl[sig].size, f_sig_tbl[sig].amp_dac1);
|
||||
}
|
||||
if (f_sig_tbl[sig].gen_func_dac2 != NULL) {
|
||||
dac_data2[i] = f_sig_tbl[sig].gen_func_dac2(cntr+i, f_sig_tbl[sig].size, f_sig_tbl[sig].amp_dac2);
|
||||
}
|
||||
if (f_sig_tbl[sig].gen_dout != NULL) {
|
||||
dout_data[i] = f_sig_tbl[sig].gen_dout(cntr+i, f_sig_tbl[sig].size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Если нужная функция определена, значит мы испоьлзуем этот канал, и
|
||||
* подаем на вход сформированный массив. Иначе - канал не используется
|
||||
* и передаем на вход NULL */
|
||||
err = X502_PrepareData(hnd,
|
||||
f_sig_tbl[sig].gen_func_dac1 ? dac_data1 : NULL,
|
||||
f_sig_tbl[sig].gen_func_dac2 ? dac_data2 : NULL,
|
||||
f_sig_tbl[sig].gen_dout ? dout_data : NULL,
|
||||
size, X502_DAC_FLAGS_VOLT | X502_DAC_FLAGS_CALIBR,
|
||||
sbuf);
|
||||
if (err != X502_ERR_OK) {
|
||||
fprintf(stderr, "Ошибка подкотовки данных на передачу: %s\n",
|
||||
X502_GetErrorString(err));
|
||||
} else {
|
||||
/* посылаем данные */
|
||||
int32_t snd_cnt = X502_Send(hnd, sbuf, size*ch_cnt, SEND_TOUT);
|
||||
if (snd_cnt < 0) {
|
||||
err = snd_cnt;
|
||||
fprintf(stderr, "Ошибка передачи данных: %s\n", X502_GetErrorString(err));
|
||||
} else if ((uint32_t)snd_cnt != size*ch_cnt) {
|
||||
/* так как мы шлем всегда не больше чем готово, то должны
|
||||
всегда передать все */
|
||||
fprintf(stderr, "Переданно недостаточно данных: передавали = %d, передано = %d\n",
|
||||
size*ch_cnt, snd_cnt);
|
||||
err = X502_ERR_SEND_INSUFFICIENT_WORDS;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int32_t f_load_cycle_signal(t_x502_hnd hnd, int sig) {
|
||||
int32_t err = 0;
|
||||
uint32_t cntr = 0;
|
||||
uint32_t ch_cnt=0;
|
||||
|
||||
/* определяем, сколько каналов используем */
|
||||
if (f_sig_tbl[sig].gen_func_dac1)
|
||||
ch_cnt++;
|
||||
if (f_sig_tbl[sig].gen_func_dac2)
|
||||
ch_cnt++;
|
||||
if (f_sig_tbl[sig].gen_dout)
|
||||
ch_cnt++;
|
||||
|
||||
|
||||
/* задаем размер буфера под все каналы! */
|
||||
err = X502_OutCycleLoadStart(hnd, f_sig_tbl[sig].size*ch_cnt);
|
||||
if (err != X502_ERR_OK)
|
||||
fprintf(stderr, "Ошибка старта загрузки данных: %s!", X502_GetErrorString(err));
|
||||
|
||||
/* в примере показано, что загружать можно поблочно, чтобы не выделять
|
||||
* большой размер памяти на весь сигнал в программе. Но можно записать
|
||||
* весь сигнал и за один L502_Send() */
|
||||
while ((cntr != f_sig_tbl[sig].size) && (err == X502_ERR_OK)) {
|
||||
uint32_t block_size = OUT_BLOCK_SIZE;
|
||||
/* последний блок может быть меньшего размера, если размер буфера не кратен
|
||||
* блоку */
|
||||
if (block_size >(f_sig_tbl[sig].size-cntr))
|
||||
block_size=f_sig_tbl[sig].size-cntr;
|
||||
|
||||
err = f_load_block(hnd, cntr, block_size, sig, ch_cnt);
|
||||
if (!err)
|
||||
cntr+=block_size;
|
||||
}
|
||||
|
||||
/* делаем активным загруженный сигнал */
|
||||
if (err == X502_ERR_OK) {
|
||||
err = X502_OutCycleSetup(hnd, X502_OUT_CYCLE_FLAGS_WAIT_DONE);
|
||||
if (err != X502_ERR_OK)
|
||||
fprintf(stderr, "Ошибка установки циклического сигнала: %s!", X502_GetErrorString(err));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int32_t err = 0;
|
||||
uint32_t ver;
|
||||
t_x502_hnd hnd = NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
/* устанавливаем локаль, чтобы можно было выводить по-русски в CP1251 без перевода в OEM */
|
||||
setlocale(LC_CTYPE, "");
|
||||
#endif
|
||||
|
||||
/********** Получение списка устройств и выбор, с каким будем работать ******************/
|
||||
hnd = select_dev_from_list(argc, argv, 0);
|
||||
|
||||
/********************************** Работа с модулем **************************/
|
||||
/* если успешно выбрали модуль и установили с ним связь - продолжаем работу */
|
||||
if (hnd != NULL) {
|
||||
/* Разрешаем все каналы на вывод (в этом примере мы не будем
|
||||
использовать асинхронный вывод), а какие каналы реально будут
|
||||
использованы определяем когда подаем данные в L502_PrepareData */
|
||||
err = X502_StreamsEnable(hnd, X502_STREAM_ALL_OUT);
|
||||
if (err != X502_ERR_OK) {
|
||||
fprintf(stderr, "Ошибка разрешения потоков (%d): %s!", err,
|
||||
X502_GetErrorString(err));
|
||||
}
|
||||
|
||||
if (err == X502_ERR_OK) {
|
||||
/* если хотим, то можем загрузить синхнал до разрешения
|
||||
* синхронного ввода. Тогда мы могли бы его запустить, наприемер,
|
||||
всесте с АЦП по L502_StreamsStart() */
|
||||
err = f_load_cycle_signal(hnd, 1);
|
||||
|
||||
/* разрешаем синхронный ввод. В принципе можно его разрешить только
|
||||
* после загрузки первого синала в нашем примере. Но данный пример
|
||||
* показывает что мы можем сделать это и до выставления сигнала,
|
||||
* например если захотим запустить ввод АЦП до того как будет нужно
|
||||
* подать циклический сигнал на вывод */
|
||||
if (err == X502_ERR_OK)
|
||||
err = X502_StreamsStart(hnd);
|
||||
|
||||
if (err == X502_ERR_OK) {
|
||||
int exit = 0;
|
||||
|
||||
printf("Введите одно из следующего:\n");
|
||||
printf(" число от 1 до %d - установить сигнал с указанным номером\n",
|
||||
(int)(sizeof(f_sig_tbl)/sizeof(f_sig_tbl[0])));
|
||||
printf(" s или stop - останов генерации сигнала\n");
|
||||
printf(" e или exit - выход из программы\n");
|
||||
|
||||
/* Цикл ввода команд */
|
||||
while (!err && !exit) {
|
||||
char cmd[512];
|
||||
printf(">");
|
||||
fflush(stdout);
|
||||
scanf("%s", cmd);
|
||||
if (!strcmp(cmd, "exit") || !strcmp(cmd,"e")) {
|
||||
exit=1;
|
||||
} else if (!strcmp(cmd, "stop")||!strcmp(cmd,"s")) {
|
||||
err = X502_OutCycleStop(hnd, X502_OUT_CYCLE_FLAGS_WAIT_DONE);
|
||||
if (err != X502_ERR_OK) {
|
||||
fprintf(stderr, "Ошибка останова циклического сигнала (%d): %s\n",
|
||||
err, X502_GetErrorString(err));
|
||||
}
|
||||
} else {
|
||||
int sig = atoi(cmd);
|
||||
if ((sig <= 0) || (sig > (int)(sizeof(f_sig_tbl)/sizeof(f_sig_tbl[0])))) {
|
||||
fprintf(stderr, "Неверный номер сигнала или неизвестная команда\n");
|
||||
} else {
|
||||
err = f_load_cycle_signal(hnd, sig-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
X502_StreamsStop(hnd);
|
||||
}
|
||||
}
|
||||
|
||||
/* закрываем связь с модулем */
|
||||
X502_Close(hnd);
|
||||
/* освобождаем описатель */
|
||||
X502_Free(hnd);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# makefile для сборки примера с помощью компиляторов mingw (под Windows)
|
||||
# или GCC (под Linux). Необходимо определить 3 переменные:
|
||||
#
|
||||
# CC - имя команды для вызова компилятора
|
||||
# X502API_LIBRARIES_DIR - путь к файлм .a или .so библиотек l502api, e502api, x502api (если не стандартный)
|
||||
# X502API_INCLUDE_DIR - путь к заголовочным файлам l502api.h, e502api.h, x502api.h
|
||||
#
|
||||
# Ниже приведено несколько примеров в закоментированном виде
|
||||
|
||||
#--- Linux с заголовками и библиотекой в стандартных директориях: компилятор GCC
|
||||
#CC = gcc
|
||||
|
||||
#--- Вариант запуска из MSYS со стандартным 32-битным mingw
|
||||
#CC = gcc
|
||||
#X502API_LIBRARIES_DIR = "/c/Program Files/L-Card/lpcie/lib/mingw"
|
||||
#X502API_INCLUDE_DIR = "/c/Program Files/L-Card/lpcie/include"
|
||||
|
||||
|
||||
#--- 64-битный вариант mingw w64, идущий вместе с cygwin --------
|
||||
#CC = x86_64-w64-mingw32-gcc
|
||||
#X502API_LIBRARIES_DIR = "/cygdrive/c/Program Files (x86)/L-Card/lpcie/lib/mingw64"
|
||||
#X502API_INCLUDE_DIR = "/cygdrive/c/Program Files (x86)/L-Card/lpcie/include"
|
||||
|
||||
#--- 32-битный вариант mingw w64, идущий вместе с cygwin --------
|
||||
#CC = i686-w64-mingw32-gcc
|
||||
#X502API_LIBRARIES_DIR = "/cygdrive/c/Program Files (x86)/L-Card/lpcie/lib/mingw"
|
||||
#X502API_INCLUDE_DIR = "/cygdrive/c/Program Files (x86)/L-Card/lpcie/include"
|
||||
|
||||
#--- 32-битный вариант mingw, идущий вместе с cygwin --------
|
||||
#CC = i686-pc-mingw32-gcc
|
||||
#X502API_LIBRARIES_DIR = "/cygdrive/c/Program Files (x86)/L-Card/lpcie/lib/mingw"
|
||||
#X502API_INCLUDE_DIR = "/cygdrive/c/Program Files (x86)/L-Card/lpcie/include"
|
||||
|
||||
|
||||
FLAGS =
|
||||
|
||||
ifdef X502API_LIBRARIES_DIR
|
||||
FLAGS += -L $(X502API_LIBRARIES_DIR)
|
||||
endif
|
||||
|
||||
ifdef X502API_INCLUDE_DIR
|
||||
FLAGS += -I $(X502API_INCLUDE_DIR)
|
||||
endif
|
||||
|
||||
|
||||
|
||||
all:
|
||||
$(CC) main.c $(FLAGS) -ll502api -le502api -lx502api -o x502_cycle_out
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "x502_cycle_out", "x502_cycle_out.vcproj", "{CA9882D8-F21E-47DD-87A6-44AD55ED0ED2}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{CA9882D8-F21E-47DD-87A6-44AD55ED0ED2}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{CA9882D8-F21E-47DD-87A6-44AD55ED0ED2}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{CA9882D8-F21E-47DD-87A6-44AD55ED0ED2}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{CA9882D8-F21E-47DD-87A6-44AD55ED0ED2}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,199 @@
|
||||
<?xml version="1.0" encoding="windows-1251"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="x502_cycle_out"
|
||||
ProjectGUID="{CA9882D8-F21E-47DD-87A6-44AD55ED0ED2}"
|
||||
RootNamespace="x502_cycle_out"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="c:\Program Files (x86)\L-Card\lpcie\include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="l502api.lib e502api.lib x502api.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="c:\Program Files (x86)\L-Card\lpcie\lib\msvc"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="c:\Program Files (x86)\L-Card\lpcie\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="l502api.lib e502api.lib x502api.lib"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="c:\Program Files (x86)\L-Card\lpcie\lib\msvc"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Ôàéëû èñõîäíîãî êîäà"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Çàãîëîâî÷íûå ôàéëû"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Ôàéëû ðåñóðñîâ"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\main.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -0,0 +1,29 @@
|
||||
# Данный файл описывает проект для системы сборки cmake.
|
||||
# С помощью cmake из этого файла можно получить нужный make-файл
|
||||
# для нужно родной системы сборки или проект для нужной среды.
|
||||
#
|
||||
# Для этого, из созданной директории для сборки нужно вызвать:
|
||||
#
|
||||
# cmake -DX502API_INCLUDE_DIR=<путь к заголовочным файлам x502api> -DX502API_LIBRARIES_DIR=<путь к файлу линкера x502api (.lib, .a или .so)> -G <имя генератора проекта> <путь к исходникам (данному файлу)>
|
||||
#
|
||||
# списко поддерживаемых генераторов можно получить вызвав cmake без аргументов
|
||||
#
|
||||
# Если заголовки и библиотека/файл линкера лежат в стандартных директориях,
|
||||
# то -DX502API_INCLUDE_DIR и -DX502API_LIBRARIES_DIR можно соответственно не указывать
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
set(PROJECT x502_stream_read)
|
||||
|
||||
project(${PROJECT} C)
|
||||
|
||||
set(SOURCES main.c)
|
||||
set(HEADERS )
|
||||
|
||||
include_directories(${X502API_INCLUDE_DIR} ../common)
|
||||
link_directories(${X502API_LIBRARIES_DIR})
|
||||
|
||||
add_executable(${PROJECT} ${HEADERS} ${SOURCES})
|
||||
|
||||
target_link_libraries(${PROJECT} x502api l502api e502api)
|
||||
@@ -0,0 +1,501 @@
|
||||
/* Данный пример представляет из себя консольную программу на языке C,
|
||||
демонстрирующую работу с модулями E16, L502 и E502 на примере синхронного
|
||||
ввода данных с АЦП и цифровых линий.
|
||||
|
||||
Перед сбором в примере идет поиск модулей, подключенных по интерфейсам PCI-Express и USB,
|
||||
и предоставляется список для выбора модуля, с которым нужно работать.
|
||||
Для подключения по Ethernet нужно указать IP-адреса интересующих модулей
|
||||
в качестве аргументов командной строки при вызове примера, тогда эти адреса
|
||||
будут добавлены в конец списка выбора модуля.
|
||||
Например, если интересуют модули с адресами 192.168.1.5 и 192.168.1.6,
|
||||
то пример можно вызвать:
|
||||
x502_stream_read 192.168.1.5 E16:192.168.1.6
|
||||
и две дополнительные строки с этими адресами появятся в списке выбора.
|
||||
Для указания что ip адрес принадлежит модулю E16, адрес надо указать с префиксом, пример: E16:192.168.1.6
|
||||
|
||||
Настройки частот, количества принимаемых данных и т.д. задаются с помощью макросов в
|
||||
начале программы.
|
||||
Настройки логических каналов - с помощью таблиц f_channels/f_ch_modes/f_ch_ranges.
|
||||
|
||||
Пример выполняет прием блоков данных заданного размера.
|
||||
Сбор идет до нажатия любой клавиши на Windows или CTRL+C на Linux.
|
||||
|
||||
Пример также показывает как выполнять обработку данных и определять начало кадра,
|
||||
в случае если в X502_ProcessData() передается не целое число кадров.
|
||||
|
||||
Данный пример содержит проект для Visual Studio 2008, а также может быть собран
|
||||
gcc в Linux или mingw в Windows через makefile или с помощью cmake (подробнее
|
||||
в комментариях в соответствующих файлах).
|
||||
|
||||
Для того чтобы собрать проект в Visual Studio, измените путь к заголовочным файлам
|
||||
(Проект (Project) -> Свойства (Properties) -> Свойства конфигурации (Configuration Properties)
|
||||
-> С/С++ -> Общие (General) -> Дополнительные каталоги включения (Additional Include Directories))
|
||||
на тот, где у вас лежат заголовочный файлы x502api.h, l502api.h и e502api.h и измените путь к библиотекам
|
||||
(Проект (Project) -> Свойства (Properties) -> Свойства конфигурации (Configuration Properties) ->
|
||||
Компановщик (Linker) -> Общие (General) -> Дополнительные катологи библиотек (Additional Library Directories)).
|
||||
|
||||
Внимание!!: Если Вы собираете проект под Visual Studio и взяли проект с сайта (а не из SDK),
|
||||
то для корректного отображения русских букв в программе нужно изменить кодировку
|
||||
или указать сохранение с сигнатурой кодировки для UTF-8:
|
||||
выберите Файл (File) -> Дополнительные параметры сохранения (Advanced Save Options)...
|
||||
и в поле Кодировка (Encoding) выберите Юникод (UTF8, с сигнатурой)/Unicode (UTF-8 with signature)
|
||||
и сохраните изменения в файле.
|
||||
|
||||
*/
|
||||
|
||||
#include <l502api.h>
|
||||
#include "e502api.h"
|
||||
//#include "dev_funcs.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <locale.h>
|
||||
#include <conio.h>
|
||||
#else
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* количество используемых логических каналов */
|
||||
#define ADC_LCH_CNT 3
|
||||
|
||||
/* частота сбора АЦП в Гц*/
|
||||
#define ADC_FREQ 500000
|
||||
/* частота кадров (на логический канал). При ADC_FREQ/ADC_LCH_CNT - межкадровой задержки нет */
|
||||
#define ADC_FRAME_FREQ (ADC_FREQ/ADC_LCH_CNT)
|
||||
/* частота синхронного ввода в Гц*/
|
||||
#define DIN_FREQ 500000
|
||||
|
||||
|
||||
#define TCP_CONNECTION_TOUT 5000
|
||||
|
||||
|
||||
/* сколько отсчетов считываем за блок */
|
||||
#define READ_BLOCK_SIZE 4096*200
|
||||
/* таймаут на прием блока (мс) */
|
||||
#define READ_TIMEOUT 2000
|
||||
|
||||
|
||||
/* номера используемых физических каналов */
|
||||
static uint32_t f_channels[ADC_LCH_CNT] = {0,4,6};
|
||||
/* режимы измерения для каналов */
|
||||
static uint32_t f_ch_modes[ADC_LCH_CNT] = {X502_LCH_MODE_DIFF, X502_LCH_MODE_DIFF, X502_LCH_MODE_DIFF};
|
||||
/* диапазоны измерения для каналов */
|
||||
static uint32_t f_ch_ranges[ADC_LCH_CNT] = {X502_ADC_RANGE_10, X502_ADC_RANGE_10, X502_ADC_RANGE_10};
|
||||
|
||||
|
||||
|
||||
/* признак необходимости завершить сбор данных */
|
||||
static int f_out = 0;
|
||||
|
||||
#ifndef _WIN32
|
||||
/* Обработчик сигнала завершения для Linux */
|
||||
static void f_abort_handler(int sig) {
|
||||
f_out = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
char const *DEV_E502 = "E502";
|
||||
char const *DEV_E16 = "E16";
|
||||
|
||||
typedef struct {
|
||||
uint32_t ip_addr;
|
||||
char const *devname;
|
||||
} ip_dev_list_t;
|
||||
|
||||
/* Функция находит все подключенные модули по интерфейсам PCI-Express и USB и
|
||||
* сохраняет записи о этих устройствах в выделенный массив.
|
||||
* Также создаются записи по переданным IP-адресам модулей и добавляются в конец
|
||||
* массива.
|
||||
* Указатель на выделенный массив, который должен быть потом очищен, сохраняется
|
||||
* в pdevrec_list, а количество действительных элементов (память которых должна
|
||||
* быть в дальнейшем освобождена с помощью X502_FreeDevRecordList()) возвращается
|
||||
* как результат функции */
|
||||
static uint32_t f_get_all_devrec(t_x502_devrec **pdevrec_list, ip_dev_list_t *ip_dev_list, unsigned ip_cnt) {
|
||||
int32_t fnd_devcnt = 0;
|
||||
uint32_t pci_devcnt = 0;
|
||||
uint32_t usb_devcnt = 0;
|
||||
uint32_t e16_usb_devcnt = 0;
|
||||
|
||||
t_x502_devrec *rec_list = NULL;
|
||||
|
||||
/* получаем количество подключенных устройств по интерфейсам PCI и USB */
|
||||
L502_GetDevRecordsList(NULL, 0, 0, &pci_devcnt);
|
||||
E502_UsbGetDevRecordsList(NULL, 0, 0, &usb_devcnt);
|
||||
E16_UsbGetDevRecordsList(NULL, 0, 0, &e16_usb_devcnt);
|
||||
|
||||
if ((pci_devcnt+usb_devcnt + e16_usb_devcnt + ip_cnt) != 0) {
|
||||
/* выделяем память для массива для сохранения найденного количества записей */
|
||||
rec_list = malloc((pci_devcnt + usb_devcnt +e16_usb_devcnt + ip_cnt) * sizeof(t_x502_devrec));
|
||||
|
||||
if (rec_list != NULL) {
|
||||
unsigned i;
|
||||
/* получаем записи о модулях L502, но не больше pci_devcnt */
|
||||
if (pci_devcnt!=0) {
|
||||
int32_t res = L502_GetDevRecordsList(&rec_list[fnd_devcnt], pci_devcnt, 0, NULL);
|
||||
if (res >= 0) {
|
||||
fnd_devcnt += res;
|
||||
}
|
||||
}
|
||||
/* добавляем записи о модулях E502, подключенных по USB, в конец массива */
|
||||
if (usb_devcnt!=0) {
|
||||
int32_t res = E502_UsbGetDevRecordsList(&rec_list[fnd_devcnt], usb_devcnt, 0, NULL);
|
||||
if (res >= 0) {
|
||||
fnd_devcnt += res;
|
||||
}
|
||||
}
|
||||
|
||||
/* добавляем записи о модулях E16, подключенных по USB, в конец массива */
|
||||
if (e16_usb_devcnt!=0) {
|
||||
int32_t res = E16_UsbGetDevRecordsList(&rec_list[fnd_devcnt], e16_usb_devcnt, 0, NULL);
|
||||
if (res >= 0) {
|
||||
fnd_devcnt += res;
|
||||
}
|
||||
}
|
||||
|
||||
/* создаем записи для переданного массива ip-адресов */
|
||||
for (i=0; i < ip_cnt; i++) {
|
||||
if (E502_MakeDevRecordByIpAddr2(&rec_list[fnd_devcnt], ip_dev_list[i].ip_addr, 0, TCP_CONNECTION_TOUT, ip_dev_list[i].devname) == X502_ERR_OK) {
|
||||
fnd_devcnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fnd_devcnt != 0) {
|
||||
/* если создана хотя бы одна запись, то сохраняем указатель на выделенный массив */
|
||||
*pdevrec_list = rec_list;
|
||||
} else {
|
||||
*pdevrec_list = NULL;
|
||||
free(rec_list);
|
||||
}
|
||||
|
||||
return fnd_devcnt;
|
||||
}
|
||||
|
||||
|
||||
static t_x502_hnd f_dev_select_open(int argc, char** argv) {
|
||||
t_x502_hnd hnd = NULL;
|
||||
uint32_t fnd_devcnt,i, dev_ind;
|
||||
t_x502_devrec *devrec_list = NULL;
|
||||
ip_dev_list_t *ip_dev_list = NULL;
|
||||
uint32_t ip_cnt = 0;
|
||||
|
||||
/* если есть аргументы командной строки, то предполагаем, что это могут быть
|
||||
ip-адреса интересующих устройств. */
|
||||
if (argc > 1) {
|
||||
ip_dev_list = malloc((argc - 1) * sizeof(ip_dev_list[0]));
|
||||
if (ip_dev_list == NULL) {
|
||||
fprintf(stderr, "Ошибка выделения памяти!\n");
|
||||
} else {
|
||||
for (i=1; (int)i < argc; i++) {
|
||||
int a[4];
|
||||
if (sscanf(argv[i], "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3])==4) {
|
||||
ip_dev_list[ip_cnt].devname = DEV_E502;
|
||||
ip_dev_list[ip_cnt++].ip_addr = ((a[0] & 0xFF) << 24) |
|
||||
((a[1] & 0xFF) << 16) |
|
||||
((a[2] & 0xFF) << 8) |
|
||||
(a[3] & 0xFF);
|
||||
} else
|
||||
if (sscanf(argv[i], "E16:%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3])==4) {
|
||||
ip_dev_list[ip_cnt].devname = DEV_E16;
|
||||
ip_dev_list[ip_cnt++].ip_addr = ((a[0] & 0xFF) << 24) |
|
||||
((a[1] & 0xFF) << 16) |
|
||||
((a[2] & 0xFF) << 8) |
|
||||
(a[3] & 0xFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* получаем список модулей для выбора */
|
||||
fnd_devcnt = f_get_all_devrec(&devrec_list, ip_dev_list, ip_cnt);
|
||||
|
||||
if (fnd_devcnt == 0) {
|
||||
printf("Не найдено ни одного модуля\n");
|
||||
} else {
|
||||
/* выводим информацию по списку модулей */
|
||||
printf("Доступны следующие модули:\n");
|
||||
for (i=0; i < fnd_devcnt; i++) {
|
||||
printf("Модуль № %d: %s, %-9s", i, devrec_list[i].devname,
|
||||
devrec_list[i].iface == X502_IFACE_PCI ? "PCI/PCIe" :
|
||||
devrec_list[i].iface == X502_IFACE_USB ? "USB" :
|
||||
devrec_list[i].iface == X502_IFACE_ETH ? "Ethernet" : "?");
|
||||
|
||||
/* при подключении по сети по IP-адресу серийный номер можно узнать
|
||||
только после открытия соединения. При этом поле location
|
||||
содержит строку с описанием адреса устройства */
|
||||
if (devrec_list[i].iface != X502_IFACE_ETH) {
|
||||
printf("Сер. номер: %s\n", devrec_list[i].serial);
|
||||
} else {
|
||||
printf("Адрес: %s\n", devrec_list[i].location);
|
||||
}
|
||||
}
|
||||
|
||||
/* выбираем нужный по введенному номеру модуля по порядку с клавиатуры */
|
||||
printf("Введите номер модуля, с которым хотите работать (от 0 до %d)\n", fnd_devcnt-1);
|
||||
fflush(stdout);
|
||||
scanf("%d", &dev_ind);
|
||||
|
||||
if (dev_ind >= fnd_devcnt) {
|
||||
printf("Неверно указан номер модуля...\n");
|
||||
} else {
|
||||
/* если ввели номер правильно - создаем описатель */
|
||||
hnd = X502_Create();
|
||||
if (hnd==NULL) {
|
||||
fprintf(stderr, "Ошибка создания описателя модуля!");
|
||||
} else {
|
||||
/* устанавливаем связь с модулем по записи */
|
||||
int32_t err = X502_OpenByDevRecord(hnd, &devrec_list[dev_ind]);
|
||||
if (err != X502_ERR_OK) {
|
||||
fprintf(stderr, "Ошибка установления связи с модулем: %s!", X502_GetErrorString(err));
|
||||
X502_Free(hnd);
|
||||
hnd = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* освобождение ресурсов действительных записей из списка */
|
||||
X502_FreeDevRecordList(devrec_list, fnd_devcnt);
|
||||
/* очистка памяти самого массива */
|
||||
free(devrec_list);
|
||||
}
|
||||
|
||||
/* освобождаем выделенный массив под IP-адреса (если был выделен) */
|
||||
free(ip_dev_list);
|
||||
|
||||
return hnd;
|
||||
}
|
||||
|
||||
|
||||
/* настройка параметров модуля */
|
||||
int32_t f_setup_params(t_x502_hnd hnd) {
|
||||
int32_t err = X502_ERR_OK, i;
|
||||
|
||||
/* устанавливаем параметры логической таблицы АЦП */
|
||||
err = X502_SetLChannelCount(hnd, ADC_LCH_CNT);
|
||||
for (i=0; (i < ADC_LCH_CNT) && (err == X502_ERR_OK); i++)
|
||||
err = X502_SetLChannel(hnd, i, f_channels[i], f_ch_modes[i], f_ch_ranges[i], 0);
|
||||
|
||||
/* устанавливаем частоты ввода для АЦП и цифровых входов */
|
||||
if (err == X502_ERR_OK) {
|
||||
double f_adc = ADC_FREQ, f_frame = ADC_FRAME_FREQ, f_din = DIN_FREQ;
|
||||
err = X502_SetAdcFreq(hnd, &f_adc, &f_frame);
|
||||
if (err == X502_ERR_OK)
|
||||
err = X502_SetDinFreq(hnd, &f_din);
|
||||
if (err == X502_ERR_OK) {
|
||||
/* выводим реально установленные значения - те что вернули функции */
|
||||
printf("Установлены частоты:\n Частота сбора АЦП = %0.0f\n"
|
||||
" Частота на лог. канал = %0.0f\n Частота цифрового ввода = %0.0f\n",
|
||||
f_adc, f_frame, f_din);
|
||||
}
|
||||
}
|
||||
|
||||
/* записываем настройки в модуль */
|
||||
if (err == X502_ERR_OK)
|
||||
err = X502_Configure(hnd, 0);
|
||||
|
||||
/* разрешаем синхронные потоки */
|
||||
if (err == X502_ERR_OK) {
|
||||
err = X502_StreamsEnable(hnd, X502_STREAM_ADC | X502_STREAM_DIN);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int32_t err = X502_ERR_OK;
|
||||
uint32_t ver;
|
||||
t_x502_hnd hnd = NULL;
|
||||
#ifndef _WIN32
|
||||
struct sigaction sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
/* В ОС Linux устанавливаем свой обработчик на сигнал закрытия,
|
||||
чтобы завершить сбор корректно */
|
||||
sa.sa_handler = f_abort_handler;
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
sigaction(SIGINT, &sa, NULL);
|
||||
sigaction(SIGABRT, &sa, NULL);
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
/* для вывода русских букв в консоль для ОС Windows в CP1251 без перевода в OEM */
|
||||
setlocale(LC_CTYPE, "");
|
||||
#endif
|
||||
/* получаем версию библиотеки */
|
||||
ver = X502_GetLibraryVersion();
|
||||
printf("Версия библиотеки: %d.%d.%d\n", (ver >> 24)&0xFF, (ver>>16)&0xFF, (ver>>8)&0xFF);
|
||||
|
||||
/********** Получение списка устройств и выбор, с каким будем работать ******************/
|
||||
hnd = f_dev_select_open(argc, argv);
|
||||
|
||||
/********************************** Работа с модулем **************************/
|
||||
/* если успешно выбрали модуль и установили с ним связь - продолжаем работу */
|
||||
if (hnd != NULL) {
|
||||
/* получаем информацию */
|
||||
t_x502_info info;
|
||||
err = X502_GetDevInfo(hnd, &info);
|
||||
if (err != X502_ERR_OK) {
|
||||
fprintf(stderr, "Ошибка получения серийного информации о модуле: %s!", X502_GetErrorString(err));
|
||||
} else {
|
||||
/* выводим полученную информацию */
|
||||
printf("Установлена связь со следующим модулем:\n");
|
||||
printf(" Серийный номер : %s\n", info.serial);
|
||||
printf(" Наличие ЦАП : %s\n", info.devflags & X502_DEVFLAGS_DAC_PRESENT ? "Да" : "Нет");
|
||||
printf(" Наличие BlackFin : %s\n", info.devflags & X502_DEVFLAGS_BF_PRESENT ? "Да" : "Нет");
|
||||
printf(" Наличие гальваноразвязки: %s\n", info.devflags & X502_DEVFLAGS_GAL_PRESENT ? "Да" : "Нет");
|
||||
printf(" Индустриальное исп. : %s\n", info.devflags & X502_DEVFLAGS_INDUSTRIAL ? "Да" : "Нет");
|
||||
printf(" Наличие интерф. PCI/PCIe: %s\n", info.devflags & X502_DEVFLAGS_IFACE_SUPPORT_PCI ? "Да" : "Нет");
|
||||
printf(" Наличие интерф. USB : %s\n", info.devflags & X502_DEVFLAGS_IFACE_SUPPORT_USB ? "Да" : "Нет");
|
||||
printf(" Наличие интерф. Ethernet: %s\n", info.devflags & X502_DEVFLAGS_IFACE_SUPPORT_ETH ? "Да" : "Нет");
|
||||
printf(" Версия ПЛИС : %d.%d\n", (info.fpga_ver >> 8) & 0xFF, info.fpga_ver & 0xFF);
|
||||
printf(" Версия PLDA : %d\n", info.plda_ver);
|
||||
if (info.mcu_firmware_ver != 0) {
|
||||
printf(" Версия прошивки ARM : %d.%d.%d.%d\n",
|
||||
(info.mcu_firmware_ver >> 24) & 0xFF,
|
||||
(info.mcu_firmware_ver >> 16) & 0xFF,
|
||||
(info.mcu_firmware_ver >> 8) & 0xFF,
|
||||
info.mcu_firmware_ver & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (err == X502_ERR_OK) {
|
||||
/* настраиваем параметры модуля */
|
||||
err = f_setup_params(hnd);
|
||||
if (err != X502_ERR_OK)
|
||||
fprintf(stderr, "Ошибка настройки модуля: %s!", X502_GetErrorString(err));
|
||||
}
|
||||
|
||||
|
||||
/* запуск синхронного ввода-вывода */
|
||||
if (err == X502_ERR_OK) {
|
||||
err = X502_StreamsStart(hnd);
|
||||
if (err != X502_ERR_OK)
|
||||
fprintf(stderr, "Ошибка запуска сбора данных: %s!\n", X502_GetErrorString(err));
|
||||
}
|
||||
|
||||
|
||||
if (err == X502_ERR_OK) {
|
||||
int block;
|
||||
int32_t stop_err;
|
||||
|
||||
printf("Сбор данных запущен. Для останова нажмите %s\n",
|
||||
#ifdef _WIN32
|
||||
"любую клавишу"
|
||||
#else
|
||||
"CTRL+C"
|
||||
#endif
|
||||
);
|
||||
fflush(stdout);
|
||||
|
||||
|
||||
|
||||
for (block = 0; (err == X502_ERR_OK) && !f_out; block++) {
|
||||
int32_t rcv_size;
|
||||
uint32_t adc_size, din_size;
|
||||
|
||||
/* массив для приема необработанных данных */
|
||||
static uint32_t rcv_buf[READ_BLOCK_SIZE];
|
||||
static double adc_data[READ_BLOCK_SIZE];
|
||||
static uint32_t din_data[READ_BLOCK_SIZE];
|
||||
|
||||
/* принимаем данные (по таймауту) */
|
||||
rcv_size = X502_Recv(hnd, rcv_buf, READ_BLOCK_SIZE, READ_TIMEOUT);
|
||||
/* результат меньше нуля означает ошибку */
|
||||
if (rcv_size < 0) {
|
||||
err = rcv_size;
|
||||
fprintf(stderr, "Ошибка приема данных: %s\n", X502_GetErrorString(err));
|
||||
} else if (rcv_size > 0) {
|
||||
uint32_t first_lch;
|
||||
/* получаем номер логического канала, которому соответствует первый отсчет АЦП в массиве */
|
||||
X502_GetNextExpectedLchNum(hnd, &first_lch);
|
||||
|
||||
adc_size = sizeof(adc_data)/sizeof(adc_data[0]);
|
||||
din_size = sizeof(din_data)/sizeof(din_data[0]);
|
||||
|
||||
/* обрабатываем принятые данные, распределяя их на данные АЦП и цифровых входов */
|
||||
err = X502_ProcessData(hnd, rcv_buf, rcv_size, X502_PROC_FLAGS_VOLT,
|
||||
adc_data, &adc_size, din_data, &din_size);
|
||||
if (err != X502_ERR_OK) {
|
||||
fprintf(stderr, "Ошибка обработки данных: %s\n", X502_GetErrorString(err));
|
||||
} else {
|
||||
uint32_t lch;
|
||||
|
||||
printf("Блок %3d. Обработано данных АЦП = %d, цифровых входов = %d\n",
|
||||
block, adc_size, din_size);
|
||||
/* если приняли цифровые данные - выводим первый отсчет */
|
||||
if (din_size != 0)
|
||||
printf(" din_data = 0x%05X\n", din_data[0]);
|
||||
|
||||
/* выводим по одному отсчету на канал. если обработанный блок
|
||||
начинается не с начала кадра, то в данном примере для
|
||||
вывода берем конец неполного кадра и начало следующего */
|
||||
for (lch=0; lch < ADC_LCH_CNT; lch++) {
|
||||
/* определяем позицию первого отсчета, соответствующего заданному логическому каналу:
|
||||
либо с конца не полного кадра, либо из начала следующего */
|
||||
uint32_t pos = lch >= first_lch ? lch - first_lch : ADC_LCH_CNT-first_lch + lch;
|
||||
if (pos <= adc_size) {
|
||||
printf(" lch[%d]=%6.4f\n", lch, adc_data[pos]);
|
||||
} else {
|
||||
printf(" lch[%d]= ---- \n", lch);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
#ifdef _WIN32
|
||||
/* проверка нажатия клавиши для выхода */
|
||||
if (err == X502_ERR_OK) {
|
||||
if (_kbhit())
|
||||
f_out = 1;
|
||||
}
|
||||
#else
|
||||
{
|
||||
// по нажатию Enter включаем/выключаем поток ADC
|
||||
fd_set fds;
|
||||
struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(STDIN_FILENO, &fds);
|
||||
if (select(1, &fds, NULL, NULL, &tv) == 1) {
|
||||
int x;
|
||||
static int adc_disabled = 0;
|
||||
int ch;
|
||||
|
||||
if (adc_disabled) {
|
||||
X502_StreamsEnable(hnd, X502_STREAM_ADC);
|
||||
} else {
|
||||
X502_StreamsDisable(hnd, X502_STREAM_ADC);
|
||||
}
|
||||
adc_disabled = !adc_disabled;
|
||||
|
||||
while(select(1, &fds, NULL, NULL, &tv) == 1) {
|
||||
read(STDIN_FILENO, &ch, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* останавливаем поток сбора данных (независимо от того, была ли ошибка) */
|
||||
stop_err = X502_StreamsStop(hnd);
|
||||
if (stop_err != X502_ERR_OK) {
|
||||
fprintf(stderr, "Ошибка останова сбора данных: %s\n", X502_GetErrorString(err));
|
||||
if (err == X502_ERR_OK)
|
||||
err = stop_err;
|
||||
} else {
|
||||
printf("Сбор данных остановлен успешно\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* закрываем связь с модулем */
|
||||
X502_Close(hnd);
|
||||
/* освобождаем описатель */
|
||||
X502_Free(hnd);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
# makefile для сборки примера с помощью компиляторов mingw (под Windows)
|
||||
# или GCC (под Linux). Необходимо определить 3 переменные:
|
||||
#
|
||||
# CC - имя команды для вызова компилятора
|
||||
# X502API_LIBRARIES_DIR - путь к файлм .a или .so библиотек l502api, e502api, x502api (если не стандартный)
|
||||
# X502API_INCLUDE_DIR - путь к заголовочным файлам l502api.h, e502api.h, x502api.h
|
||||
#
|
||||
# Ниже приведено несколько примеров в закоментированном виде
|
||||
|
||||
#--- Linux с заголовками и библиотекой в стандартных директориях: компилятор GCC
|
||||
#CC = gcc
|
||||
|
||||
#--- Вариант запуска из MSYS со стандартным 32-битным mingw
|
||||
#CC = gcc
|
||||
#X502API_LIBRARIES_DIR = "/c/Program Files/L-Card/lpcie/lib/mingw"
|
||||
#X502API_INCLUDE_DIR = "/c/Program Files/L-Card/lpcie/include"
|
||||
|
||||
|
||||
#--- 64-битный вариант mingw w64, идущий вместе с cygwin --------
|
||||
#CC = x86_64-w64-mingw32-gcc
|
||||
#X502API_LIBRARIES_DIR = "/cygdrive/c/Program Files (x86)/L-Card/lpcie/lib/mingw64"
|
||||
#X502API_INCLUDE_DIR = "/cygdrive/c/Program Files (x86)/L-Card/lpcie/include"
|
||||
|
||||
#--- 32-битный вариант mingw w64, идущий вместе с cygwin --------
|
||||
#CC = i686-w64-mingw32-gcc
|
||||
#X502API_LIBRARIES_DIR = "/cygdrive/c/Program Files (x86)/L-Card/lpcie/lib/mingw"
|
||||
#X502API_INCLUDE_DIR = "/cygdrive/c/Program Files (x86)/L-Card/lpcie/include"
|
||||
|
||||
#--- 32-битный вариант mingw, идущий вместе с cygwin --------
|
||||
#CC = i686-pc-mingw32-gcc
|
||||
#X502API_LIBRARIES_DIR = "/cygdrive/c/Program Files (x86)/L-Card/lpcie/lib/mingw"
|
||||
#X502API_INCLUDE_DIR = "/cygdrive/c/Program Files (x86)/L-Card/lpcie/include"
|
||||
|
||||
|
||||
FLAGS =
|
||||
|
||||
ifdef X502API_LIBRARIES_DIR
|
||||
FLAGS += -L $(X502API_LIBRARIES_DIR)
|
||||
endif
|
||||
|
||||
ifdef X502API_INCLUDE_DIR
|
||||
FLAGS += -I $(X502API_INCLUDE_DIR)
|
||||
endif
|
||||
|
||||
|
||||
|
||||
all:
|
||||
$(CC) main.c $(FLAGS) -ll502api -le502api -lx502api -o x502_stream_read
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "x502_stream_read", "x502_stream_read.vcproj", "{D9460CE1-B571-4A69-A4C1-0676BF57EB04}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{D9460CE1-B571-4A69-A4C1-0676BF57EB04}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{D9460CE1-B571-4A69-A4C1-0676BF57EB04}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{D9460CE1-B571-4A69-A4C1-0676BF57EB04}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{D9460CE1-B571-4A69-A4C1-0676BF57EB04}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,199 @@
|
||||
<?xml version="1.0" encoding="windows-1251"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="x502_stream_read"
|
||||
ProjectGUID="{D9460CE1-B571-4A69-A4C1-0676BF57EB04}"
|
||||
RootNamespace="x502_stream_read"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="c:\Program Files (x86)\L-Card\lpcie\include\"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="x502api.lib l502api.lib e502api.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="c:\Program Files (x86)\L-Card\lpcie\lib\msvc"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="c:\Program Files (x86)\L-Card\lpcie\include\"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="x502api.lib l502api.lib e502api.lib"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="c:\Program Files (x86)\L-Card\lpcie\lib\msvc"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Ôàéëû èñõîäíîãî êîäà"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\main.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Çàãîëîâî÷íûå ôàéëû"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Ôàéëû ðåñóðñîâ"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
Reference in New Issue
Block a user