manually merged with ARM version

This commit is contained in:
2025-11-13 17:43:55 +03:00
parent f978759ae0
commit 04015fb4cb
463 changed files with 119514 additions and 45 deletions

View File

@ -0,0 +1,7 @@
if(X502API_ENABLE_DEV_E502)
add_subdirectory(e502)
endif(X502API_ENABLE_DEV_E502)
if(X502API_ENABLE_DEV_L502)
add_subdirectory(l502)
endif(X502API_ENABLE_DEV_L502)

Binary file not shown.

View File

@ -0,0 +1,170 @@
cmake_minimum_required(VERSION 2.8.12)
project(e502api C)
set(PROJECT_VARNAME_PREFIX E502API)
option(E502API_ENABLE_USB "enable usb interface support" ON)
option(E502API_ENABLE_TCP "enable tcp interface support" ON)
option(E502API_ENABLE_DNSSD "enable dns-sd service discovery" ON)
set(OSSPEC_USE_MUTEX ON)
if(E502API_ENABLE_USB)
option(E502API_LIBUSB_DEBUG "Print debug messages from libusb" OFF)
if(WIN32)
option(LIBUSB_INTERNAL "use internal libusb realisation" ON)
endif(WIN32)
set(OSSPEC_USE_EVENTS ON)
set(OSSPEC_USE_THREADS ON)
else(E502API_ENABLE_USB)
set(OSSPEC_USE_EVENTS OFF)
set(OSSPEC_USE_THREADS OFF)
endif(E502API_ENABLE_USB)
if (E502API_ENABLE_DNSSD)
if(WIN32)
option(ENABLE_BONJOUR "enable bonjour support" ON)
else(WIN32)
option(ENABLE_AVAHI "enable avahi support" ON)
endif(WIN32)
endif(E502API_ENABLE_DNSSD)
include(${LTIMER_DIR}/ltimer.cmake)
include(${OSSPEC_DIR}/osspec.cmake)
set(E502API_COMPILE_DEFINITIONS ${E502API_COMPILE_DEFINITIONS} ${LTIMER_DEFINITIONS} ${OSSPEC_DEFINITIONS})
set(SOURCES
e502api_usb.c
e502api_tcp.c
e502api_dnssd.c
e502api.c
e502api_eth_config.c
${LTIMER_SOURCES}
${OSSPEC_SOURCES}
)
set(SETUP_HEADERS e502api.h)
set(HEADERS
${OSSPEC_HEADERS}
${LTIMER_HEADERS}
e502_fpga_regs.h
e502_cm4_defs.h
e502_eth_config.h
e502api_private.h
e502api_tcp_private.h
e502_tcp_protocol.h)
set(LIBS
x502api
${LTIMER_LIBS}
${OSSPEC_LIBS})
include_directories(${X502API_LIB_DIR}/osspec)
if (E502API_ENABLE_USB)
set(E502API_COMPILE_DEFINITIONS ${E502API_COMPILE_DEFINITIONS} ENABLE_USB)
if(E502API_LIBUSB_DEBUG)
set(E502API_COMPILE_DEFINITIONS ${E502API_COMPILE_DEFINITIONS} LIBUSB_DEBUG)
endif(E502API_LIBUSB_DEBUG)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/")
if(LIBUSB_INTERNAL)
include(CheckStructHasMember)
check_struct_has_member("struct timespec" tv_sec time.h HAVE_STRUCT_TIMESPEC LANGUAGE C)
if(HAVE_STRUCT_TIMESPEC)
add_definitions(-DHAVE_STRUCT_TIMESPEC)
endif(HAVE_STRUCT_TIMESPEC)
# использование внутренней реализации libusb, а не внешеней библиотеки
# используется под windows, так как стандартная версия c WinUSB драйвером
# имеет проблемны при отмене трансферов
include_directories(libusb-1.0 libusb-1.0/msvc)
set(SOURCES ${SOURCES}
libusb-1.0/core.c
libusb-1.0/descriptor.c
libusb-1.0/hotplug.c
libusb-1.0/io.c
libusb-1.0/strerror.c
libusb-1.0/sync.c
libusb-1.0/os/poll_windows.c
libusb-1.0/os/threads_windows.c
libusb-1.0/os/windows_usb.c
)
set(HEADERS ${HEADERS}
libusb-1.0/libusb.h
libusb-1.0/libusbi.h
libusb-1.0/hotplug.h
libusb-1.0/version.h
libusb-1.0/version_nano.h
libusb-1.0/os/poll_windows.h
libusb-1.0/os/threads_windows.h
libusb-1.0/os/windows_common.h
libusb-1.0/msvc/config.h
libusb-1.0/msvc/errno.h
libusb-1.0/msvc/inttypes.h
libusb-1.0/msvc/missing.h
libusb-1.0/msvc/stdint.h
)
else()
#ищем libusb-1.0
find_package(LibUSB REQUIRED)
include_directories(${LIBUSB_INCLUDE_DIR})
set(LIBS ${LIBS} ${LIBUSB_LIBRARIES})
endif()
endif(E502API_ENABLE_USB)
if(E502API_ENABLE_TCP)
set(E502API_COMPILE_DEFINITIONS ${E502API_COMPILE_DEFINITIONS} ENABLE_TCP)
if(WIN32)
#подключение библиотеки для работы с сокетами
set(LIBS ${LIBS} Ws2_32)
endif(WIN32)
endif(E502API_ENABLE_TCP)
if(E502API_ENABLE_DNSSD)
set(E502API_COMPILE_DEFINITIONS ${E502API_COMPILE_DEFINITIONS} ENABLE_DNSSD)
if(ENABLE_BONJOUR)
find_package(DNSSD REQUIRED)
include_directories(${DNSSD_INCLUDE_DIRS})
set(LIBS ${LIBS} ${DNSSD_LIBRARIES})
set(E502API_COMPILE_DEFINITIONS ${E502API_COMPILE_DEFINITIONS} ENABLE_BONJOUR)
endif(ENABLE_BONJOUR)
if(ENABLE_AVAHI)
find_package(Avahi REQUIRED)
include_directories(${AVAHI_INCLUDE_DIRS})
set(LIBS ${LIBS} ${AVAHI_LIBRARIES})
set(E502API_COMPILE_DEFINITIONS ${E502API_COMPILE_DEFINITIONS} ENABLE_AVAHI)
endif(ENABLE_AVAHI)
endif(E502API_ENABLE_DNSSD)
message("e502 libs: ${LIBS}")
include(${X502_LIBS_CMAKE_FILE})
if(UNIX)
if (E502API_ENABLE_USB)
if(NOT UDEV_RULES_DIR)
set(UDEV_RULES_DIR lib/udev/rules.d)
endif(NOT UDEV_RULES_DIR)
install(FILES e502.rules DESTINATION ${UDEV_RULES_DIR})
install(FILES e16.rules DESTINATION ${UDEV_RULES_DIR})
endif(E502API_ENABLE_USB)
endif(UNIX)

View File

@ -0,0 +1,9 @@
find_library(AVAHI_LIBRARY-COMMON NAMES avahi-common)
find_library(AVAHI_LIBRARY-CLIENT NAMES avahi-client)
find_path(AVAHI_INCLUDE_DIR avahi-client/publish.h)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Avahi DEFAULT_MSG AVAHI_LIBRARY-COMMON AVAHI_LIBRARY-CLIENT AVAHI_INCLUDE_DIR)
if(AVAHI_FOUND)
set(AVAHI_LIBRARIES ${AVAHI_LIBRARY-COMMON} ${AVAHI_LIBRARY-CLIENT})
set(AVAHI_INCLUDE_DIRS ${AVAHI_INCLUDE_DIR})
endif()

View File

@ -0,0 +1,64 @@
# - Try to find dnssd library from Bonjour SDK
# Once done this will define
#
# DNSSD_FOUND - system has dnssd library
# DNSSD_INCLUDE_DIRS - the dnssd include directory
# DNSSD_LIBRARIES - Link these to use dnssd library
if(WIN32)
cmake_policy(VERSION 3.2)
endif(WIN32)
if (DNSSD_INCLUDE_DIRS AND DNSSD_LIBRARIES)
# in cache already
set(DNSSD_FOUND TRUE)
message(STATUS "Found dnssd: ${DNSSD_LIBRARIES}, ${DNSSD_INCLUDE_DIRS}")
else (DNSSD_INCLUDE_DIRS AND DNSSD_LIBRARIES)
string(REGEX REPLACE "\\\\" "/" PROGFILES $ENV{PROGRAMFILES})
string(REGEX REPLACE "\\\\" "/" PROGFILESX86 $ENV{PROGRAMFILES\(x86\)})
set(DNSSD_SEARCH_DIRS "${PROGFILES}/Bonjour SDK" "${PROGFILESX86}/Bonjour SDK" ${BONJOUR_ROOT_DIR})
find_path(DNSSD_INCLUDE_DIRS dns_sd.h
PATHS ${DNSSD_SEARCH_DIRS}
PATH_SUFFIXES "Include"
)
if( CMAKE_SIZEOF_VOID_P EQUAL 4 )
set(DNSSD_LIBRARY_PATH_SUFFIX "Lib/Win32")
else()
set(DNSSD_LIBRARY_PATH_SUFFIX "Lib/x64")
endif()
find_library(DNSSD_LIBRARIES NAMES dnssd
PATHS ${DNSSD_SEARCH_DIRS}
PATH_SUFFIXES ${DNSSD_LIBRARY_PATH_SUFFIX}
)
set(CMAKE_REQUIRED_INCLUDES ${DNSSD_INCLUDE_DIRS})
set(CMAKE_REQUIRED_LIBRARIES ${DNSSD_LIBRARIES})
if(DNSSD_INCLUDE_DIRS AND DNSSD_LIBRARIES)
set(DNSSD_FOUND TRUE)
else (DNSSD_INCLUDE_DIRS AND DNSSD_LIBRARIES)
set(DNSSD_FOUND FALSE)
endif(DNSSD_INCLUDE_DIRS AND DNSSD_LIBRARIES)
if (DNSSD_FOUND)
if (NOT DNSSD_FIND_QUIETLY)
message(STATUS "Found dnssd: ${DNSSD_LIBRARIES}, ${DNSSD_INCLUDE_DIRS}")
endif (NOT DNSSD_FIND_QUIETLY)
else (DNSSD_FOUND)
if (DNSSD_FIND_REQUIRED)
message(FATAL_ERROR "dnssd not found!")
endif (DNSSD_FIND_REQUIRED)
endif (DNSSD_FOUND)
mark_as_advanced(DNSSD_INCLUDE_DIRS DNSSD_LIBRARIES)
endif (DNSSD_INCLUDE_DIRS AND DNSSD_LIBRARIES)

View File

@ -0,0 +1,65 @@
if (NOT FFTW3_FOUND)
if(WIN32)
cmake_policy(VERSION 3.2)
endif(WIN32)
if(WIN32)
string(REGEX REPLACE "\\\\" "/" PROGFILES $ENV{PROGRAMFILES})
string(REGEX REPLACE "\\\\" "/" PROGFILESX86 $ENV{PROGRAMFILES\(x86\)})
set(FFTW3_SEARCH_DIRS ${FFTW3_ROOT_DIR} ${PROGFILES} ${PROGFILES}/libs ${PROGFILESX86} ${PROGFILESX86}/libs)
set(FFTW3_SEARCH_INCLUDE_DIRS ${FFTW3_SEARCH_DIRS})
set(FFTW3_SEARCH_LIBRARY_DIRS ${FFTW3_SEARCH_DIRS})
set(FFTW3_SEARCH_INCLUDE_SUFFIX include libfftw3/include fftw3/include)
if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(FFTW3_SEARCH_LIBRARY_DEF_SUFFIX "msvc")
else(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(FFTW3_SEARCH_LIBRARY_DEF_SUFFIX "msvc64")
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
else("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(FFTW3_SEARCH_LIBRARY_DEF_SUFFIX "mingw")
else(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(FFTW3_SEARCH_LIBRARY_DEF_SUFFIX "mingw64")
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
endif("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
set(FFTW3_SEARCH_LIBRARY_SUFFIX "lib/${FFTW3_SEARCH_LIBRARY_DEF_SUFFIX}"
"libfftw3/lib/${FFTW3_SEARCH_LIBRARY_DEF_SUFFIX}"
"fftw3/lib/${FFTW3_SEARCH_LIBRARY_DEF_SUFFIX}")
else(WIN32)
find_package(PkgConfig QUIET)
pkg_check_modules(FFTW3_PKG QUIET libfftw3)
set(FFTW3_SEARCH_INCLUDE_DIRS ${FFTW3_PKG_INCLUDE_DIRS} include local/include)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(FFTW3_SEARCH_LIBRARY_DIRS lib local/lib lib/i386-linux-gnu)
else(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(FFTW3_SEARCH_LIBRARY_DIRS lib64 lib/x86_64-linux-gnu local/lib64)
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
endif(WIN32)
find_path(FFTW3_INCLUDE_DIR NAMES fftw3.h
PATHS
${FFTW3_SEARCH_INCLUDE_DIRS}
PATH_SUFFIXES ${FFTW3_SEARCH_INCLUDE_SUFFIX}
)
find_library(FFTW3_LIBRARY NAMES fftw3
PATHS
${FFTW3_SEARCH_LIBRARY_DIRS}
PATH_SUFFIXES ${FFTW3_SEARCH_LIBRARY_SUFFIX}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(FFTW3
REQUIRED_VARS FFTW3_INCLUDE_DIR FFTW3_LIBRARY
)
if(FFTW3_FOUND)
set(FFTW3_LIBRARIES ${FFTW3_LIBRARY})
set(FFTW3_INCLUDE_DIRS ${FFTW3_INCLUDE_DIR})
endif(FFTW3_FOUND)
endif (NOT FFTW3_FOUND)

View File

@ -0,0 +1,16 @@
# - Try to find libgpg-error
# Once done this will define
# GPGERROR_FOUND - System has libgpg-error
# GPGERROR_INCLUDE_DIRS - The libgpg-error include directories
# GPGERROR_LIBRARIES - The libraries needed to use libgpg-error
# GPGERROR_DEFINITIONS - Compiler switches required for using libgpg-error
find_path ( GPGERROR_INCLUDE_DIR gpg-error.h )
find_library ( GPGERROR_LIBRARY NAMES gpg-error)
set ( GPGERROR_LIBRARIES ${GPGERROR_LIBRARY} )
set ( GPGERROR_INCLUDE_DIRS ${GPGERROR_INCLUDE_DIR} )
include ( FindPackageHandleStandardArgs )
find_package_handle_standard_args ( libgpg-error DEFAULT_MSG GPGERROR_LIBRARY GPGERROR_INCLUDE_DIR )

View File

@ -0,0 +1,100 @@
# - Find LTRAPI library
# This module defines
# LTRAPI_INCLUDE_DIRS, where to find LTRAPI headers
# LTRAPI_LIBRARIES, the libraries needed to LTRAPI
# LTRAPI_FOUND, If false, do not try to use LTRAPI.
#
# Components: ltrapi, ltrXXXapi (xxx - module number)
#
# On Windows you can specify LTRAPI_ROOT_DIR for root dir of ltrapi installation (if not default)
if (NOT LTRAPI_FOUND)
if(WIN32)
cmake_policy(VERSION 3.2)
endif(WIN32)
#по-умолчанию ищем все компоненты
if(NOT LTRAPI_FIND_COMPONENTS)
set(LTRAPI_FIND_COMPONENTS ltrapi)
endif(NOT LTRAPI_FIND_COMPONENTS)
if(WIN32)
string(REGEX REPLACE "\\\\" "/" PROGFILES $ENV{PROGRAMFILES})
string(REGEX REPLACE "\\\\" "/" PROGFILESX86 $ENV{PROGRAMFILES\(x86\)})
set(LTRAPI_SEARCH_DIRS ${PROGFILES} ${PROGFILESX86} ${LTRAPI_ROOT_DIR})
set(LTRAPI_SEARCH_INCLUDE_DIRS ${LTRAPI_SEARCH_DIRS})
set(LTRAPI_SEARCH_LIBRARY_DIRS ${LTRAPI_SEARCH_DIRS})
set(LTRAPI_SEARCH_INCLUDE_SUFFIX L-Card)
if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LTRAPI_SEARCH_LIBRARY_DEF_SUFFIX "msvc")
else(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LTRAPI_SEARCH_LIBRARY_DEF_SUFFIX "msvc64")
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
else("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LTRAPI_SEARCH_LIBRARY_DEF_SUFFIX "mingw")
else(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LTRAPI_SEARCH_LIBRARY_DEF_SUFFIX "mingw64")
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
endif("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
set(LTRAPI_SEARCH_LIBRARY_SUFFIX "lib/${LTRAPI_SEARCH_LIBRARY_DEF_SUFFIX}"
"ltr/lib/${LTRAPI_SEARCH_LIBRARY_DEF_SUFFIX}"
"L-Card/ltr/lib/${LTRAPI_SEARCH_LIBRARY_DEF_SUFFIX}")
else(WIN32)
find_package(PkgConfig QUIET)
pkg_check_modules(LTRAPI_PKG QUIET libltrapi1)
set(LTRAPI_SEARCH_INCLUDE_DIRS ${LTRAPI_PKG_INCLUDE_DIRS} include local/include)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LTRAPI_SEARCH_LIBRARY_DIRS lib local/lib lib/i386-linux-gnu)
else(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LTRAPI_SEARCH_LIBRARY_DIRS lib64 lib/x86_64-linux-gnu local/lib64)
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
endif(WIN32)
foreach(LTRAPI_COMPONENT ${LTRAPI_FIND_COMPONENTS})
find_path(LTRAPI_${LTRAPI_COMPONENT}_INCLUDE_DIR NAMES ltr/include/${LTRAPI_COMPONENT}.h
PATHS
${LTRAPI_SEARCH_INCLUDE_DIRS}
PATH_SUFFIXES ${LTRAPI_SEARCH_INCLUDE_SUFFIX}
)
if (WIN32)
find_library(LTRAPI_${LTRAPI_COMPONENT}_LIBRARY NAMES ${LTRAPI_COMPONENT}
PATHS
${LTRAPI_SEARCH_LIBRARY_DIRS}
PATH_SUFFIXES ${LTRAPI_SEARCH_LIBRARY_SUFFIX}
NO_DEFAULT_PATH
)
else(WIN32)
find_library(LTRAPI_${LTRAPI_COMPONENT}_LIBRARY NAMES ${LTRAPI_COMPONENT}
PATHS
${LTRAPI_SEARCH_LIBRARY_DIRS}
PATH_SUFFIXES ${LTRAPI_SEARCH_LIBRARY_SUFFIX}
)
endif(WIN32)
if (LTRAPI_${LTRAPI_COMPONENT}_INCLUDE_DIR AND LTRAPI_${LTRAPI_COMPONENT}_LIBRARY)
set(LTRAPI_${LTRAPI_COMPONENT}_FOUND TRUE)
set(LTRAPI_COMPONENT_LIBRARIES ${LTRAPI_COMPONENT_LIBRARIES} ${LTRAPI_${LTRAPI_COMPONENT}_LIBRARY})
set(LTRAPI_COMPONENT_INCLUDE_DIRS ${LTRAPI_COMPONENT_INCLUDE_DIRS} ${LTRAPI_${LTRAPI_COMPONENT}_INCLUDE_DIR})
endif()
endforeach()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LTRAPI REQUIRED_VARS
LTRAPI_COMPONENT_LIBRARIES
LTRAPI_COMPONENT_INCLUDE_DIRS
HANDLE_COMPONENTS)
if(LTRAPI_FOUND)
set(LTRAPI_LIBRARIES ${LTRAPI_LIBRARY} ${LTRAPI_COMPONENT_LIBRARIES})
set(LTRAPI_INCLUDE_DIRS ${LTRAPI_INCLUDE_DIR} ${LTRAPI_COMPONENT_INCLUDE_DIRS})
set(LTRAPI_COMPILE_DEFINITIONS LTRAPI_DISABLE_COMPAT_DEFS)
endif(LTRAPI_FOUND)
endif (NOT LTRAPI_FOUND)

View File

@ -0,0 +1,66 @@
if (NOT LIBCBOR_FOUND)
if(WIN32)
cmake_policy(VERSION 3.2)
endif(WIN32)
if(WIN32)
string(REGEX REPLACE "\\\\" "/" PROGFILES $ENV{PROGRAMFILES})
string(REGEX REPLACE "\\\\" "/" PROGFILESX86 $ENV{PROGRAMFILES\(x86\)})
set(LIBCBOR_SEARCH_DIRS ${LIBCBOR_ROOT_DIR} ${PROGFILES} ${PROGFILES}/libs ${PROGFILESX86} ${PROGFILESX86}/libs)
set(LIBCBOR_SEARCH_INCLUDE_DIRS ${LIBCBOR_SEARCH_DIRS})
set(LIBCBOR_SEARCH_LIBRARY_DIRS ${LIBCBOR_SEARCH_DIRS})
set(LIBCBOR_SEARCH_INCLUDE_SUFFIX include libcbor/include cbor/include)
if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LIBCBOR_SEARCH_LIBRARY_DEF_SUFFIX "msvc")
else(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LIBCBOR_SEARCH_LIBRARY_DEF_SUFFIX "msvc64")
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
else("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LIBCBOR_SEARCH_LIBRARY_DEF_SUFFIX "mingw")
else(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LIBCBOR_SEARCH_LIBRARY_DEF_SUFFIX "mingw64")
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
endif("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
set(LIBCBOR_SEARCH_LIBRARY_SUFFIX "lib/${LIBCBOR_SEARCH_LIBRARY_DEF_SUFFIX}"
"libcbor/lib/${LIBCBOR_SEARCH_LIBRARY_DEF_SUFFIX}"
"cbor/lib/${LIBCBOR_SEARCH_LIBRARY_DEF_SUFFIX}")
else(WIN32)
find_package(PkgConfig QUIET)
pkg_check_modules(LIBCBOR_PKG QUIET libcbor)
set(LIBCBOR_SEARCH_INCLUDE_DIRS ${LIBCBOR_PKG_INCLUDE_DIRS} include local/include)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LIBCBOR_SEARCH_LIBRARY_DIRS lib local/lib lib/i386-linux-gnu)
else(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LIBCBOR_SEARCH_LIBRARY_DIRS lib64 lib/x86_64-linux-gnu local/lib64)
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
endif(WIN32)
find_path(LIBCBOR_INCLUDE_DIR NAMES cbor.h
PATHS
${LIBCBOR_SEARCH_INCLUDE_DIRS}
PATH_SUFFIXES ${LIBCBOR_SEARCH_INCLUDE_SUFFIX}
)
find_library(LIBCBOR_LIBRARY NAMES cbor libcbor liblibcbor
PATHS
${LIBCBOR_SEARCH_LIBRARY_DIRS}
PATH_SUFFIXES ${LIBCBOR_SEARCH_LIBRARY_SUFFIX}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LibCBOR
REQUIRED_VARS LIBCBOR_INCLUDE_DIR LIBCBOR_LIBRARY
)
if(LIBCBOR_FOUND)
set(LIBCBOR_LIBRARIES ${LIBCBOR_LIBRARY})
set(LIBCBOR_INCLUDE_DIRS ${LIBCBOR_INCLUDE_DIR})
endif(LIBCBOR_FOUND)
endif (NOT LIBCBOR_FOUND)

View File

@ -0,0 +1,48 @@
# - Find libusb-1.0 library
# This module defines
# LIBUSB_INCLUDE_DIR, where to find bluetooth.h
# LIBUSB_LIBRARIES, the libraries needed to use libusb-1.0.
# LIBUSB_FOUND, If false, do not try to use libusb-1.0.
#
# Copyright (c) 2009, Michal Cihar, <michal@cihar.com>
#
# vim: expandtab sw=4 ts=4 sts=4:
if (NOT LIBUSB_FOUND)
find_package(PkgConfig QUIET)
pkg_check_modules(LIBUSB_PKG QUIET libusb-1.0)
if( CMAKE_SIZEOF_VOID_P EQUAL 4 )
set(LIBUSB_SEARCH_PATH lib lib/i386-linux-gnu /usr/local/lib "c:/Program Files (x86)/libusb/MS32/static")
else()
set(LIBUSB_SEARCH_PATH lib64 lib/x86_64-linux-gnu /usr/local/lib64 "c:/Program Files (x86)/libusb/MS64/static")
endif()
find_path(LIBUSB_INCLUDE_DIR NAMES libusb-1.0/libusb.h
PATHS
${LIBUSB_PKG_INCLUDE_DIRS}
/usr/include
/usr/local/include
"c:/Program Files (x86)/libusb/include"
)
find_library(LIBUSB_LIBRARIES NAMES usb-1.0 libusb-1.0
PATHS
${LIBUSB_PKG_LIBRARY_DIRS}
/usr/lib
/usr/local/lib
${LIBUSB_SEARCH_PATH}
)
if(LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
set(LIBUSB_FOUND TRUE CACHE INTERNAL "libusb-1.0 found")
message(STATUS "Found libusb-1.0: ${LIBUSB_INCLUDE_DIR}, ${LIBUSB_LIBRARIES}")
else(LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
set(LIBUSB_FOUND FALSE CACHE INTERNAL "libusb-1.0 found")
message(STATUS "libusb-1.0 not found.")
endif(LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
mark_as_advanced(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARIES)
endif (NOT LIBUSB_FOUND)

View File

@ -0,0 +1,42 @@
# - Find libdaemon library
# This module defines
# LIBDAEMON_INCLUDE_DIRS, where to find libdaemon headers
# LIBDAEMON_LIBRARIES, the libraries needed to libdaemon
# LIBDAEMON_FOUND, If false, do not try to use libdaemon.
#
if(NOT LIBDAEMON_FOUND)
find_package(PkgConfig QUIET)
pkg_check_modules(LIBDAEMON_PKG QUIET libdaemon)
set(LIBDAEMON_SEARCH_INCLUDE_DIRS ${LIBDAEMON_PKG_INCLUDE_DIRS} include local/include)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LIBDAEMON_SEARCH_LIBRARY_DIRS lib local/lib lib/i386-linux-gnu)
else(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LIBDAEMON_SEARCH_LIBRARY_DIRS lib64 lib/x86_64-linux-gnu local/lib64)
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
find_path(LIBDAEMON_INCLUDE_DIR NAMES libdaemon/daemon.h
PATHS
${LIBDAEMON_SEARCH_INCLUDE_DIRS}
PATH_SUFFIXES
)
find_library(LIBDAEMON_LIBRARY NAMES daemon
PATHS
${LIBDAEMON_SEARCH_LIBRARY_DIRS}
PATH_SUFFIXES libdaemon
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LIBDAEMON
REQUIRED_VARS LIBDAEMON_INCLUDE_DIR LIBDAEMON_LIBRARY
)
if(LIBDAEMON_FOUND)
set(LIBDAEMON_LIBRARIES ${LIBDAEMON_LIBRARY})
set(LIBDAEMON_INCLUDE_DIRS ${LIBDAEMON_INCLUDE_DIR})
endif(LIBDAEMON_FOUND)
endif(NOT LIBDAEMON_FOUND)

View File

@ -0,0 +1,66 @@
find_path ( LIBGCRYPT_INCLUDE_DIR gcrypt.h )
find_library ( LIBGCRYPT_LIBRARY NAMES gcrypt )
if(WIN32)
cmake_policy(VERSION 3.2)
string(REGEX REPLACE "\\\\" "/" PROGFILES $ENV{PROGRAMFILES})
string(REGEX REPLACE "\\\\" "/" PROGFILESX86 $ENV{PROGRAMFILES\(x86\)})
set(LIBGCRYPT_SEARCH_DIRS ${LIBGCRYPT_ROOT_DIR} ${PROGFILES} ${PROGFILES}/libs ${PROGFILESX86} ${PROGFILESX86}/libs)
set(LIBGCRYPT_SEARCH_INCLUDE_DIRS ${LIBGCRYPT_SEARCH_DIRS})
set(LIBGCRYPT_SEARCH_LIBRARY_DIRS ${LIBGCRYPT_SEARCH_DIRS})
set(LIBGCRYPT_SEARCH_INCLUDE_SUFFIX include libgcrypt/include gcrypt/include)
if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LIBGCRYPT_SEARCH_LIBRARY_DEF_SUFFIX "msvc")
else(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LIBGCRYPT_SEARCH_LIBRARY_DEF_SUFFIX "msvc64")
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
else("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LIBGCRYPT_SEARCH_LIBRARY_DEF_SUFFIX "mingw")
else(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LIBGCRYPT_SEARCH_LIBRARY_DEF_SUFFIX "mingw64")
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
endif("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
set(LIBGCRYPT_SEARCH_LIBRARY_SUFFIX "lib/${LIBGCRYPT_SEARCH_LIBRARY_DEF_SUFFIX}"
"libgcrypt/lib/${LIBGCRYPT_SEARCH_LIBRARY_DEF_SUFFIX}"
"gcrypt/lib/${LIBGCRYPT_SEARCH_LIBRARY_DEF_SUFFIX}")
else(WIN32)
find_package(PkgConfig QUIET)
pkg_check_modules(LIBGCRYPT_PKG QUIET libgcrypt)
set(LIBGCRYPT_SEARCH_INCLUDE_DIRS ${LIBGCRYPT_PKG_INCLUDE_DIRS} include local/include)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LIBGCRYPT_SEARCH_LIBRARY_DIRS lib local/lib lib/i386-linux-gnu)
else(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LIBGCRYPT_SEARCH_LIBRARY_DIRS lib64 lib/x86_64-linux-gnu local/lib64)
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
endif(WIN32)
find_path(LIBGCRYPT_INCLUDE_DIR NAMES gcrypt.h
PATHS
${LIBGCRYPT_SEARCH_INCLUDE_DIRS}
PATH_SUFFIXES ${LIBGCRYPT_SEARCH_INCLUDE_SUFFIX}
)
find_library(LIBGCRYPT_LIBRARY NAMES gcrypt
PATHS
${LIBGCRYPT_SEARCH_LIBRARY_DIRS}
PATH_SUFFIXES ${LIBGCRYPT_SEARCH_LIBRARY_SUFFIX}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Libgcrypt
REQUIRED_VARS LIBGCRYPT_LIBRARY LIBGCRYPT_INCLUDE_DIR
)
if(LIBGCRYPT_FOUND)
set(LIBGCRYPT_LIBRARIES ${LIBGCRYPT_LIBRARY})
set(LIBGCRYPT_INCLUDE_DIRS ${LIBGCRYPT_INCLUDE_DIR})
endif(LIBGCRYPT_FOUND)

View File

@ -0,0 +1,173 @@
# базовая директория может быть задана с помощью переменной cmake MKL_ROOT (самый высокий приоритет)
# или с помощью переменной окружения MKL_ROOT.
# Если MKL_ROOT не задан, то ищет в стандартных путях:
# на Windows в Program Files или Program Files (x86) в директории Intel/oneAPI/mkl/latest
# на Linux в штатных путях (в корне или /usr)
#
# использует tbb threading model, соглашение ILP64 на 64 битах, cdecl на 32
# (при необходимости можно добавить опции...)
# можно задать пользовательскую версию библитеки
# (если создана своя версия с подможеством функций с помощью intel compiler):
# MKL_CUSTOM_LIBRARY_NAME - имя библиотеки
# MKL_CUSTOM_LIBRARY_DIR - путь к пользовательской библиотеки без lib/<сиффикс> (может быть вне MKL_ROOT)
# Заголовочные файлы в этом случае сперва ищутся в ${MKL_CUSTOM_LIBRARY_DIR}/include, а затем уже внутри MKL_ROOT
# в первую очередь пытаемся найти mkl с помощью pkgconfig, если применимо
if (NOT MKL_FOUND)
if(NOT WIN32 AND NOT MKL_CUSTOM_LIBRARY_NAME AND NOT MKL_ROOT)
find_package(PkgConfig QUIET)
if(PkgConfig_FOUND)
#ищем среди разных реализаций потоков в порядке приоритета
pkg_check_modules(MKL QUIET mkl-dynamic-ilp64-tbb)
if (NOT MKL_FOUND)
pkg_check_modules(MKL QUIET mkl-dynamic-ilp64-iomp)
endif(NOT MKL_FOUND)
if (NOT MKL_FOUND)
pkg_check_modules(MKL QUIET mkl-dynamic-ilp64-seq)
endif(NOT MKL_FOUND)
endif(PkgConfig_FOUND)
endif()
endif(NOT MKL_FOUND)
# если не нашли через PkgConfig, то ищмем самостоятельно
if (NOT MKL_FOUND)
macro(MKL_FIND_LIBRARY LIB_VAR LIB_FILE_NAME)
find_library(${LIB_VAR} NAMES ${LIB_FILE_NAME}
PATHS
${MKL_SEARCH_LIBRARY_DIRS}
PATH_SUFFIXES ${MKL_SEARCH_LIBRARY_DIR_SUFFIX}
)
get_filename_component(LIB_DIR ${${LIB_VAR}} DIRECTORY)
get_filename_component(LIB_NAME ${${LIB_VAR}} NAME)
if (${LIB_DIR} IN_LIST MKL_LIBRARY_DIRS)
else()
set(MKL_LIBRARY_DIRS ${MKL_LIBRARY_DIRS} ${LIB_DIR})
endif()
set(MKL_REQIRED_LIBS ${MKL_REQIRED_LIBS} ${LIB_VAR})
endmacro()
if(WIN32)
cmake_policy(VERSION 3.2)
# в переменных окружения могут быть пути с разделителем \.
# если пыти с разными разделителями, то могут быть проблемы, поэтому переводим
# все к /
if(NOT MKL_ROOT)
set(set MKL_ROOT $ENV{MKLROOT})
endif(NOT MKL_ROOT)
if(MKL_ROOT)
string(REGEX REPLACE "\\\\" "/" MKL_ROOT MKL_ROOT)
endif(MKL_ROOT)
string(REGEX REPLACE "\\\\" "/" PROGFILES $ENV{PROGRAMFILES})
string(REGEX REPLACE "\\\\" "/" PROGFILESX86 $ENV{PROGRAMFILES\(x86\)})
if(MKL_ROOT)
set(MKL_SEARCH_DIRS ${MKL_ROOT})
else(MKL_ROOT)
set(MKL_WINSTD_DIR "Intel/oneAPI/mkl/latest")
set(MKL_SEARCH_DIRS "${PROGFILES}/${MKL_WINSTD_DIR}" "${PROGFILESX86}/${MKL_WINSTD_DIR}")
endif(MKL_ROOT)
set(MKL_SEARCH_INCLUDE_DIRS ${MKL_SEARCH_DIRS})
set(MKL_SEARCH_LIBRARY_DIRS ${MKL_SEARCH_DIRS})
set(MKL_SEARCH_INCLUDE_DIR_SUFFIX include)
if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(MKL_SEARCH_LIBRARY_DEF_SUFFIX "ia32_win")
else(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(MKL_SEARCH_LIBRARY_DEF_SUFFIX "intel64_win")
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
endif("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
set(MKL_SEARCH_LIBRARY_DIR_SUFFIX "lib/${MKL_SEARCH_LIBRARY_DEF_SUFFIX}")
#todo возможно сделать опцию, static или dll
set(MKL_LIB_FILE_SUFFIX "_dll")
else(WIN32)
if(NOT MKL_ROOT)
set(MKL_ROOT $ENV{MKLROOT})
endif(NOT MKL_ROOT)
if (MKL_ROOT)
set(MKL_SEARCH_INCLUDE_DIRS ${MKL_ROOT}/include)
else(MKL_ROOT)
set(MKL_SEARCH_INCLUDE_DIRS include local/include)
endif(MKL_ROOT)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
if (MKL_ROOT)
set(MKL_SEARCH_LIBRARY_DIRS ${MKL_ROOT}/lib)
else (MKL_ROOT)
set(MKL_SEARCH_LIBRARY_DIRS lib local/lib lib/i386-linux-gnu)
endif(MKL_ROOT)
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
if (MKL_ROOT)
set(MKL_SEARCH_LIBRARY_DIRS ${MKL_ROOT}/lib64 ${MKL_ROOT}/lib/intel64)
else(MKL_ROOT)
set(MKL_SEARCH_LIBRARY_DIRS lib64 lib/x86_64-linux-gnu local/lib64)
endif(MKL_ROOT)
#взято из готового примера - проверить необходимость
set(ABI "-m64")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ABI}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ABI}")
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
endif(WIN32)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
#todo возможно сделать опцию выбора между ILP64 и LP64 (MKL_LONG 64 или 32)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DMKL_ILP64")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMKL_ILP64")
endif(CMAKE_SIZEOF_VOID_P EQUAL 8)
if(MKL_CUSTOM_LIBRARY_DIR)
set(MKL_SEARCH_INCLUDE_DIRS ${MKL_CUSTOM_LIBRARY_DIR} ${MKL_SEARCH_INCLUDE_DIRS})
endif(MKL_CUSTOM_LIBRARY_DIR)
find_path(MKL_INCLUDE_DIR NAMES mkl.h
PATHS
${MKL_SEARCH_INCLUDE_DIRS}
PATH_SUFFIXES ${MKL_SEARCH_INCLUDE_DIR_SUFFIX}
)
if (NOT MKL_CUSTOM_LIBRARY_NAME)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
MKL_FIND_LIBRARY(MKL_INTERFACE_LIBRARY mkl_intel_c${MKL_LIB_FILE_SUFFIX})
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
MKL_FIND_LIBRARY(MKL_INTERFACE_LIBRARY mkl_intel_ilp64${MKL_LIB_FILE_SUFFIX})
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
MKL_FIND_LIBRARY(MKL_CORE_LIBRARY mkl_core${MKL_LIB_FILE_SUFFIX})
MKL_FIND_LIBRARY(MKL_THREAD_LIBRARY mkl_tbb_thread${MKL_LIB_FILE_SUFFIX})
if(NOT WIN32)
MKL_FIND_LIBRARY(MKL_TBB_LIBRARY tbb)
endif(NOT WIN32)
else(NOT MKL_CUSTOM_LIBRARY_NAME)
set(MKL_SEARCH_LIBRARY_DIRS ${MKL_SEARCH_LIBRARY_DIRS} ${MKL_CUSTOM_LIBRARY_DIR})
MKL_FIND_LIBRARY(MKL_CUSTOM_LIBRARY ${MKL_CUSTOM_LIBRARY_NAME})
endif(NOT MKL_CUSTOM_LIBRARY_NAME)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MKL
REQUIRED_VARS MKL_INCLUDE_DIR ${MKL_REQIRED_LIBS}
)
if(MKL_FOUND)
foreach(MKL_LIB ${MKL_REQIRED_LIBS})
set(MKL_LIBRARIES ${MKL_LIBRARIES} ${${MKL_LIB}})
endforeach()
set(MKL_INCLUDE_DIRS ${MKL_INCLUDE_DIR})
endif(MKL_FOUND)
endif()

View File

@ -0,0 +1,55 @@
# - Try to find libmodbus
# Once done this will define
#
# MODBUS_FOUND - system has MODBUS
# MODBUS_INCLUDE_DIRS - the MODBUS include directory
# MODBUS_LIBRARIES - Link these to use MODBUS
# Copyright (c) 2006, Jasem Mutlaq <mutlaqja@ikarustech.com>
# Based on FindLibfacile by Carsten Niehaus, <cniehaus@gmx.de>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
if (MODBUS_INCLUDE_DIRS AND MODBUS_LIBRARIES)
# in cache already
set(MODBUS_FOUND TRUE)
message(STATUS "Found libmodbus: ${MODBUS_LIBRARIES}")
else (MODBUS_INCLUDE_DIRS AND MODBUS_LIBRARIES)
find_path(MODBUS_INCLUDE_DIRS modbus.h
PATH_SUFFIXES modbus
${_obIncDir}
${GNUWIN32_DIR}/include
)
find_library(MODBUS_LIBRARIES NAMES modbus
PATHS
${_obLinkDir}
${GNUWIN32_DIR}/lib
)
set(CMAKE_REQUIRED_INCLUDES ${MODBUS_INCLUDE_DIRS})
set(CMAKE_REQUIRED_LIBRARIES ${MODBUS_LIBRARIES})
if(MODBUS_INCLUDE_DIRS AND MODBUS_LIBRARIES)
set(MODBUS_FOUND TRUE)
else (MODBUS_INCLUDE_DIRS AND MODBUS_LIBRARIES)
set(MODBUS_FOUND FALSE)
endif(MODBUS_INCLUDE_DIRS AND MODBUS_LIBRARIES)
if (MODBUS_FOUND)
if (NOT MODBUS_FIND_QUIETLY)
message(STATUS "Found libmodbus: ${MODBUS_LIBRARIES}")
endif (NOT MODBUS_FIND_QUIETLY)
else (MODBUS_FOUND)
if (MODBUS_FIND_REQUIRED)
message(FATAL_ERROR "libmodbus not found. Please install libmodbus from http://libmodbus.org/")
endif (MODBUS_FIND_REQUIRED)
endif (MODBUS_FOUND)
mark_as_advanced(MODBUS_INCLUDE_DIRS MODBUS_LIBRARIES)
endif (MODBUS_INCLUDE_DIRS AND MODBUS_LIBRARIES)

View File

@ -0,0 +1,110 @@
# - Find x502api library
# This module defines
# X502API_INCLUDE_DIRS, where to find x502api headers
# X502API_LIBRARIES, the libraries needed to x502api
# X502API_FOUND, If false, do not try to use x502api.
#
# Components: l502api e502api (all enabled if not specified)
#
# On Windows you can specify LPCIE_ROOT_DIR for root dir of lpcie (if not default)
if (NOT X502API_FOUND)
if(WIN32)
cmake_policy(VERSION 3.2)
endif(WIN32)
set(X502API_SUPPORTED_COMPONENTS x502api l502api e502api)
#по-умолчанию ищем все компоненты
if(NOT X502API_FIND_COMPONENTS)
set(X502API_FIND_COMPONENTS ${X502API_SUPPORTED_COMPONENTS})
else(NOT X502API_FIND_COMPONENTS)
set(X502API_FIND_COMPONENTS x502api ${X502API_FIND_COMPONENTS})
endif(NOT X502API_FIND_COMPONENTS)
if(WIN32)
string(REGEX REPLACE "\\\\" "/" PROGFILES $ENV{PROGRAMFILES})
string(REGEX REPLACE "\\\\" "/" PROGFILESX86 $ENV{PROGRAMFILES\(x86\)})
set(X502API_SEARCH_DIRS ${PROGFILES} ${PROGFILESX86} ${LPCIE_ROOT_DIR})
set(X502API_SEARCH_INCLUDE_DIRS ${X502API_SEARCH_DIRS})
set(X502API_SEARCH_LIBRARY_DIRS ${X502API_SEARCH_DIRS})
set(X502API_SEARCH_INCLUDE_SUFFIX L-Card/lpcie/include include)
if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(X502API_SEARCH_LIBRARY_DEF_SUFFIX "msvc")
else(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(X502API_SEARCH_LIBRARY_DEF_SUFFIX "msvc64")
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
else("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(X502API_SEARCH_LIBRARY_DEF_SUFFIX "mingw")
else(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(X502API_SEARCH_LIBRARY_DEF_SUFFIX "mingw64")
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
endif("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
set(X502API_SEARCH_LIBRARY_SUFFIX "lib/${X502API_SEARCH_LIBRARY_DEF_SUFFIX}"
"L-Card/lpcie/lib/${X502API_SEARCH_LIBRARY_DEF_SUFFIX}")
else(WIN32)
find_package(PkgConfig QUIET)
pkg_check_modules(X502API_PKG QUIET libx502api1)
set(X502API_SEARCH_INCLUDE_DIRS ${X502API_PKG_INCLUDE_DIRS} include local/include)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(X502API_SEARCH_LIBRARY_DIRS lib local/lib lib/i386-linux-gnu)
else(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(X502API_SEARCH_LIBRARY_DIRS lib64 lib/x86_64-linux-gnu local/lib64)
endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
endif(WIN32)
foreach(X502API_COMPONENT ${X502API_FIND_COMPONENTS})
list(FIND X502API_SUPPORTED_COMPONENTS ${X502API_COMPONENT} X502API_COMPONENT_IDX)
if(${X502API_COMPONENT_IDX}_IDX EQUAL -1)
message(WARNING "x502api: unsupported component ${X502API_COMPONENT}")
else()
find_path(X502API_${X502API_COMPONENT}_INCLUDE_DIR NAMES ${X502API_COMPONENT}.h
PATHS
${X502API_SEARCH_INCLUDE_DIRS}
PATH_SUFFIXES ${X502API_SEARCH_INCLUDE_SUFFIX}
)
if (WIN32)
find_library(X502API_${X502API_COMPONENT}_LIBRARY NAMES ${X502API_COMPONENT}
PATHS
${X502API_SEARCH_LIBRARY_DIRS}
PATH_SUFFIXES ${X502API_SEARCH_LIBRARY_SUFFIX}
NO_DEFAULT_PATH
)
else(WIN32)
find_library(X502API_${X502API_COMPONENT}_LIBRARY NAMES ${X502API_COMPONENT}
PATHS
${X502API_SEARCH_LIBRARY_DIRS}
PATH_SUFFIXES ${X502API_SEARCH_LIBRARY_SUFFIX}
)
endif(WIN32)
if (X502API_${X502API_COMPONENT}_INCLUDE_DIR AND X502API_${X502API_COMPONENT}_LIBRARY)
set(X502API_${X502API_COMPONENT}_FOUND TRUE)
set(X502API_COMPONENT_LIBRARIES ${X502API_COMPONENT_LIBRARIES} ${X502API_${X502API_COMPONENT}_LIBRARY})
set(X502API_COMPONENT_INCLUDE_DIRS ${X502API_COMPONENT_INCLUDE_DIRS} ${X502API_${X502API_COMPONENT}_INCLUDE_DIR})
endif()
endif()
endforeach()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(X502API REQUIRED_VARS
X502API_COMPONENT_LIBRARIES
X502API_COMPONENT_INCLUDE_DIRS
HANDLE_COMPONENTS)
if(X502API_FOUND)
set(X502API_LIBRARIES ${X502API_LIBRARY} ${X502API_COMPONENT_LIBRARIES})
set(X502API_INCLUDE_DIRS ${X502API_INCLUDE_DIR} ${X502API_COMPONENT_INCLUDE_DIRS})
endif(X502API_FOUND)
endif (NOT X502API_FOUND)

View File

@ -0,0 +1,52 @@
# - Try to find libmodbus
# Once done this will define
#
# XLSXWRITER_FOUND - system has XLSXWRITER
# XLSXWRITER_INCLUDE_DIRS - the XLSXWRITER include directory
# XLSXWRITER_LIBRARIES - Link these to use XLSXWRITER
# Copyright (c) 2006, Jasem Mutlaq <mutlaqja@ikarustech.com>
# Based on FindLibfacile by Carsten Niehaus, <cniehaus@gmx.de>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
if (XLSXWRITER_INCLUDE_DIRS AND XLSXWRITER_LIBRARIES)
# in cache already
set(XLSXWRITER_FOUND TRUE)
message(STATUS "Found libxlsxwriter: ${XLSXWRITER_LIBRARIES}")
else (XLSXWRITER_INCLUDE_DIRS AND XLSXWRITER_LIBRARIES)
find_path(XLSXWRITER_INCLUDE_DIRS xlsxwriter.h
PATH_SUFFIXES xlsxwriter
${_obIncDir}
${GNUWIN32_DIR}/include
)
find_library(XLSXWRITER_LIBRARIES NAMES xlsxwriter
PATHS
${_obLinkDir}
${GNUWIN32_DIR}/lib
)
set(CMAKE_REQUIRED_INCLUDES ${XLSXWRITER_INCLUDE_DIRS})
set(CMAKE_REQUIRED_LIBRARIES ${XLSXWRITER_LIBRARIES})
if(XLSXWRITER_INCLUDE_DIRS AND XLSXWRITER_LIBRARIES)
set(XLSXWRITER_FOUND TRUE)
else (XLSXWRITER_INCLUDE_DIRS AND XLSXWRITER_LIBRARIES)
set(XLSXWRITER_FOUND FALSE)
endif(XLSXWRITER_INCLUDE_DIRS AND XLSXWRITER_LIBRARIES)
if (XLSXWRITER_FOUND)
if (NOT XLSXWRITER_FIND_QUIETLY)
message(STATUS "Foud llibxlsxwriter: ${XLSXWRITER_LIBRARIES}")
endif (NOT XLSXWRITER_FIND_QUIETLY)
else (XLSXWRITER_FOUND)
if (XLSXWRITER_FIND_REQUIRED)
message(FATAL_ERROR "llibxlsxwriter not found.")
endif (XLSXWRITER_FIND_REQUIRED)
endif (XLSXWRITER_FOUND)
mark_as_advanced(XLSXWRITER_INCLUDE_DIRS XLSXWRITER_LIBRARIES)
endif (XLSXWRITER_INCLUDE_DIRS AND XLSXWRITER_LIBRARIES)

View File

@ -0,0 +1,17 @@
# - Try to find ZMQ
# Once done this will define
# ZMQ_FOUND - System has ZMQ
# ZMQ_INCLUDE_DIRS - The ZMQ include directories
# ZMQ_LIBRARIES - The libraries needed to use ZMQ
# ZMQ_DEFINITIONS - Compiler switches required for using ZMQ
find_path ( ZMQ_INCLUDE_DIR zmq.h )
find_library ( ZMQ_LIBRARY NAMES zmq )
set ( ZMQ_LIBRARIES ${ZMQ_LIBRARY} )
set ( ZMQ_INCLUDE_DIRS ${ZMQ_INCLUDE_DIR} )
include ( FindPackageHandleStandardArgs )
# handle the QUIETLY and REQUIRED arguments and set ZMQ_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args ( ZMQ DEFAULT_MSG ZMQ_LIBRARY ZMQ_INCLUDE_DIR )

View File

@ -0,0 +1 @@
SUBSYSTEM=="usb", ATTRS{idVendor}=="2a52", ATTRS{idProduct}=="0e16", MODE="0666"

View File

@ -0,0 +1 @@
SUBSYSTEM=="usb", ATTRS{idVendor}=="2a52", ATTRS{idProduct}=="e502", MODE="0666"

View File

@ -0,0 +1,164 @@
#ifndef E502_LPC_CMD_DEFS_H
#define E502_LPC_CMD_DEFS_H
#define E502_CM4_SUPPORT_OUT_CYCLE_SETUP_CHECK(ver) (ver >= 0x01000200)
/***************************************************************************//**
@addtogroup e502proto_defs Определения протокола обмена с модулем E502
@{
*******************************************************************************/
/** Коды ошибок, возвращаемые модулем при завершении управляющей команды */
typedef enum {
E502_CM4_ERR_OK = 0, /**< Команда выполнена успешно */
E502_CM4_ERR_FPGA_NSTATUS_TOUT = -1001, /**< При загрузке ПЛИС не удалось дождаться сигнала перехода в режим загрузки */
E502_CM4_ERR_FPGA_CONF_DONE_TOUT = -1002, /**< При загрузке ПЛИС не удалось дождаться сигнала завершения загрузки */
E502_CM4_ERR_FPGA_FW_NOT_PRESENT = -1003, /**< Не обнаружена прошивка ПЛИС во flash-памяти модуля */
E502_CM4_ERR_FPGA_REG_NACK = -1004, /**< Обращение к регистру ПЛИС вернуло ответ NACK */
E502_CM4_ERR_FPGA_REG_ERROR = -1005, /**< Обращение к регистру ПЛИС вернуло ответ ERROR */
E502_CM4_ERR_FPGA_REG_WT_TOUT = -1006, /**< Не удалось дожлаться ответ на обращение к регистру ПЛИС */
E502_CM4_ERR_TEST_INVALID_NUM = -1007, /**< Неподдерживаемый номер теста */
E502_CM4_ERR_HARD_FAULT = -1007, /**< Восстановление после hard fault */
E502_CM4_ERR_TEST_VALUE_MISMATH = -1008, /**< Несовпадение ожидаемых значений при проходе теста */
E502_CM4_ERR_TEST_NOT_RUNNING = -1009, /**< Тест не запущен */
E502_CM4_ERR_TEST_ALREADY_RUNNING = -1010, /**< Tест уже запщен */
E502_CM4_ERR_BF_LDR_FILE_SIZE = -1011, /**< Не удалось найти конец файла прошивки BlackFin */
E502_CM4_ERR_LDR_FILE_FORMAT = -1012, /**< Неверный формат файла прошивки BlackFin */
/** Используются возможность LDR-файла, недоступные при записи прошивки
BlackFin по HDMA */
E502_CM4_ERR_LDR_FILE_UNSUP_FEATURE = -1013,
/** Неверный стартовый адрес программы в прошивке BlackFin */
E502_CM4_ERR_LDR_FILE_UNSUP_STARTUP_ADDR = -1014,
/** Истек таймаут выполнения запроса на чтения/запись памяти BlackFin */
E502_CM4_ERR_BF_REQ_TIMEOUT = -1015,
/** Команда для BlackFin все еще находится в процессе обработки */
E502_CM4_ERR_BF_CMD_IN_PROGRESS = -1016,
/** Истекло время выполнения управляющей команды процессором BlackFin */
E502_CM4_ERR_BF_CMD_TIMEOUT = -1017,
/** Возвращено недостаточно данных в ответ на команду к BlackFin */
E502_CM4_ERR_BF_CMD_RETURN_INSUF_DATA = -1018,
/** Истек таймаут ожидания готовности процессора BlackFin к записи прошивки */
E502_CM4_ERR_BF_LOAD_RDY_TOUT = -1019,
/** Попытка выполнить операцию для которой нужен сигнальный процессор при
отсутствии сигнального процессора в модуле */
E502_CM4_ERR_BF_NOT_PRESENT = -1020,
/** Неверный адрес памяти BlackFin при записи или чтении по HDMA */
E502_CM4_ERR_BF_INVALID_ADDR = -1021,
/** Неверный размер данных, передаваемых с управляющей командой в BlackFin */
E502_CM4_ERR_BF_INVALID_CMD_DATA_SIZE = -1022,
E502_CM4_ERR_UNKNOWN_CMD = -1023, /**< Неподдерживаемый код команды */
E502_CM4_ERR_INVALID_CMD_PARAMS = -1024, /**< Неверные параметры переданной команды */
E502_CM4_ERR_FIRM_BUF_OVERFLOW = -1025, /**< Переполнение буфера для приема прошивки */
E502_CM4_ERR_CMD_SIGNATURE = -1026, /**< Неверный признак начала команды */
E502_CM4_ERR_INVALID_CMD_DATA_SIZE = -1027, /**< Неверное количество данных в команде */
E502_CM4_ERR_FLASH_PROT_CODE = -1028, /**< Неверный код настройки защиты Flash-памяти */
E502_CM4_ERR_FLASH_OP = -1029, /**< Ошибка выполнения операции с Flash-памятью */
E502_CM4_ERR_FLASH_DATA_COMPARE = -1030, /**< Ошибка сравнения записанных данных во Flash-память */
E502_CM4_ERR_INVALID_PASSWORD = -1031, /**< Неверный пароль для изменения сетевых настроек */
E502_CM4_ERR_FPGA_NOT_LOADED = -1032, /**< ПЛИС не был загружен */
E502_CM4_ERR_FLASH_SET_PROT_BITS = -1033, /**< Не удалось изменить занчения битов защиты Flash-памяти */
E502_CM4_ERR_FPGA_FW_INVALID_TEMP_RANGE = -1034, /**< Загруженная прошивка ПЛИС предназначена для другого темп. исполнения */
E502_CM4_ERR_M0_STREAM_START_REQ = -1035, /**< Нет ответа на запрос запуска потока от ядра Cortex-M0 */
E502_CM4_ERR_M0_STREAM_STOP_REQ = -1036, /**< Нет ответа на запрос останова потока от ядра Cortex-M0 */
E502_CM4_ERR_OUT_STREAM_RUNNING = -1037, /**< Уже запущен вывод в потоковом режиме */
E502_CM4_ERR_OUT_NO_CYCLE_BUF = -1038, /**< Нет свободного буфера для циклического режима. Не произошла смена страниц */
E502_CM4_ERR_OUT_CYCLE_BUF_SIZE = -1039, /**< Задан слишком большой размер циклического буфера */
E502_CM4_ERR_OUT_CYCLE_NOT_LOADED = -1040, /**< Не был полностью загружен циклический буфер перед сменой */
} t_e502_cm4_errs;
/** @} */
typedef enum {
E502_STREAM_CH_IN = 0,
E502_STREAM_CH_OUT = 1
} t_e502_stream_ch;
typedef enum {
E502_IFACE_USB = 0,
E502_IFACE_TCP = 1
} t_e502_ifaces;
/** Коды команды протокола обмена с модулем E502 */
typedef enum {
E502_CM4_CMD_GET_USB_SPEED = 6,
E502_CM4_CMD_GET_MODULE_NAME = 11,
E502_CM4_CMD_BOOT = 0x0F,
E502_CM4_CMD_FPGA_REG_READ = 0x10,
E502_CM4_CMD_FPGA_REG_WRITE = 0x11,
E502_CM4_CMD_STREAM_START = 0x12,
E502_CM4_CMD_STREAM_STOP = 0x13,
E502_CM4_CMD_STREAM_SET_STEP = 0x14,
E502_CM4_CMD_STREAM_IS_RUNNING = 0x15,
E502_CM4_CMD_FIRM_BUF_WRITE = 0x16,
E502_CM4_CMD_FLASH_RD = 0x17,
E502_CM4_CMD_FLASH_WR = 0x18,
E502_CM4_CMD_FLASH_ERASE = 0x19,
E502_CM4_CMD_FLASH_SET_PROTECT = 0x1A,
E502_CM4_CMD_FLASH_RELOAD_INFO = 0x1B,
E502_CM4_CMD_ETH_CFG_SET = 0x1C,
E502_CM4_CMD_ETH_CFG_GET = 0x1D,
E502_CM4_CMD_BF_MEM_WRITE = 0x20,
E502_CM4_CMD_BF_MEM_READ = 0x21,
E502_CM4_CMD_BF_FIRM_LOAD = 0x22,
E502_CM4_CMD_DROP_DATA_CON = 0x23,
E502_CM4_CMD_RELOAD_FPGA = 0x24,
E502_CM4_CMD_GET_DEVFLAGS = 0x25,
E502_CM4_CMD_OUT_CYCLE_LOAD = 0x26,
E502_CM4_CMD_OUT_CYCLE_SETUP = 0x27,
E502_CM4_CMD_OUT_CYCLE_STOP = 0x28,
E502_CM4_CMD_OUT_CYCLE_SETUP_CHECK = 0x29,
E502_CM4_CMD_TEST_START = 0x40,
E502_CM4_CMD_TEST_STOP = 0x41,
E502_CM4_CMD_TEST_GET_STATE = 0x42,
E502_CM4_CMD_GET_MODULE_INFO = 0x80,
E502_CM4_CMD_GET_MODULE_MODE = 0x81,
E502_CM4_CMD_GET_LAST_ERROR = 0x82
} t_e502_cm4_cmd_codes;
/** @internal */
typedef enum {
E502_CM4_TEST_NONE=0,
E502_CM4_TEST_SRAM_BUF_RING,
E502_CM4_TEST_SRAM_SDRAM_RING_DMA,
E502_CM4_TEST_USB_TX_CNTR,
E502_CM4_TEST_USB_RING,
E502_CM4_TEST_SPI_SLAVE,
E502_CM4_TEST_SDRAM,
E502_CM4_TEST_ETH_PHY_LOOPBACK,
E502_CM4_TEST_DAC_CNTR,
E502_CM4_TEST_GD_SDIO,
E502_CM4_TEST_DCI_CNTR,
E502_CM4_TEST_FPGA_RING
} t_test_number;
/** @internal */
/** Параметры теста */
typedef struct {
uint32_t test; /**< Номер выполняемого теста */
uint32_t run; /**< Признак, запущен ли сейчас тест */
uint32_t stage; /**< Этап выполнения теста */
uint32_t cntr; /**< Счетчик - сколько раз прошел тест */
int32_t err; /**< Код ошибки выполнения теста */
uint32_t last_addr; /**< Последний используемый адрес */
uint32_t last_wr; /**< Последнее записанное значение */
uint32_t last_rd; /**< Последнее считанное значение */
} t_e502_cm4_test_state;
#endif // E502_LPC_CMD_DEFS_H

View File

@ -0,0 +1,51 @@
#ifndef E502_ETH_CONFIG_H
#define E502_ETH_CONFIG_H
#define E502_ETHCONFIG_MAC_ADDR_SIZE 6
#define E502_ETHCONFIG_INSTANCE_NAME_SIZE 64
#define E502_ETHCONFIG_PASSWD_SIZE 32
#define E502_IPV4_ADDR_SIZE 4
typedef enum {
E502_ETH_FLAGS_IFACE_ENABLED = 0x0001,
E502_ETH_FLAGS_AUTO_IP = 0x0002,
E502_ETH_FLAGS_USER_MAC = 0x0004,
E502_ETH_FLAGS_ADDR_ESTABLISHED = 0x0008, /* адрес, выделенный DHCP-сервером, проверен */
E502_ETH_FLAGS_AUTO_IP_STATE_MASK = E502_ETH_FLAGS_ADDR_ESTABLISHED,
} t_e502_eth_flags;
typedef struct {
uint8_t addr[E502_IPV4_ADDR_SIZE];
uint8_t mask[E502_IPV4_ADDR_SIZE];
uint8_t gate[E502_IPV4_ADDR_SIZE];
} t_e502_ipv4_config;
typedef struct {
uint32_t format;
uint32_t flags;
char inst_name[E502_ETHCONFIG_INSTANCE_NAME_SIZE];
uint8_t mac[E502_ETHCONFIG_MAC_ADDR_SIZE];
t_e502_ipv4_config ipv4;
uint16_t tcp_cmd_port;
uint16_t tcp_data_port;
} t_e502_eth_config;
typedef enum {
E502_ETH_CONFIG_FLAGS_SET_NEW_PASSWD = 0x0001
} t_e502_eth_config_flags;
typedef struct {
char passwd[E502_ETHCONFIG_PASSWD_SIZE];
char new_passwd[E502_ETHCONFIG_PASSWD_SIZE];
t_e502_eth_config cfg;
} t_e502_eth_set_config_params;
#define E502_ETHCONFIG_SET_HDR_SIZE offsetof(t_e502_eth_set_config_params, cfg)
#endif // E502_ETH_CONFIG_H

View File

@ -0,0 +1,208 @@
#ifndef E502_FPGA_REGS_H
#define E502_FPGA_REGS_H
//#ifndef L5XX_REGS_H
//#define L5XX_REGS_H
#define E502_MAX_PAGES_CNT 252
#define E502_BF_SDRAM_SIZE (32UL*1024*1024)
#define E502_BF_MEMADDR_CMD 0xFF800800
#define E502_BF_CMD_READ 0x0001
#define E502_BF_CMD_WRITE 0x0002
#define E502_BF_CMD_HIRQ 0x0004
#define E502_BF_CMD_HDMA_RST 0x0008
#define RING_MODE(a) (a << 2)
// Разрешение синхронного потока цифрового вывода
#define SYN_DIGOUT_EN (1 << 0)
//Разрешение синхронного потока ЦАП1
#define SYN_DAC1_EN (1 << 1)
//Разрешение синхронного потока ЦАП2
#define SYN_DAC2_EN (1 << 2)
#define DCI_TEST_MODE (1)
#define clk125_fail (1 << 0)
#define clk125_lock (1 << 1)
#define slv_clk_pll_fail (1 << 2)
#define slv_clk_pll_lock (1 << 3)
#define adcbuf_empty_err (1 << 4)
#define adcbuf_full_err (1 << 5)
#define dacbuf_empty_err (1 << 6)
#define dacbuf_full_err (1 << 7)
#define gd32_sdio_crc_err (1 << 8)
#define dac_buf_chan_extra_err (1 << 9)
#define dac_buf_chan_extra_err1 (1 << 10)
#define dacbuf_rst_done_err (1 << 11)
#define adcbuf_rst_done_err (1 << 12)
#define ch_sdio_size_req_err (1 << 14)
#define gd_sdio_size_req_err (1 << 15)
#define ch32_sdio_crc_err (1 << 16)
/********************* Адреса регистров блока ARM_INTERFACE *******************/
#define E502_REGS_ARM_BLOCK 0x0100
#define E502_REGS_ARM_DMA (E502_REGS_ARM_BLOCK+0)
#define E502_REGS_ARM_FPGA_ERR (E502_REGS_ARM_BLOCK+1)
#define E502_REGS_ARM_DAC_ERR (E502_REGS_ARM_BLOCK+3)
#define DIGOUT_ERROR (1 << 0)
#define DAC1_ERROR (1 << 2)
#define DAC2_ERROR (1 << 4)
#define E502_REGS_ARM_VERSION (E502_REGS_ARM_BLOCK + 2)
#define E502_REGS_ARM_HARD_ID (E502_REGS_ARM_BLOCK + 0xA)
#define E502_REGS_ARM_DEBUG_REG (E502_REGS_ARM_BLOCK + 0xB)
#define E502_REGS_ARM_DAC_CH_EN (E502_REGS_ARM_BLOCK + 0xD)
#define E502_REGS_ARM_TIME_CTRL (E502_REGS_ARM_BLOCK + 0x10)
#define E502_REGS_ARM_TIME_SEC (E502_REGS_ARM_BLOCK + 0x11)
#define E502_REGS_ARM_TIME_SSEC (E502_REGS_ARM_BLOCK + 0x12)
#define E502_REGS_ARM_TIME_ADJ (E502_REGS_ARM_BLOCK + 0x13)
#define E502_REGS_ARM_FLASHSIZE (E502_REGS_ARM_BLOCK + 0x14)
/********************* Адреса регистров блока IOHARD **************************/
#define E502_REGS_IOHARD_BLOCK 0x0200
//Адрес Control Table
#define E502_REGS_IOHARD_LTABLE (E502_REGS_IOHARD_BLOCK+0)
#define E502_REGS_IOHARD_LTABLE_MAX_SIZE 0x100 // Максимальный размер Control Table
#define E502_REGS_IOHARD_LCH_CNT (E502_REGS_IOHARD_BLOCK+0x100)
#define E502_REGS_IOHARD_ADC_FREQ_DIV (E502_REGS_IOHARD_BLOCK+0x102)
#define E502_REGS_IOHARD_ADC_FRAME_DELAY (E502_REGS_IOHARD_BLOCK+0x104)
#define E502_REGS_IOHARD_DIGIN_FREQ_DIV (E502_REGS_IOHARD_BLOCK+0x106)
#define E502_REGS_IOHARD_IO_MODE (E502_REGS_IOHARD_BLOCK+0x108)
#define E502_REGS_IOHARD_GO_SYNC_IO (E502_REGS_IOHARD_BLOCK+0x10A)
#define E502_REGS_IOHARD_PRELOAD_ADC (E502_REGS_IOHARD_BLOCK+0x10C)
#define E502_REGS_IOHARD_DAC_FLUSH (E502_REGS_IOHARD_BLOCK+0x110)
#define E502_REGS_IOHARD_ASYNC_OUT (E502_REGS_IOHARD_BLOCK+0x112)
#define E502_REGS_IOHARD_LED (E502_REGS_IOHARD_BLOCK+0x114)
#define E502_REGS_IOHARD_DIGIN_PULLUP (E502_REGS_IOHARD_BLOCK+0x116)
#define E502_REGS_IOHARD_OUTSWAP_BFCTL (E502_REGS_IOHARD_BLOCK+0x118)
#define E502_REGS_IOHARD_OUTSWAP_ERROR (E502_REGS_IOHARD_BLOCK+0x120)
/********************* Адреса регистров блока IOARITH **************************/
#define E502_REGS_IOARITH_BLOCK 0x0400
#define E502_REGS_IOARITH_B10 E502_REGS_IOARITH_BLOCK
#define E502_REGS_IOARITH_B5 (E502_REGS_IOARITH_BLOCK+0x01)
#define E502_REGS_IOARITH_B2 (E502_REGS_IOARITH_BLOCK+0x02)
#define E502_REGS_IOARITH_B1 (E502_REGS_IOARITH_BLOCK+0x03)
#define E502_REGS_IOARITH_B05 (E502_REGS_IOARITH_BLOCK+0x04)
#define E502_REGS_IOARITH_B02 (E502_REGS_IOARITH_BLOCK+0x05)
#define E502_REGS_IOARITH_K10 (E502_REGS_IOARITH_BLOCK+0x08)
#define E502_REGS_IOARITH_K5 (E502_REGS_IOARITH_BLOCK+0x09)
#define E502_REGS_IOARITH_K2 (E502_REGS_IOARITH_BLOCK+0x0A)
#define E502_REGS_IOARITH_K1 (E502_REGS_IOARITH_BLOCK+0x0B)
#define E502_REGS_IOARITH_K05 (E502_REGS_IOARITH_BLOCK+0x0C)
#define E502_REGS_IOARITH_K02 (E502_REGS_IOARITH_BLOCK+0x0D)
#define E502_REGS_IOARITH_ADC_FREQ_DIV (E502_REGS_IOARITH_BLOCK+0x12)
#define E502_REGS_IOARITH_THRESHOLD (E502_REGS_IOARITH_BLOCK+0x15)
#define E502_REGS_IOARITH_N_CHAN_SYN (E502_REGS_IOARITH_BLOCK+0x16)
#define E502_REGS_IOARITH_IN_STREAM_ENABLE (E502_REGS_IOARITH_BLOCK+0x19)
#define E502_REGS_IOARITH_DIN_ASYNC (E502_REGS_IOARITH_BLOCK+0x1A)
/********************* Адреса регистров блока CMD **************************/
#define E502_REGS_CMD_BLOCK 0x0600
/********************* Адреса регистров блока управления BlackFin'ом **********/
#define E502_REGS_BF_CTL_BLOCK 0
#define E502_REGS_BF_CTL (E502_REGS_BF_CTL_BLOCK+0)
#define E502_REGS_BF_CMD (E502_REGS_BF_CTL_BLOCK+1)
#define E502_REGS_BF_STATUS (E502_REGS_BF_CTL_BLOCK+2)
#define E502_REGS_BF_IRQ (E502_REGS_BF_CTL_BLOCK+3)
#define E502_REGS_BF_IRQ_EN (E502_REGS_BF_CTL_BLOCK+4)
#define E502_REGS_BF_REQ_ADDR (E502_REGS_BF_CTL_BLOCK+5)
#define E502_REGS_BF_REQ_SIZE (E502_REGS_BF_CTL_BLOCK+6)
#define E502_REGS_BF_REQ_DATA (E502_REGS_BF_CTL_BLOCK+128)
#define E502_BF_REQ_DATA_SIZE_MAX 128
#define E502_BF_REQ_DATA_SIZE_MIN 8
/********************* Адреса служебных регистров контроллера **************************/
#define E502_REGS_ARM_SRV_BLOCK 0x0700
#define E502_REGS_ARM_CH_UID (E502_REGS_ARM_SRV_BLOCK + 0)
#define E502_REGS_ARM_GD_UID (E502_REGS_ARM_CH_UID + 3)
#define E502_REGS_PTP_LOCK_LIMIT (E502_REGS_ARM_GD_UID + 3)
#define E502_REGS_PINS_DEVID (E502_REGS_PTP_LOCK_LIMIT + 1)
/* описание отдельных битов регистров */
#define E502_REGBIT_ARM_DMA_ADC_BUF_CLR_Pos 0
#define E502_REGBIT_ARM_DMA_ADC_BUF_CLR_Msk (1UL << E502_REGBIT_ARM_DMA_ADC_BUF_CLR_Pos)
#define E502_REGBIT_ARM_DMA_DAC_BUF_CLR_Pos 1
#define E502_REGBIT_ARM_DMA_DAC_BUF_CLR_Msk (1UL << E502_REGBIT_ARM_DMA_DAC_BUF_CLR_Pos)
#define E502_REGBIT_ARM_DMA_RING_MODE_Pos 2
#define E502_REGBIT_ARM_DMA_RING_MODE_Msk (1UL << E502_REGBIT_ARM_DMA_RING_MODE_Pos)
#define E502_REGBIT_BF_STATUS_HWAIT_Pos 0
#define E502_REGBIT_BF_STATUS_HWAIT_Msk (1UL << E502_REGBIT_BF_STATUS_HWAIT_Pos)
#define E502_REGBIT_BF_STATUS_BUSY_Pos 1
#define E502_REGBIT_BF_STATUS_BUSY_Msk (1UL << E502_REGBIT_BF_STATUS_BUSY_Pos)
#define E502_REGBIT_BF_CTL_BF_RESET_Pos 1
#define E502_REGBIT_BF_CTL_BF_RESET_Msk (0x1UL << E502_REGBIT_BF_CTL_BF_RESET_Pos)
#define E502_REGBIT_BF_CTL_HOST_WAIT_Pos 3
#define E502_REGBIT_BF_CTL_HOST_WAIT_Msk (0x1UL << E502_REGBIT_BF_CTL_HOST_WAIT_Pos)
#define E502_REGBIT_BF_CTL_DSP_MODE_Pos 4
#define E502_REGBIT_BF_CTL_DSP_MODE_Msk (0x1UL << E502_REGBIT_BF_CTL_DSP_MODE_Pos)
#define E502_REGBIT_BF_CTL_DBG_MODE_Pos 5
#define E502_REGBIT_BF_CTL_DBG_MODE_Msk (0x1UL << E502_REGBIT_BF_CTL_DBG_MODE_Pos)
#define E502_REGBIT_BF_CTL_CLK_DIV_Pos 8
#define E502_REGBIT_BF_CTL_CLK_DIV_Msk (0xFUL << E502_REGBIT_BF_CTL_CLK_DIV_Pos)
#define E502_REGBIT_ADC_SLV_CLK_LOCK_Pos 31
#define E502_REGBIT_ADC_SLV_CLK_LOCK_Msk (0x1UL << E502_REGBIT_ADC_SLV_CLK_LOCK_Pos)
#define E502_REGBIT_IOHARD_OUT_SWAP_Pos 0
#define E502_REGBIT_IOHARD_OUT_SWAP_Msk (0x1UL << E502_REGBIT_IOHARD_OUT_SWAP_Pos)
#define E502_REGBIT_IOHARD_OUT_TFS_EN_Pos 1
#define E502_REGBIT_IOHARD_OUT_TFS_EN_Msk (0x1UL << E502_REGBIT_IOHARD_OUT_TFS_EN_Pos)
#define E502_REGBIT_IOHARD_OUT_RING_Pos 2
#define E502_REGBIT_IOHARD_OUT_RING_Msk (0x1UL << E502_REGBIT_IOHARD_OUT_RING_Pos)
#define E502_REGBIT_IOHARD_OUT_RFS_EN_Pos 3
#define E502_REGBIT_IOHARD_OUT_RFS_EN_Msk (0x1UL << E502_REGBIT_IOHARD_OUT_RFS_EN_Pos)
#define E502_REGBIT_DMA_IRQ_STEP_Msk(ch) (1UL << ch)
#define E502_REGBIT_DMA_IRQ_PAGE_Msk(ch) (1UL << (ch+8))
#define E502_REGBIT_DMA_IRQ_FLUSH_Msk(ch) (1UL << (ch+16))
//#endif // L5XX_REGS_H
#endif // E502_FPGA_REGS_H

View File

@ -0,0 +1,37 @@
#ifndef E502_TCP_PROTOCOL_H
#define E502_TCP_PROTOCOL_H
//значения сигнатуры, которое является признаком действительной команды или ответа
#define E502_TCP_CMD_SIGNATURE 0x314C5443
//заголово команды
typedef struct {
uint32_t sign;
uint32_t cmd; //код команды (реально используются 0-255)
uint32_t par; //параметр (соответствует value и index в usb)
uint32_t data_len; //кол-во данных на передачу в байтах
uint32_t resp_len; //кол-во ожидаем данных на прием в байтах
} t_e502_tcp_cmd_hdr;
//заголовок ответа
typedef struct {
uint32_t sign;
int32_t res; //код возврата (0 - ОК, <0 - ошибка)
uint32_t len; //кол-во данных в ответе
} t_e502_tcp_resp_hdr;
#define E502_TCP_CMD_HDR_SIZE sizeof(t_e502_tcp_cmd_hdr)
#define E502_TCP_CMD_RESP_SIZE sizeof(t_e502_tcp_resp_hdr)
#define E502_TCP_CMD_RX_DATA_SIZE_MAX 512
#define E502_TCP_CMD_TX_DATA_SIZE_MAX 512
#define E502_TCP_DEFAULT_CMD_PORT 11114
#define E502_TCP_DEFAULT_DATA_PORT 11115
#define E502_TCP_SERVICE_NAME "_lcard_acqdev._tcp"
#endif // E502_TCP_PROTOCOL_H

View File

@ -0,0 +1,281 @@
#include "e502api_private.h"
#include <stdlib.h>
#include <string.h>
#define BF_LOAD_TOUT 20000
int32_t e502_iface_fpga_read(t_x502_hnd hnd, uint32_t addr, uint32_t *val) {
return hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_FPGA_REG_READ, addr, NULL, 0,
val, sizeof(*val), NULL, 0);
}
int32_t e502_iface_fpga_write(t_x502_hnd hnd, uint32_t addr, uint32_t val) {
return hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_FPGA_REG_WRITE, addr, &val, sizeof(val),
NULL, 0, NULL,0);
}
int32_t e502_iface_fpga_mode_init(t_x502_hnd hnd) {
int32_t err;
t_e502_cm4_test_state res;
err = hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_TEST_GET_STATE, 0, NULL, 0,
&res, sizeof(res), NULL, 0);
if ((err == X502_ERR_OK) && res.run) {
err = hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_TEST_STOP, 0, NULL, 0,
NULL, 0, NULL,0);
}
return err;
}
int32_t e502_iface_stream_running(t_x502_hnd hnd, uint32_t ch, int32_t* running) {
int32_t err;
uint8_t l_run;
err = hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_STREAM_IS_RUNNING, (ch << 16),
NULL, 0, &l_run, 1, NULL, 0);
if (!err && (running!=NULL)) {
*running = l_run;
}
return err;
}
int32_t e502_iface_bf_mem_block_rd(t_x502_hnd hnd, uint32_t addr, uint32_t *block, uint32_t size) {
return hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_BF_MEM_READ, addr, NULL, 0,
block, size*4, NULL, 0);
}
int32_t e502_iface_bf_mem_block_wr(t_x502_hnd hnd, uint32_t addr, const uint32_t *block, uint32_t size) {
return hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_BF_MEM_WRITE, addr, block, size*4,
NULL, 0, NULL, 0);
}
int32_t e502_iface_bf_firm_load(t_x502_hnd hnd, const char *filename) {
int32_t err = 0;
FILE* f=fopen(filename, "rb");
if (f==NULL) {
err = X502_ERR_LDR_FILE_OPEN;
} else {
uint8_t *buf = malloc(hnd->iface_hnd->ioctl_max_data_size);
long size, done=0;
if (buf == NULL)
err = X502_ERR_MEMORY_ALLOC;
//определяем размер файла
fseek(f, 0, SEEK_END);
size = ftell(f);
fseek(f, 0, SEEK_SET);
/* данные записываем блоками по L502_BF_REQ_DATA_SIZE */
while (!err && (size!=done)) {
unsigned block_size = size-done;
if (block_size > hnd->iface_hnd->ioctl_max_data_size)
block_size = hnd->iface_hnd->ioctl_max_data_size;
if (fread(buf, 1, block_size, f) != block_size) {
err = X502_ERR_LDR_FILE_READ;
}
if (!err) {
err = hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_FIRM_BUF_WRITE,
done, buf, block_size, NULL, 0, NULL, 0);
}
if (!err) {
done += block_size;
}
}
if (!err) {
err = hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_BF_FIRM_LOAD, 0,
NULL, 0, NULL, 0, NULL, BF_LOAD_TOUT);
}
free(buf);
fclose(f);
}
return err;
}
int32_t e502_iface_flash_rd(t_x502_hnd hnd, uint32_t addr, uint8_t* data, uint32_t size) {
return hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_FLASH_RD, addr, NULL, 0,
data, size, NULL, 0);
}
int32_t e502_iface_flash_wr(t_x502_hnd hnd, uint32_t addr, const uint8_t* data, uint32_t size) {
return hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_FLASH_WR, addr, data, size,
NULL, 0, NULL, 0);
}
int32_t e502_iface_flash_erase(t_x502_hnd hnd, uint32_t addr, uint32_t size) {
return hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_FLASH_ERASE, addr, &size, sizeof(size), NULL, 0, NULL, 0);
}
int32_t e502_iface_flash_set_prot(t_x502_hnd hnd, uint32_t prot, const uint8_t* prot_data, uint32_t size) {
return hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_FLASH_SET_PROTECT, prot, prot_data, size, NULL, 0, NULL, 0);
}
int32_t e502_iface_reload_dev_info(t_x502_hnd hnd) {
int32_t err = hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_FLASH_RELOAD_INFO, 0, NULL, 0, NULL, 0, NULL, 0);
if (err == X502_ERR_OK) {
err = e502_fill_devflags(hnd);
}
return err;
}
int32_t e502_iface_cycle_load_start(t_x502_hnd hnd, uint32_t size) {
int32_t err = X502_ERR_OK;
if (!(hnd->flags & PRIV_FLAGS_CYCLE_MODE)) {
STREAM_OUT_CFG(hnd, err);
if (err == X502_ERR_OK)
err = hnd->iface_hnd->stream_start(hnd, X502_STREAM_CH_OUT, X502_STREAM_FLAG_NO_REQUEST);
}
if (err == X502_ERR_OK) {
err = hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_OUT_CYCLE_LOAD, size, NULL,0, NULL, 0, NULL, 0);
}
return err;
}
int32_t e502_iface_cycle_setup(t_x502_hnd hnd, uint32_t flags) {
return hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_OUT_CYCLE_SETUP, flags, NULL,0, NULL, 0, NULL, 0);
}
int32_t e502_iface_cycle_stop(t_x502_hnd hnd, uint32_t flags) {
int32_t err = hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_OUT_CYCLE_STOP, flags, NULL,0, NULL, 0, NULL, 0);
if (err == X502_ERR_OK)
err = hnd->iface_hnd->stream_free(hnd, X502_STREAM_CH_OUT, X502_STREAM_FLAG_NO_REQUEST);
return err;
}
bool E502_is_E16(t_x502_hnd hnd) {
if (strcmp(hnd->info.name, E16_DEVICE_NAME) == 0) {
return true;
} else {
return false;
}
}
int32_t e502_iface_cycle_check_setup(t_x502_hnd hnd, uint32_t *done) {
int32_t err = E502_CM4_SUPPORT_OUT_CYCLE_SETUP_CHECK(hnd->info.mcu_firmware_ver)
? X502_ERR_OK : X502_ERR_NOT_SUP_BY_FIRMWARE;
if (E502_is_E16(hnd) || err == X502_ERR_OK) {
uint8_t ret_done;
err = hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_OUT_CYCLE_SETUP_CHECK, 0, NULL,0, &ret_done, sizeof(ret_done), NULL, 0);
if (err == X502_ERR_OK) {
*done = ret_done ? 1 : 0;
}
}
return err;
}
int32_t e502_iface_check_feature(t_x502_hnd hnd, uint32_t feature) {
int32_t err = X502_ERR_NOT_SUP_BY_FIRMWARE;
switch (feature) {
case X502_FEATURE_OUT_FREQ_DIV:
case X502_FEATURE_OUT_STATUS_FLAGS:
err = X502_ERR_OK;
break;
default:
err = X502_ERR_UNKNOWN_FEATURE_CODE;
break;
}
return err;
}
void e502_devinfo_init(t_x502_info *info, const t_lboot_devinfo *lboot_info) {
int ver[4];
int ver_comp_valid;
strcpy(info->serial, lboot_info->serial);
info->mcu_firmware_ver = 0;
ver_comp_valid = sscanf(lboot_info->soft_ver, "%d.%d.%d.%d", &ver[0], &ver[1], &ver[2], &ver[3]);
if (ver_comp_valid >= 1)
info->mcu_firmware_ver |= (ver[0]&0xFF) << 24;
if (ver_comp_valid >= 2)
info->mcu_firmware_ver |= (ver[1]&0xFF) << 16;
if (ver_comp_valid >= 3)
info->mcu_firmware_ver |= (ver[2]&0xFF) << 8;
if (ver_comp_valid >= 4)
info->mcu_firmware_ver |= ver[3]&0xFF;
}
int32_t e502_fill_devflags(t_x502_hnd hnd) {
int32_t err;
uint32_t devflags;
err = hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_GET_DEVFLAGS, 0, NULL, 0, &devflags,
sizeof(devflags), NULL, 0);
if (err == X502_ERR_OK) {
hnd->info.devflags &= ~E502_CM4_DEVFLAGS;
hnd->info.devflags |= devflags;
}
return err;
}
X502_EXPORT(int32_t) E502_SwitchToBootloader(t_x502_hnd hnd) {
int32_t err = X502_CHECK_HND_OPENED(hnd);
if (err == X502_ERR_OK) {
err = hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_BOOT, 0, NULL, 0, NULL, 0, NULL, 0);
}
return err;
}
X502_EXPORT(int32_t) E502_ReloadFPGA(t_x502_hnd hnd) {
int32_t err = X502_CHECK_HND_OPENED(hnd);
if (err == X502_ERR_OK) {
err = hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_RELOAD_FPGA, 0, NULL, 0, NULL, 0, NULL, 0);
}
return err;
}
X502_EXPORT(int32_t) E502_CortexExecCmd(t_x502_hnd hnd, uint32_t cmd_code, uint32_t par,
const uint8_t* snd_data, uint32_t snd_size,
uint8_t* rcv_data, uint32_t rcv_size,
uint32_t tout, uint32_t* recvd_size) {
int32_t err = X502_CHECK_HND_OPENED(hnd);
if (err == X502_ERR_OK) {
err = hnd->iface_hnd->gen_ioctl(hnd, cmd_code, par,
snd_data, snd_size, rcv_data, rcv_size,
recvd_size, tout);
}
return err;
}
#ifdef WIN32
#include <winsock2.h>
BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
WSADATA wsaData;
WORD wVersionRequested;
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
wVersionRequested = MAKEWORD(2, 2);
if (WSAStartup(wVersionRequested, &wsaData))
return FALSE;
if (wsaData.wVersion != wVersionRequested) {
WSACleanup();
return FALSE;
}
break;
case DLL_PROCESS_DETACH:
WSACleanup();
break;
}
return TRUE;
}
#endif

View File

@ -0,0 +1,60 @@
LIBRARY e502api.dll
EXPORTS
E502_UsbGetDevRecordsList
E502_UsbGetDevRecordsList2
E16_UsbGetDevRecordsList
E440_UsbGetDevRecordsList
E502_UsbGetSerialList
E16_UsbGetSerialList
E502_OpenUsb
E16_OpenUsb
E502_OpenByIpAddr
E16_OpenByIpAddr
E502_MakeDevRecordByIpAddr
E502_MakeDevRecordByIpAddr2
E502_MakeDevRecordByEthSvc
E502_EthConfigCreate
E502_EthConfigFree
E502_GetIpAddr
E502_EthConfigRead
E502_EthConfigWrite
E502_EthConfigGetEnabled
E502_EthConfigSetEnabled
E502_EthConfigGetAutoIPEnabled
E502_EthConfigSetAutoIPEnabled
E502_EthConfigGetAutoIPState
E502_EthConfigGetUserMACEnabled
E502_EthConfigSetUserMACEnabled
E502_EthConfigGetIPv4Addr
E502_EthConfigSetIPv4Addr
E502_EthConfigGetIPv4Mask
E502_EthConfigSetIPv4Mask
E502_EthConfigGetIPv4Gate
E502_EthConfigSetIPv4Gate
E502_EthConfigGetUserMac
E502_EthConfigSetUserMac
E502_EthConfigGetFactoryMac
E502_EthConfigGetInstanceName
E502_EthConfigSetInstanceName
E502_EthConfigSetNewPassword
E502_EthConfigCopy
E502_SwitchToBootloader
E502_ReloadFPGA
E502_CortexExecCmd
E502_EthSvcRecordFree
E502_EthSvcRecordGetInstanceName
E502_EthSvcRecordGetDevName
E502_EthSvcRecordGetDevSerial
E502_EthSvcRecordResolveIPv4Addr
E502_EthSvcRecordIsSameInstance
E502_EthSvcBrowseStart
E502_EthSvcBrowseGetEvent
E502_EthSvcBrowseStop
E502_EthDevRecordSetCmdPort
E502_EthDevRecordSetDataPort
E502_SearchEthForDevicesIPv4Addr
E502_EthConfigSetTcpCmdPort
E502_EthConfigSetTcpDataPort
E502_EthConfigGetTcpCmdPort
E502_EthConfigGetTcpDataPort

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,48 @@
#include <winresrc.h>
#define LIB_VERSION @X502API_VER_MAJOR@,@X502API_VER_MINOR@,@X502API_VER_PATCH@,0
#define VER_DEBUG VS_FF_DEBUG
1 VERSIONINFO
FILEVERSION LIB_VERSION
PRODUCTVERSION LIB_VERSION
#ifndef NDEBUG
FILEFLAGS 0
#else
FILEFLAGS VER_DEBUG
#endif
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "04090000"
BEGIN
VALUE "CompanyName", "L-Card"
VALUE "FileDescription", "Library for E502"
VALUE "FileVersion", "@X502API_VERSION@"
VALUE "OriginalFilename", "e502api.dll"
VALUE "ProductName", "e502api"
VALUE "ProductVersion", "@X502API_VERSION@"
VALUE "LegalCopyright", "© 2015 L-Card Ltd."
END
BLOCK "04190000"
BEGIN
VALUE "CompanyName", "Л Кард"
VALUE "FileDescription", "Библиотека для работы с модулем E502"
VALUE "FileVersion", "@X502API_VERSION@"
VALUE "OriginalFilename", "e502api.dll"
VALUE "ProductName", "e502api"
VALUE "ProductVersion", "@X502API_VERSION@"
VALUE "LegalCopyright", "© 2015 ООО 'Л Кард'"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
VALUE "Translation", 0x419, 1251
END
END

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,307 @@
#include "e502api_private.h"
#include "e502_eth_config.h"
#include <string.h>
#include <stdlib.h>
#if E502_ETHCONFIG_MAC_ADDR_SIZE != X502_MAC_ADDR_SIZE
#error "inconsistent E502_ETHCONFIG_MAC_ADDR_SIZE"
#endif
#if E502_ETHCONFIG_INSTANCE_NAME_SIZE != X502_INSTANCE_NAME_SIZE
#error "inconsistent E502_ETHCONFIG_INSTANCE_NAME_SIZE"
#endif
#if E502_ETHCONFIG_PASSWD_SIZE != X502_PASSWORD_SIZE
#error "inconsistent E502_ETHCONFIG_PASSWD_SIZE"
#endif
#define E502_ETH_CFG_SIGN 0xE502CFA5
#define E502_ETH_CHECK_CFG(cfg) ((cfg != NULL) ? (cfg)->sign == E502_ETH_CFG_SIGN ? X502_ERR_OK \
: X502_ERR_INVALID_CONFIG_HANDLE : X502_ERR_INVALID_CONFIG_HANDLE)
#define IP_ADDR_TO_UINT32(addr, dword) ((dword) = ((uint32_t)addr[0] << 24) | \
((uint32_t)addr[1] << 16) | \
((uint32_t)addr[2] << 8) | \
addr[3]);
#define IP_UINT32_TO_ADDR(dword, addr) do { \
addr[0] = (dword >> 24) & 0xFF; \
addr[1] = (dword >> 16) & 0xFF; \
addr[2] = (dword >> 8) & 0xFF; \
addr[3] = (dword) & 0xFF; \
} while(0)
typedef struct st_e502_eth_config_state {
uint32_t sign;
uint32_t flags;
uint8_t factory_mac[E502_ETHCONFIG_MAC_ADDR_SIZE];
t_e502_eth_set_config_params params;
} t_e502_eth_config_state;
X502_EXPORT(t_e502_eth_config_hnd) E502_EthConfigCreate(void) {
t_e502_eth_config_hnd cfg = calloc(1, sizeof(t_e502_eth_config_state));
if (cfg != NULL) {
cfg->sign = E502_ETH_CFG_SIGN;
}
return cfg;
}
X502_EXPORT(int32_t) E502_EthConfigCopy(t_e502_eth_config_hnd src_cfg, t_e502_eth_config_hnd dst_cfg) {
int32_t err = E502_ETH_CHECK_CFG(src_cfg);
if (err == X502_ERR_OK)
err = E502_ETH_CHECK_CFG(dst_cfg);
if (err == X502_ERR_OK) {
memcpy(dst_cfg, src_cfg, sizeof(t_e502_eth_config_state));
}
return err;
}
X502_EXPORT(int32_t) E502_EthConfigFree(t_e502_eth_config_hnd cfg) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK) {
memset(cfg, 0, sizeof(t_e502_eth_config_state));
free(cfg);
}
return err;
}
X502_EXPORT(int32_t) E502_EthConfigRead(t_x502_hnd hnd, t_e502_eth_config_hnd cfg) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK) {
err = X502_CHECK_HND_OPENED(hnd);
}
if (err == X502_ERR_OK) {
uint32_t recvd_size;
err = hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_ETH_CFG_GET, 0,
NULL, 0, &cfg->params.cfg, sizeof(t_e502_eth_config), &recvd_size, 0);
if (err == X502_ERR_OK) {
cfg->flags = 0;
memcpy(cfg->factory_mac, hnd->info.factory_mac, sizeof(cfg->factory_mac));
}
}
return err;
}
X502_EXPORT(int32_t) E502_EthConfigWrite(t_x502_hnd hnd, t_e502_eth_config_hnd cfg, const char *passwd) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK) {
err = X502_CHECK_HND_OPENED(hnd);
}
if (err == X502_ERR_OK) {
if (passwd != NULL) {
strncpy(cfg->params.passwd, passwd, E502_ETHCONFIG_PASSWD_SIZE-1);
cfg->params.passwd[E502_ETHCONFIG_PASSWD_SIZE-1] = '\0';
} else {
cfg->params.passwd[0] = '\0';
}
err = hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_ETH_CFG_SET, cfg->flags,
&cfg->params, sizeof(cfg->params),
NULL, 0, NULL, 0);
memset(cfg->params.passwd, 0, E502_ETHCONFIG_PASSWD_SIZE);
}
return err;
}
X502_EXPORT(int32_t) E502_EthConfigSetNewPassword(t_e502_eth_config_hnd cfg, const char *new_passwd) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK) {
cfg->flags |= E502_ETH_CONFIG_FLAGS_SET_NEW_PASSWD;
if (new_passwd != NULL) {
strncpy(cfg->params.new_passwd, new_passwd, E502_ETHCONFIG_PASSWD_SIZE);
cfg->params.new_passwd[E502_ETHCONFIG_PASSWD_SIZE-1] = '\0';
} else {
cfg->params.new_passwd[0] = '\0';
}
}
return err;
}
X502_EXPORT(int32_t) E502_EthConfigGetEnabled(t_e502_eth_config_hnd cfg, uint32_t *en) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK)
*en = cfg->params.cfg.flags & E502_ETH_FLAGS_IFACE_ENABLED;
return err;
}
X502_EXPORT(int32_t) E502_EthConfigSetEnabled(t_e502_eth_config_hnd cfg, uint32_t en) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK) {
if (en) {
cfg->params.cfg.flags |= E502_ETH_FLAGS_IFACE_ENABLED;
} else {
cfg->params.cfg.flags &= ~E502_ETH_FLAGS_IFACE_ENABLED;
}
}
return err;
}
X502_EXPORT(int32_t) E502_EthConfigGetAutoIPState(t_e502_eth_config_hnd cfg, uint32_t *state) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK)
*state = cfg->params.cfg.flags & E502_ETH_FLAGS_AUTO_IP_STATE_MASK;
return err;
}
X502_EXPORT(int32_t) E502_EthConfigGetAutoIPEnabled(t_e502_eth_config_hnd cfg, uint32_t *en) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK)
*en = cfg->params.cfg.flags & E502_ETH_FLAGS_AUTO_IP;
return err;
}
X502_EXPORT(int32_t) E502_EthConfigSetAutoIPEnabled(t_e502_eth_config_hnd cfg, uint32_t en) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK) {
if (en) {
cfg->params.cfg.flags |= E502_ETH_FLAGS_AUTO_IP;
} else {
cfg->params.cfg.flags &= ~E502_ETH_FLAGS_AUTO_IP;
}
}
return err;
}
X502_EXPORT(int32_t) E502_EthConfigGetUserMACEnabled(t_e502_eth_config_hnd cfg, uint32_t *en) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK)
*en = cfg->params.cfg.flags & E502_ETH_FLAGS_USER_MAC;
return err;
}
X502_EXPORT(int32_t) E502_EthConfigSetUserMACEnabled(t_e502_eth_config_hnd cfg, uint32_t en) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK) {
if (en) {
cfg->params.cfg.flags |= E502_ETH_FLAGS_USER_MAC;
} else {
cfg->params.cfg.flags &= ~E502_ETH_FLAGS_USER_MAC;
}
}
return err;
}
X502_EXPORT(int32_t) E502_EthConfigGetIPv4Addr(t_e502_eth_config_hnd cfg, uint32_t *addr) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK)
IP_ADDR_TO_UINT32(cfg->params.cfg.ipv4.addr, *addr);
return err;
}
X502_EXPORT(int32_t) E502_EthConfigSetIPv4Addr(t_e502_eth_config_hnd cfg, uint32_t addr) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK)
IP_UINT32_TO_ADDR(addr, cfg->params.cfg.ipv4.addr);
return err;
}
X502_EXPORT(int32_t) E502_EthConfigGetIPv4Mask(t_e502_eth_config_hnd cfg, uint32_t *mask) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK)
IP_ADDR_TO_UINT32(cfg->params.cfg.ipv4.mask, *mask);
return err;
}
X502_EXPORT(int32_t) E502_EthConfigSetIPv4Mask(t_e502_eth_config_hnd cfg, uint32_t mask) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK)
IP_UINT32_TO_ADDR(mask, cfg->params.cfg.ipv4.mask);
return err;
}
X502_EXPORT(int32_t) E502_EthConfigGetIPv4Gate(t_e502_eth_config_hnd cfg, uint32_t *gate) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK)
IP_ADDR_TO_UINT32(cfg->params.cfg.ipv4.gate, *gate);
return err;
}
X502_EXPORT(int32_t) E502_EthConfigSetIPv4Gate(t_e502_eth_config_hnd cfg, uint32_t gate) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK)
IP_UINT32_TO_ADDR(gate, cfg->params.cfg.ipv4.gate);
return err;
}
X502_EXPORT(int32_t) E502_EthConfigGetUserMac(t_e502_eth_config_hnd cfg, uint8_t *mac) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK)
memcpy(mac, cfg->params.cfg.mac, E502_ETHCONFIG_MAC_ADDR_SIZE);
return err;
}
X502_EXPORT(int32_t) E502_EthConfigSetUserMac(t_e502_eth_config_hnd cfg, const uint8_t *mac) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK)
memcpy(cfg->params.cfg.mac, mac, E502_ETHCONFIG_MAC_ADDR_SIZE);
return err;
}
X502_EXPORT(int32_t) E502_EthConfigGetFactoryMac(t_e502_eth_config_hnd cfg, uint8_t *mac) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK)
memcpy(mac, cfg->factory_mac, E502_ETHCONFIG_MAC_ADDR_SIZE);
return err;
}
X502_EXPORT(int32_t) E502_EthConfigGetInstanceName(t_e502_eth_config_hnd cfg, char *name) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK) {
strncpy(name, cfg->params.cfg.inst_name, E502_ETHCONFIG_INSTANCE_NAME_SIZE);
name[E502_ETHCONFIG_INSTANCE_NAME_SIZE-1] = '\0';
}
return err;
}
X502_EXPORT(int32_t) E502_EthConfigSetInstanceName(t_e502_eth_config_hnd cfg, const char *name) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK) {
if (name != NULL) {
strncpy(cfg->params.cfg.inst_name, name, E502_ETHCONFIG_INSTANCE_NAME_SIZE);
cfg->params.cfg.inst_name[E502_ETHCONFIG_INSTANCE_NAME_SIZE-1] = '\0';
} else {
cfg->params.cfg.inst_name[0] = '\0';
}
}
return err;
}
X502_EXPORT(int32_t) E502_EthConfigSetTcpCmdPort(t_e502_eth_config_hnd cfg, uint16_t port) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK) {
cfg->params.cfg.tcp_cmd_port = port;
}
return err;
}
X502_EXPORT(int32_t) E502_EthConfigSetTcpDataPort(t_e502_eth_config_hnd cfg, uint16_t port) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK) {
cfg->params.cfg.tcp_data_port = port;
}
return err;
}
X502_EXPORT(int32_t) E502_EthConfigGetTcpCmdPort(t_e502_eth_config_hnd cfg, uint16_t *port) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK)
*port = cfg->params.cfg.tcp_cmd_port;
return err;
}
X502_EXPORT(int32_t) E502_EthConfigGetTcpDataPort(t_e502_eth_config_hnd cfg, uint16_t *port) {
int32_t err = E502_ETH_CHECK_CFG(cfg);
if (err == X502_ERR_OK)
*port = cfg->params.cfg.tcp_data_port;
return err;
}

View File

@ -0,0 +1,47 @@
#ifndef E502API_PRIVATE_H
#define E502API_PRIVATE_H
#include "e502api.h"
#include "x502api_private.h"
#include "e502_cm4_defs.h"
#include "lboot_req.h"
#define E502_CM4_DEVFLAGS (X502_DEVFLAGS_IFACE_SUPPORT_ETH \
| X502_DEVFLAGS_INDUSTRIAL \
| X502_DEVFLAGS_FPGA_LOADED \
| X502_DEVFLAGS_DAC_TYPE \
)
#define E502_DEVICE_NAME "E502"
#define E16_DEVICE_NAME "E16"
int32_t e502_iface_fpga_read(t_x502_hnd hnd, uint32_t addr, uint32_t *val);
int32_t e502_iface_fpga_write(t_x502_hnd hnd, uint32_t addr, uint32_t val);
int32_t e502_iface_fpga_mode_init(t_x502_hnd hnd);
int32_t e502_iface_stream_running(t_x502_hnd hnd, uint32_t ch, int32_t* running);
int32_t e502_iface_bf_mem_block_rd(t_x502_hnd hnd, uint32_t addr, uint32_t *block, uint32_t size);
int32_t e502_iface_bf_mem_block_wr(t_x502_hnd hnd, uint32_t addr, const uint32_t *block, uint32_t size);
int32_t e502_iface_bf_firm_load(t_x502_hnd hnd, const char *filename);
int32_t e502_iface_flash_rd(t_x502_hnd hnd, uint32_t addr, uint8_t* data, uint32_t size);
int32_t e502_iface_flash_wr(t_x502_hnd hnd, uint32_t addr, const uint8_t* data, uint32_t size);
int32_t e502_iface_flash_erase(t_x502_hnd hnd, uint32_t addr, uint32_t size);
int32_t e502_iface_flash_set_prot(t_x502_hnd hnd, uint32_t prot, const uint8_t* prot_data, uint32_t size);
int32_t e502_iface_reload_dev_info(t_x502_hnd hnd);
int32_t e502_iface_cycle_load_start(t_x502_hnd hnd, uint32_t size);
int32_t e502_iface_cycle_setup(t_x502_hnd hnd, uint32_t flags);
int32_t e502_iface_cycle_stop(t_x502_hnd hnd, uint32_t flags);
int32_t e502_iface_cycle_check_setup(t_x502_hnd hnd, uint32_t *done);
int32_t e502_iface_check_feature(t_x502_hnd hnd, uint32_t feature);
void e502_devinfo_init(t_x502_info *info, const t_lboot_devinfo *lboot_info);
int32_t e502_fill_devflags(t_x502_hnd hnd);
#endif // E502API_PRIVATE_H

View File

@ -0,0 +1,902 @@
#ifdef ENABLE_TCP
#include "e502api_private.h"
#include "e502_tcp_protocol.h"
#include "ltimer.h"
#include "e502_fpga_regs.h"
#include "e502api_tcp_private.h"
#include "osspec.h"
#include <stdlib.h>
#include <string.h>
#if defined _WIN32
#include <winsock2.h>
typedef int socklen_t;
typedef SOCKET t_socket;
#define SOCK_ERR_SIGBREAK() 0
#define L_SOCK_LAST_ERR_BLOCK() (WSAEWOULDBLOCK == WSAGetLastError())
#define L_SOCK_LAST_ERR_RESET() (WSAECONNRESET == WSAGetLastError())
#else
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/tcp.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
//#include <stropts.h>
#include <linux/sockios.h>
typedef int t_socket;
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define SOCK_ERR_SIGBREAK() (EINTR == errno)
#define L_SOCK_LAST_ERR_BLOCK() ((EAGAIN==errno) || (EWOULDBLOCK==errno))
#ifdef ECONNRESET
#define L_SOCK_LAST_ERR_RESET() (ECONNRESET==errno)
#endif
#define closesocket(sock) close(sock)
#endif
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif
#define E502_TCP_REQ_TOUT 5000
#define E502_TCP_STOP_WAIT_TOUT 5000
#define X502_MUTEX_TCP_IOCTL_LOCK_TOUT 5000
#define X502_MUTEX_TCP_DATA_LOCK_TOUT 5000
#define TCP_CTL_REQ_MAX_SIZE 512
#define TCP_IN_STREAM_BUF_MIN 128
#define TCP_IOCTL_INLINE_MAX_DATA_SIZE 64
#if 0
#define dprintf(...) fprintf(stderr, __VA_ARGS__)
#else
#define dprintf(...)
#endif
typedef struct {
t_socket cmd_sock;
t_socket data_sock;
uint32_t ip_addr;
uint32_t open_tout;
uint16_t data_port;
t_mutex ioctl_mutex;
t_mutex data_mutex;
uint32_t data_chs_en;
uint32_t recv_part_wrd; /**< принятое неполностью слово */
uint32_t send_part_wrd; /**< переданное неполностью слово */
uint8_t recv_part_size; /**< кол-во принятых байт в последнем неполном слове */
uint8_t send_part_size; /**< кол-во неотправленных байт в последнем переданном не полностью слове */
} t_tcp_iface_data;
static int32_t f_iface_free_devinfo_ptr(t_x502_devrec_inptr *devinfo_ptr);
static int32_t f_iface_open(t_x502_hnd hnd, const t_x502_devrec *devrec);
static int32_t f_iface_close(t_x502_hnd hnd);
static int32_t f_iface_stream_cfg(t_x502_hnd hnd, uint32_t ch, t_x502_stream_ch_params *params);
static int32_t f_iface_stream_start(t_x502_hnd hnd, uint32_t ch, uint32_t signle);
static int32_t f_iface_stream_stop(t_x502_hnd hnd, uint32_t ch, uint32_t flags);
static int32_t f_iface_stream_free(t_x502_hnd hnd, uint32_t ch, uint32_t flags);
static int32_t f_iface_stream_read(t_x502_hnd hnd, uint32_t *buf, uint32_t size, uint32_t tout);
static int32_t f_iface_stream_write(t_x502_hnd hnd, const uint32_t *buf, uint32_t size, uint32_t tout) ;
static int32_t f_iface_stream_get_rdy_cnt(t_x502_hnd hnd, uint32_t ch, uint32_t *rdy_cnt);
static int32_t f_iface_gen_ioctl(t_x502_hnd hnd, uint32_t cmd_code, uint32_t param,
const void* snd_data, uint32_t snd_size,
void* rcv_data, uint32_t recv_size, uint32_t* recvd_size,
uint32_t tout);
static const t_x502_dev_iface f_tcp_iface = {
E502_REGS_ARM_HARD_ID,
TCP_IN_STREAM_BUF_MIN,
TCP_CTL_REQ_MAX_SIZE,
TCP_CTL_REQ_MAX_SIZE/4,
TCP_CTL_REQ_MAX_SIZE, //flash rd size
TCP_CTL_REQ_MAX_SIZE, //flash wr size
f_iface_free_devinfo_ptr,
f_iface_open,
f_iface_close,
e502_iface_fpga_read,
e502_iface_fpga_write,
f_iface_stream_cfg,
f_iface_stream_start,
f_iface_stream_stop,
f_iface_stream_free,
e502_iface_stream_running,
f_iface_stream_read,
f_iface_stream_write,
f_iface_stream_get_rdy_cnt,
e502_iface_bf_mem_block_rd,
e502_iface_bf_mem_block_wr,
e502_iface_bf_firm_load,
e502_iface_flash_rd,
e502_iface_flash_wr,
e502_iface_flash_erase,
e502_iface_flash_set_prot,
e502_iface_reload_dev_info,
e502_iface_cycle_load_start,
e502_iface_cycle_setup,
e502_iface_cycle_stop,
e502_iface_cycle_check_setup,
e502_iface_fpga_mode_init,
f_iface_gen_ioctl,
e502_iface_check_feature
};
static void f_set_timeval_left(t_ltimer* tmr, struct timeval* tval) {
t_lclock_ticks left = ltimer_expiration(tmr);
tval->tv_sec = left / LCLOCK_TICKS_PER_SECOND;
tval->tv_usec = (left % LCLOCK_TICKS_PER_SECOND) * 1000000/LCLOCK_TICKS_PER_SECOND;
}
static int32_t f_con_sock(t_socket *psock, uint32_t ip_addr, uint16_t port, uint32_t tout) {
int32_t err = X502_ERR_OK;
struct sockaddr_in peer;
int connected = 0;
t_socket s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET)
err = X502_ERR_SOCKET_OPEN;
/* Переводим сокет в неблокирующий режим работы */
if (err == X502_ERR_OK) {
#ifdef _WIN32
ULONG nonblocking = 1;
if (SOCKET_ERROR == ioctlsocket(s, FIONBIO, &nonblocking))
err = X502_ERR_SOCKET_OPEN;
#else
int n = fcntl(s, F_GETFL, 0);
if (fcntl(s, F_SETFL, n|O_NONBLOCK)==-1) {
err = X502_ERR_SOCKET_OPEN;
}
#endif
}
if (err == X502_ERR_OK) {
/* заполняем структуру с адресом LTR-сервера */
memset(&peer, 0, sizeof(peer));
peer.sin_family = AF_INET;
peer.sin_port = htons(port);
peer.sin_addr.s_addr = htonl(ip_addr);
}
while (!connected && (err==X502_ERR_OK)) {
t_ltimer tmr;
ltimer_set(&tmr, LTIMER_MS_TO_CLOCK_TICKS(tout));
if (SOCKET_ERROR == connect(s, (struct sockaddr*)&peer, sizeof(peer))) {
int sockerr = 0;
fd_set fd_w, fd_e;
#ifdef _WIN32
if (WSAEWOULDBLOCK != WSAGetLastError()) {
#else
if (errno != EINPROGRESS) {
#endif
err = X502_ERR_SOCKET_OPEN;
} else {
struct timeval tval;
FD_ZERO(&fd_w);
FD_SET(s, &fd_w);
FD_ZERO(&fd_e);
FD_SET(s, &fd_e);
f_set_timeval_left(&tmr, &tval);
if (select((int)s+1, NULL, &fd_w, &fd_e, &tval) < 1)
err = X502_ERR_CONNECTION_TOUT;
}
if (err == X502_ERR_OK) {
/* судя по man - если произошла ошибка, то сокет становится writable!
так что в fd_w тоже нужно проверять ошибку */
socklen_t optlen = sizeof(sockerr);
if (SOCKET_ERROR == getsockopt(s, SOL_SOCKET, SO_ERROR,
(char*)&sockerr, &optlen)) {
err = X502_ERR_SOCKET_OPEN;
} else if (sockerr) {
#ifdef EHOSTUNREACH
if (sockerr == EHOSTUNREACH) {
err = X502_ERR_HOST_UNREACHABLE;
}
#endif
#ifdef ECONNRESET
if (sockerr == ECONNRESET) {
err = X502_ERR_CONNECTION_RESET;
}
#endif
if (err == X502_ERR_OK)
err = X502_ERR_TCP_CONNECTION_ERROR;
}
}
/* проверяем, что соединились успешно */
if ((err == X502_ERR_OK) && !sockerr && (FD_ISSET(s, &fd_w)))
connected = 1;
} else {
/* удалось соединится без ожидания */
connected = 1;
}
} /* while (!connected && !err) */
if (err != X502_ERR_OK) {
if (s!=INVALID_SOCKET) {
closesocket(s);
}
} else if (psock!=NULL) {
*psock = s;
}
return err;
}
static int32_t f_recv(t_socket s, uint8_t *buf, uint32_t size, t_ltimer *ptmr) {
int32_t err = X502_ERR_OK;
uint32_t offset = 0;
int timed_out = 0;
fd_set fd_r;
struct timeval tval;
if ((err == X502_ERR_OK) && (size!=0)) {
while (!err && !timed_out && (offset < size)) {
FD_ZERO(&fd_r);
FD_SET(s, &fd_r);
f_set_timeval_left(ptmr, &tval);
switch (select((int)s+1, &fd_r, NULL, NULL, &tval)) {
case SOCKET_ERROR:
/* Если пришел сигнал, то это не ошибка приема.
* Но скорее всего управление стоит вернуть сразу, хотя
* может сделать опцию... */
if (SOCK_ERR_SIGBREAK()) {
ltimer_set(ptmr, 0);
timed_out = 1;
} else {
err = X502_ERR_RECV;
}
break;
case 0: // таймаут
timed_out = 1;
break;
default: { /* дождались готовности на чтение */
int res = recv(s, buf + offset, size - offset, 0);
if (SOCKET_ERROR == res) {
if (!L_SOCK_LAST_ERR_BLOCK()) {
err = X502_ERR_RECV;
}
} else if (0 == res) {
/* соединение закрыто */
err = X502_ERR_CONNECTION_CLOSED_BY_DEV;
} else {
offset += res;
}
}
break;
}
} /* switch (select(ch->sock+1, &fd_r, NULL, NULL, &tval)) */
}
return err ? err : (int32_t)offset;
}
int32_t f_send(t_socket s, const uint8_t *buf, uint32_t size, t_ltimer *ptmr) {
int32_t err = X502_ERR_OK;
uint32_t offset = 0;
int timed_out = 0;
fd_set fd_w;
if ((err == X502_ERR_OK) && (size != 0)) {
while ((err == X502_ERR_OK) && !timed_out && (offset < size)) {
/* Сначала пробуем сделать запись без ожидания */
int res = send(s, buf + offset, size - offset, MSG_NOSIGNAL);
if (res == SOCKET_ERROR) {
struct timeval tval;
if (L_SOCK_LAST_ERR_BLOCK()) {
/* Надо ждать освобождения сокета */
FD_ZERO(&fd_w);
FD_SET(s, &fd_w);
f_set_timeval_left(ptmr, &tval);
switch (select((int)s+1, NULL, &fd_w, NULL, &tval)) {
case SOCKET_ERROR:
if (SOCK_ERR_SIGBREAK()) {
ltimer_set(ptmr, 0);
timed_out = 1;
} else {
err = X502_ERR_SEND;
}
break;
case 0: // таймаут
timed_out = 1;
break;
default:
if (ltimer_expired(ptmr))
timed_out = 1;
break;
}
} else {
err = X502_ERR_SEND;
}
} else { // no error
offset += res;
}
}
}
return (err) ? err : (int)offset;
}
static int32_t f_recv_exact(t_socket s, uint8_t *buf, uint32_t size, t_ltimer *ptmr) {
int32_t ret = f_recv(s, buf, size, ptmr);
return ret == (int32_t)size ? X502_ERR_OK : ret < 0 ? ret : X502_ERR_RECV_INSUFFICIENT_WORDS;
}
static int32_t f_send_exact(t_socket s, const uint8_t *buf, uint32_t size, t_ltimer *ptmr) {
int32_t ret = f_send(s, buf, size, ptmr);
return ret == (int32_t)size ? X502_ERR_OK : ret < 0 ? ret : X502_ERR_SEND_INSUFFICIENT_WORDS;
}
static int32_t f_iface_gen_ioctl(t_x502_hnd hnd, uint32_t cmd_code, uint32_t param,
const void* snd_data, uint32_t snd_size,
void* rcv_data, uint32_t recv_size, uint32_t* recvd_size, uint32_t tout) {
struct {
t_e502_tcp_cmd_hdr hdr;
uint8_t data[TCP_IOCTL_INLINE_MAX_DATA_SIZE];
} cmd;
t_e502_tcp_resp_hdr cmd_resp;
int32_t err = X502_ERR_OK;
t_ltimer tmr;
t_tcp_iface_data* iface_data = (t_tcp_iface_data*)hnd->iface_data;
t_socket s = iface_data->cmd_sock;
err = osspec_mutex_lock(iface_data->ioctl_mutex, X502_MUTEX_TCP_IOCTL_LOCK_TOUT);
if (err == X502_ERR_OK) {
ltimer_set(&tmr, LTIMER_MS_TO_CLOCK_TICKS(tout == 0 ? E502_TCP_REQ_TOUT : tout));
cmd.hdr.sign = E502_TCP_CMD_SIGNATURE;
cmd.hdr.cmd = cmd_code;
cmd.hdr.par = param;
cmd.hdr.data_len = snd_size;
cmd.hdr.resp_len = recv_size;
/* чтобы избежать двух передач по TCP, если данных, передаваемых с командой,
* меньше заданного порога, то объединяем их вместе с заголовком и посылаем
* за один вызов send */
if (snd_size <= TCP_IOCTL_INLINE_MAX_DATA_SIZE) {
if (snd_size > 0)
memcpy(cmd.data, snd_data, snd_size);
err = f_send_exact(s, (uint8_t*)&cmd, E502_TCP_CMD_HDR_SIZE + snd_size, &tmr);
} else {
err = f_send_exact(s, (uint8_t*)&cmd.hdr, E502_TCP_CMD_HDR_SIZE, &tmr);
if (err == X502_ERR_OK) {
err = f_send_exact(s, snd_data, snd_size, &tmr);
}
}
if (err == X502_ERR_OK) {
err = f_recv_exact(s, (uint8_t*)&cmd_resp, E502_TCP_CMD_RESP_SIZE, &tmr);
if (err == X502_ERR_RECV_INSUFFICIENT_WORDS) {
err = X502_ERR_NO_CMD_RESPONSE;
}
}
if ((err == X502_ERR_OK) && (cmd_resp.len > 0)) {
if (cmd_resp.len > recv_size) {
err = X502_ERR_IOCTL_INVALID_RESP_SIZE;
} else {
err = f_recv_exact(s, rcv_data, cmd_resp.len, &tmr);
}
}
if (err == X502_ERR_OK) {
if (recvd_size != NULL) {
*recvd_size = cmd_resp.len;
} else if (cmd_resp.len != recv_size) {
err = X502_ERR_IOCTL_INVALID_RESP_SIZE;
}
}
if ((err == X502_ERR_OK) && (cmd_resp.res!=0)) {
err = cmd_resp.res;
}
osspec_mutex_release(iface_data->ioctl_mutex);
}
return err;
}
static int32_t f_iface_free_devinfo_ptr(t_x502_devrec_inptr *devinfo_ptr) {
t_tcp_devinfo_data *devinfo_data = (t_tcp_devinfo_data*)devinfo_ptr->iface_data;
#ifdef ENABLE_DNSSD
if ((devinfo_data != NULL) && (devinfo_data->svc_rec != NULL))
E502_EthSvcRecordFree(devinfo_data->svc_rec);
#endif
free(devinfo_ptr->iface_data);
free(devinfo_ptr);
return X502_ERR_OK;
}
static int32_t f_iface_open(t_x502_hnd hnd, const t_x502_devrec *devrec) {
int32_t err = X502_ERR_OK;
t_tcp_devinfo_data *devinfo_data = (t_tcp_devinfo_data*)devrec->internal->iface_data;
t_socket s = INVALID_SOCKET;
#ifdef ENABLE_DNSSD
if (devinfo_data->svc_rec) {
err = e502_svc_fill_devinfo(devinfo_data);
}
#endif
if (err == X502_ERR_OK) {
err = f_con_sock(&s, devinfo_data->ip_addr, devinfo_data->cmd_port, devinfo_data->open_tout);
if (err == X502_ERR_OK) {
int flag = 1;
if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(flag))==SOCKET_ERROR)
err = X502_ERR_SOCKET_OPEN;
}
}
if (err == X502_ERR_OK) {
t_tcp_iface_data *iface_data = malloc(sizeof(t_tcp_iface_data));
if (iface_data == NULL) {
err = X502_ERR_MEMORY_ALLOC;
} else {
t_lboot_devinfo lboot_info;
iface_data->cmd_sock = s;
iface_data->data_sock = INVALID_SOCKET;
iface_data->ip_addr = devinfo_data->ip_addr;
iface_data->open_tout = devinfo_data->open_tout;
iface_data->data_port = devinfo_data->data_port;
iface_data->ioctl_mutex = osspec_mutex_create();
iface_data->data_mutex = osspec_mutex_create();
iface_data->data_chs_en = 0;
if ((iface_data->ioctl_mutex == OSSPEC_INVALID_MUTEX)
|| (iface_data->data_mutex == OSSPEC_INVALID_MUTEX)) {
err = X502_ERR_MUTEX_CREATE;
} else {
hnd->iface_data = iface_data;
err = hnd->iface_hnd->gen_ioctl(hnd, E502_CM4_CMD_GET_MODULE_INFO, 0, NULL, 0, &lboot_info,
sizeof(lboot_info), NULL, 0);
if (err == X502_ERR_OK) {
if (strcmp(lboot_info.devname, devrec->devname)) {
err = X502_ERR_INVALID_DEVICE;
} else {
e502_devinfo_init(&hnd->info, &lboot_info);
err = e502_fill_devflags(hnd);
}
}
}
if (err != X502_ERR_OK) {
if (iface_data->ioctl_mutex != OSSPEC_INVALID_MUTEX)
osspec_mutex_destroy(iface_data->ioctl_mutex);
if (iface_data->data_mutex != OSSPEC_INVALID_MUTEX)
osspec_mutex_destroy(iface_data->data_mutex);
hnd->iface_data = NULL;
free(iface_data);
}
}
}
if ((err != X502_ERR_OK) && (s != INVALID_SOCKET)) {
closesocket(s);
}
return err;
}
static int32_t f_iface_close(t_x502_hnd hnd) {
int32_t err = X502_ERR_OK;
t_tcp_iface_data *tcp_data = (t_tcp_iface_data*)hnd->iface_data;
if (tcp_data != NULL) {
if (tcp_data->data_sock!=INVALID_SOCKET) {
closesocket(tcp_data->data_sock);
tcp_data->data_sock = INVALID_SOCKET;
}
if (tcp_data->cmd_sock!=INVALID_SOCKET) {
closesocket(tcp_data->cmd_sock);
tcp_data->cmd_sock = INVALID_SOCKET;
}
if (tcp_data->ioctl_mutex != OSSPEC_INVALID_MUTEX) {
osspec_mutex_destroy(tcp_data->ioctl_mutex);
tcp_data->ioctl_mutex = OSSPEC_INVALID_MUTEX;
}
if (tcp_data->data_mutex != OSSPEC_INVALID_MUTEX) {
osspec_mutex_destroy(tcp_data->data_mutex);
tcp_data->data_mutex = OSSPEC_INVALID_MUTEX;
}
free(hnd->iface_data);
hnd->iface_data = NULL;
}
return err;
}
static int32_t f_iface_stream_cfg(t_x502_hnd hnd, uint32_t ch, t_x502_stream_ch_params *params) {
int32_t err = X502_ERR_OK;
t_tcp_iface_data *tcp_data = (t_tcp_iface_data*)hnd->iface_data;
err = osspec_mutex_lock(tcp_data->data_mutex, X502_MUTEX_TCP_DATA_LOCK_TOUT);
if (err == X502_ERR_OK) {
if (tcp_data->data_sock == INVALID_SOCKET) {
err = f_iface_gen_ioctl(hnd, E502_CM4_CMD_DROP_DATA_CON, 0, NULL, 0, NULL, 0, NULL, 0);
if (err == X502_ERR_OK) {
err = f_con_sock(&tcp_data->data_sock, tcp_data->ip_addr, tcp_data->data_port, tcp_data->open_tout);
}
if (err == X502_ERR_OK) {
int flag = 1;
if (setsockopt(tcp_data->data_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(flag))==SOCKET_ERROR)
err = X502_ERR_SOCKET_OPEN;
}
}
if (err == X502_ERR_OK) {
unsigned buf_size = params->buf_size*4;
if (ch==X502_STREAM_CH_IN) {
tcp_data->recv_part_size = 0;
if (setsockopt(tcp_data->data_sock, SOL_SOCKET, SO_RCVBUF, (char*)&buf_size, sizeof(buf_size))==SOCKET_ERROR) {
err = X502_ERR_SOCKET_SET_BUF_SIZE;
}
else {
dprintf("set SO_RCVBUF to %d\n", buf_size);
}
#ifndef _WIN32
setsockopt(tcp_data->data_sock, SOL_SOCKET, SO_RCVBUFFORCE, (char*)&buf_size, sizeof(buf_size));
#endif
socklen_t opt_len = sizeof(buf_size);
if (getsockopt(tcp_data->data_sock, SOL_SOCKET, SO_RCVBUF, (char*)&buf_size, &opt_len) != SOCKET_ERROR) {
dprintf("get SO_RCVBUF = %d\n", buf_size);
}
#ifdef _WIN32
else {
dprintf("getsockopt error = %d\n", WSAGetLastError());
}
#endif
} else {
tcp_data->send_part_size = 0;
if (setsockopt(tcp_data->data_sock, SOL_SOCKET, SO_SNDBUF, (char*)&buf_size, sizeof(buf_size))==SOCKET_ERROR) {
err = X502_ERR_SOCKET_SET_BUF_SIZE;
}
}
}
if (err == X502_ERR_OK) {
tcp_data->data_chs_en |= (1UL << ch);
}
osspec_mutex_release(tcp_data->data_mutex);
}
return err;
}
static int32_t f_iface_stream_start(t_x502_hnd hnd, uint32_t ch, uint32_t flags) {
int32_t err = 0;
if (!err && !(flags & X502_STREAM_FLAG_NO_REQUEST)) {
err = f_iface_gen_ioctl(hnd, E502_CM4_CMD_STREAM_START, (ch<<16),
NULL, 0, NULL, 0, NULL, 0);
}
return err;
}
static int32_t f_iface_stream_stop(t_x502_hnd hnd, uint32_t ch, uint32_t flags) {
int32_t err = 0;
if (!(flags & X502_STREAM_FLAG_NO_REQUEST)) {
int32_t running;
err = hnd->iface_hnd->stream_running(hnd, ch, &running);
if (!err && running) {
err = f_iface_gen_ioctl(hnd, E502_CM4_CMD_STREAM_STOP, (ch << 16),
NULL, 0, NULL, 0, NULL, 0);
}
}
return err;
}
static int32_t f_iface_stream_free(t_x502_hnd hnd, uint32_t ch, uint32_t flags) {
t_tcp_iface_data *tcp_data = (t_tcp_iface_data *)hnd->iface_data;
int32_t err = osspec_mutex_lock(tcp_data->data_mutex, X502_MUTEX_TCP_DATA_LOCK_TOUT);
if (err == X502_ERR_OK) {
err = hnd->iface_hnd->stream_stop(hnd, ch, flags);
if (err == X502_ERR_OK) {
tcp_data->data_chs_en &= ~(1UL << ch);
if ((tcp_data->data_chs_en == 0) && (tcp_data->data_sock != INVALID_SOCKET)) {
closesocket(tcp_data->data_sock);
tcp_data->data_sock = INVALID_SOCKET;
}
}
osspec_mutex_release(tcp_data->data_mutex);
}
return err;
}
static int32_t f_iface_stream_read(t_x502_hnd hnd, uint32_t *buf, uint32_t size, uint32_t tout) {
t_tcp_iface_data *tcp_data = (t_tcp_iface_data*)hnd->iface_data;
int32_t recvd;
t_ltimer tmr;
if (tcp_data->data_sock == INVALID_SOCKET) {
recvd = X502_ERR_NO_DATA_CONNECTION;
} else {
ltimer_set(&tmr, LTIMER_MS_TO_CLOCK_TICKS(tout));
if (tcp_data->recv_part_size != 0) {
buf[0] = tcp_data->recv_part_wrd;
}
recvd = f_recv(tcp_data->data_sock, (uint8_t*)buf + tcp_data->recv_part_size,
size *sizeof(buf[0]) - tcp_data->recv_part_size, &tmr);
if (recvd > 0) {
recvd += tcp_data->recv_part_size;
tcp_data->recv_part_size = recvd % sizeof(buf[0]);
recvd /= sizeof(buf[0]);
if (tcp_data->recv_part_size!=0) {
tcp_data->recv_part_wrd = buf[recvd];
}
}
}
return recvd;
}
static int32_t f_iface_stream_write(t_x502_hnd hnd, const uint32_t *buf, uint32_t size, uint32_t tout) {
int32_t sent = 0;
t_ltimer tmr;
t_tcp_iface_data *tcp_data = (t_tcp_iface_data*)hnd->iface_data;
if (tcp_data->data_sock == INVALID_SOCKET) {
sent = X502_ERR_NO_DATA_CONNECTION;
} else {
ltimer_set(&tmr, LTIMER_MS_TO_CLOCK_TICKS(tout));
/* проверяем, не осталось ли не переданного некратного слова => если осталось
* то пробуем сперва дослать его */
if (tcp_data->send_part_size!=0) {
sent = f_send(tcp_data->data_sock, (uint8_t*)&tcp_data->send_part_wrd,
tcp_data->send_part_size, &tmr);
if (sent >= 0) {
tcp_data->send_part_size -= (uint8_t)sent;
if (tcp_data->send_part_size != 0) {
tcp_data->send_part_wrd >>= 8*sent;
}
sent = 0;
}
}
/* новые данные пересылаем только если старое неполное слово точно ушло */
if ((sent == 0) && (tcp_data->send_part_size==0)) {
sent = f_send(tcp_data->data_sock, (uint8_t*)buf, size * sizeof(buf[0]), &tmr);
if (sent >= 0) {
/* если не полностью передали последнее слово, то нужно сохранить
* остаток слова, чтобы потом передать его */
tcp_data->send_part_size = sent % sizeof(buf[0]);
sent /= sizeof(buf[0]);
if (tcp_data->send_part_size!=0) {
tcp_data->send_part_wrd = buf[sent] >> (8*tcp_data->send_part_size);
tcp_data->send_part_size = sizeof(buf[0]) - tcp_data->send_part_size;
sent++;
}
}
}
}
return sent;
}
static int32_t f_iface_stream_get_rdy_cnt(t_x502_hnd hnd, uint32_t ch, uint32_t *rdy_cnt) {
int32_t err = 0;
t_tcp_iface_data *tcp_data = (t_tcp_iface_data *)hnd->iface_data;
#ifdef _WIN32
if (ch == X502_STREAM_CH_IN) {
u_long val;
if (ioctlsocket(tcp_data->data_sock, FIONREAD, &val) == SOCKET_ERROR) {
err = X502_ERR_IOCTL_FAILD;
} else {
*rdy_cnt = val/4;
}
} else {
err = X502_ERR_NOT_IMPLEMENTED;
}
#else
if (ch == X502_STREAM_CH_IN) {
int val;
if (ioctl(tcp_data->data_sock, SIOCINQ, &val)==-1) {
err = X502_ERR_IOCTL_FAILD;
} else {
*rdy_cnt = val/4;
}
} else {
err = X502_ERR_NOT_IMPLEMENTED;
#if 0
/* Данный вариант в реальности не работает корректно */
int buf_len, val;
socklen_t optlen = sizeof(buf_len);
if (getsockopt(tcp_data->data_sock, SOL_SOCKET, SO_SNDBUF, (char*)&buf_len, &optlen)==SOCKET_ERROR) {
err = X502_ERR_IOCTL_FAILD;
} else if (ioctl(tcp_data->data_sock, SIOCOUTQ, &val)==-1) {
err = X502_ERR_IOCTL_FAILD;
} else {
*rdy_cnt = (buf_len - val)/4;
}
#endif
}
#endif
return err;
}
int32_t e502_make_tcp_rec(t_x502_devrec *devrec, uint32_t flags, uint32_t tout, char const *devname) {
int32_t err = (devrec == NULL) ? X502_ERR_INVALID_DEVICE_RECORD : X502_ERR_OK;
X502_DevRecordInit(devrec);
if (err==X502_ERR_OK) {
t_tcp_devinfo_data *devinfo_data = malloc(sizeof(t_tcp_devinfo_data));
t_x502_devrec_inptr *devinfo_ptr = malloc(sizeof(t_x502_devrec_inptr));
if ((devinfo_data==NULL) || (devinfo_ptr == NULL)) {
err = X502_ERR_MEMORY_ALLOC;
} else {
strcpy(devrec->devname, devname);
devinfo_data->cmd_port = E502_TCP_DEFAULT_CMD_PORT;
devinfo_data->data_port = E502_TCP_DEFAULT_DATA_PORT;
devinfo_data->open_tout = tout;
devinfo_data->flags = flags;
devinfo_ptr->iface = &f_tcp_iface;
devinfo_ptr->iface_data = devinfo_data;
devrec->internal = devinfo_ptr;
devrec->iface = X502_IFACE_ETH;
devrec->flags = X502_DEVFLAGS_IFACE_SUPPORT_USB | X502_DEVFLAGS_IFACE_SUPPORT_ETH;
}
if (err != X502_ERR_OK) {
free(devinfo_data);
free(devinfo_ptr);
}
}
return err;
}
X502_EXPORT(int32_t) E502_MakeDevRecordByIpAddr2(t_x502_devrec *devrec, uint32_t ip_addr,
uint32_t flags, uint32_t tout, char const *devname) {
int32_t err = e502_make_tcp_rec(devrec, flags, tout, devname);
if (err == X502_ERR_OK) {
t_tcp_devinfo_data *devinfo_data = (t_tcp_devinfo_data *)devrec->internal->iface_data;
devinfo_data->ip_addr = ip_addr;
#ifdef ENABLE_DNSSD
devinfo_data->svc_rec = NULL;
#endif
sprintf(devrec->location, "%d.%d.%d.%d",
(ip_addr>>24) & 0xFF,
(ip_addr>>16) & 0xFF,
(ip_addr>>8) & 0xFF,
(ip_addr>>0) & 0xFF);
devrec->location_type = X502_LOCATION_TYPE_ADDR;
}
return err;
}
X502_EXPORT(int32_t) E502_MakeDevRecordByIpAddr(t_x502_devrec *devrec, uint32_t ip_addr,
uint32_t flags, uint32_t tout) {
return E502_MakeDevRecordByIpAddr2(devrec, ip_addr, flags, tout, E502_DEVICE_NAME);
}
X502_EXPORT(int32_t) E502_EthDevRecordSetCmdPort(t_x502_devrec *devrec, uint16_t cmd_port) {
int32_t err = ((devrec == NULL) || (devrec->internal->iface != &f_tcp_iface)) ?
X502_ERR_INVALID_DEVICE_RECORD : X502_ERR_OK;
if (err == X502_ERR_OK) {
t_tcp_devinfo_data *devinfo_data = (t_tcp_devinfo_data *)devrec->internal->iface_data;
devinfo_data->cmd_port = cmd_port;
}
return err;
}
X502_EXPORT(int32_t) E502_EthDevRecordSetDataPort(t_x502_devrec *devrec, uint16_t data_port) {
int32_t err = ((devrec == NULL) || (devrec->internal->iface != &f_tcp_iface)) ?
X502_ERR_INVALID_DEVICE_RECORD : X502_ERR_OK;
if (err == X502_ERR_OK) {
t_tcp_devinfo_data *devinfo_data = (t_tcp_devinfo_data *)devrec->internal->iface_data;
devinfo_data->data_port = data_port;
}
return err;
}
X502_EXPORT(int32_t) E16_OpenByIpAddr(t_x502_hnd hnd, uint32_t ip_addr, uint32_t flags, uint32_t tout) {
int32_t err = X502_CHECK_HND(hnd);
if (err == X502_ERR_OK) {
t_x502_devrec devinfo;
err = E502_MakeDevRecordByIpAddr2(&devinfo, ip_addr, flags, tout, E16_DEVICE_NAME);
if (err == X502_ERR_OK) {
err = X502_OpenByDevRecord(hnd, &devinfo);
X502_FreeDevRecordList(&devinfo, 1);
}
}
return err;
}
X502_EXPORT(int32_t) E502_OpenByIpAddr(t_x502_hnd hnd, uint32_t ip_addr, uint32_t flags, uint32_t tout) {
int32_t err = X502_CHECK_HND(hnd);
if (err == X502_ERR_OK) {
t_x502_devrec devinfo;
err = E502_MakeDevRecordByIpAddr(&devinfo, ip_addr, flags, tout);
if (err == X502_ERR_OK) {
err = X502_OpenByDevRecord(hnd, &devinfo);
X502_FreeDevRecordList(&devinfo, 1);
}
}
return err;
}
X502_EXPORT(int32_t) E502_GetIpAddr(t_x502_hnd hnd, uint32_t *ip_addr) {
int32_t err = X502_CHECK_HND_OPENED(hnd);
if (err == X502_ERR_OK) {
if (hnd->iface != X502_IFACE_ETH) {
err = X502_ERR_INVALID_OP_FOR_IFACE;
} else {
t_tcp_iface_data *tcp_data = (t_tcp_iface_data *)hnd->iface_data;
*ip_addr = tcp_data->ip_addr;
}
}
return err;
}
#else
#include "e502api.h"
X502_EXPORT(int32_t) E502_MakeDevRecordByIpAddr(t_x502_devrec *devrec, uint32_t ip_addr,
uint32_t flags, uint32_t tout) {
return X502_ERR_NOT_IMPLEMENTED;
}
X502_EXPORT(int32_t) E502_EthDevRecordSetCmdPort(t_x502_devrec *devrec, uint16_t cmd_port) {
return X502_ERR_NOT_IMPLEMENTED;
}
X502_EXPORT(int32_t) E502_EthDevRecordSetDataPort(t_x502_devrec *devrec, uint16_t data_port) {
return X502_ERR_NOT_IMPLEMENTED;
}
X502_EXPORT(int32_t) E502_OpenByIpAddr(t_x502_hnd hnd, uint32_t ip_addr, uint32_t flags, uint32_t tout) {
return X502_ERR_NOT_IMPLEMENTED;
}
X502_EXPORT(int32_t) E502_GetIpAddr(t_x502_hnd hnd, uint32_t *ip_addr) {
return X502_ERR_NOT_IMPLEMENTED;
}
#endif

View File

@ -0,0 +1,21 @@
#ifndef E502API_TCP_PRIVATE_H
#define E502API_TCP_PRIVATE_H
#include "e502api_private.h"
typedef struct {
uint16_t cmd_port;
uint16_t data_port;
uint32_t ip_addr;
uint32_t open_tout;
uint32_t flags;
#ifdef ENABLE_DNSSD
t_e502_eth_svc_record_hnd svc_rec;
#endif
} t_tcp_devinfo_data;
int32_t e502_make_tcp_rec(t_x502_devrec *devrec, uint32_t flags, uint32_t tout, char const *devname);
int32_t e502_svc_fill_devinfo(t_tcp_devinfo_data *data);
#endif // E502API_TCP_PRIVATE_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,75 @@
all: libusb-1.0.la libusb-1.0.dll
AUTOMAKE_OPTIONS = subdir-objects
lib_LTLIBRARIES = libusb-1.0.la
POSIX_POLL_SRC = os/poll_posix.c
LINUX_USBFS_SRC = os/linux_usbfs.c
DARWIN_USB_SRC = os/darwin_usb.c
OPENBSD_USB_SRC = os/openbsd_usb.c
NETBSD_USB_SRC = os/netbsd_usb.c
WINDOWS_USB_SRC = os/poll_windows.c os/windows_usb.c libusb-1.0.rc libusb-1.0.def
WINCE_USB_SRC = os/wince_usb.c os/wince_usb.h
EXTRA_DIST = $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) $(OPENBSD_USB_SRC) \
$(NETBSD_USB_SRC) $(WINDOWS_USB_SRC) $(WINCE_USB_SRC) \
$(POSIX_POLL_SRC) \
os/threads_posix.c os/threads_windows.c \
os/linux_udev.c os/linux_netlink.c
if OS_LINUX
if USE_UDEV
OS_SRC = $(LINUX_USBFS_SRC) $(POSIX_POLL_SRC) \
os/linux_udev.c
else
OS_SRC = $(LINUX_USBFS_SRC) $(POSIX_POLL_SRC) \
os/linux_netlink.c
endif
endif
if OS_DARWIN
OS_SRC = $(DARWIN_USB_SRC) $(POSIX_POLL_SRC)
AM_CFLAGS_EXT = -no-cpp-precomp
endif
if OS_OPENBSD
OS_SRC = $(OPENBSD_USB_SRC) $(POSIX_POLL_SRC)
endif
if OS_NETBSD
OS_SRC = $(NETBSD_USB_SRC) $(POSIX_POLL_SRC)
endif
if OS_WINDOWS
OS_SRC = $(WINDOWS_USB_SRC)
.rc.lo:
$(AM_V_GEN)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(RCFLAGS) -i $< -o $@
libusb-1.0.rc: version.h version_nano.h
endif
libusb-1.0.dll: libusb-1.0.def libusb-1.0.la
if CREATE_IMPORT_LIB
# Rebuild the import lib from the .def so that MS and MinGW DLLs can be interchanged
$(AM_V_GEN)$(DLLTOOL) $(DLLTOOLFLAGS) --kill-at --input-def $(srcdir)/libusb-1.0.def --dllname $@ --output-lib .libs/$@.a
endif
if THREADS_POSIX
THREADS_SRC = os/threads_posix.h os/threads_posix.c
else
THREADS_SRC = os/threads_windows.h os/threads_windows.c
endif
libusb_1_0_la_CFLAGS = $(AM_CFLAGS)
libusb_1_0_la_LDFLAGS = $(LTLDFLAGS)
libusb_1_0_la_SOURCES = libusbi.h core.c descriptor.c io.c strerror.c sync.c \
os/linux_usbfs.h os/darwin_usb.h os/windows_usb.h os/windows_common.h \
hotplug.h hotplug.c $(THREADS_SRC) $(OS_SRC) \
os/poll_posix.h os/poll_windows.h
hdrdir = $(includedir)/libusb-1.0
hdr_HEADERS = libusb.h

View File

@ -0,0 +1,914 @@
# Makefile.in generated by automake 1.14.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = libusb
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp $(hdr_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/libusb/version.h $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(hdrdir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libusb_1_0_la_LIBADD =
am__libusb_1_0_la_SOURCES_DIST = libusbi.h core.c descriptor.c io.c \
strerror.c sync.c os/linux_usbfs.h os/darwin_usb.h \
os/windows_usb.h os/windows_common.h hotplug.h hotplug.c \
os/threads_windows.h os/threads_windows.c os/threads_posix.h \
os/threads_posix.c os/darwin_usb.c os/poll_posix.c \
os/linux_usbfs.c os/linux_netlink.c os/linux_udev.c \
os/netbsd_usb.c os/openbsd_usb.c os/poll_windows.c \
os/windows_usb.c libusb-1.0.rc libusb-1.0.def os/poll_posix.h \
os/poll_windows.h
am__dirstamp = $(am__leading_dot)dirstamp
@THREADS_POSIX_FALSE@am__objects_1 = \
@THREADS_POSIX_FALSE@ os/libusb_1_0_la-threads_windows.lo
@THREADS_POSIX_TRUE@am__objects_1 = os/libusb_1_0_la-threads_posix.lo
am__objects_2 = os/libusb_1_0_la-darwin_usb.lo
am__objects_3 = os/libusb_1_0_la-poll_posix.lo
am__objects_4 = os/libusb_1_0_la-linux_usbfs.lo
am__objects_5 = os/libusb_1_0_la-netbsd_usb.lo
am__objects_6 = os/libusb_1_0_la-openbsd_usb.lo
am__objects_7 = os/libusb_1_0_la-poll_windows.lo \
os/libusb_1_0_la-windows_usb.lo libusb-1.0.lo
@OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_FALSE@@OS_WINDOWS_TRUE@am__objects_8 = $(am__objects_7)
@OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_TRUE@am__objects_8 = $(am__objects_6) \
@OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_FALSE@@OS_OPENBSD_TRUE@ $(am__objects_3)
@OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_TRUE@am__objects_8 = $(am__objects_5) \
@OS_DARWIN_FALSE@@OS_LINUX_FALSE@@OS_NETBSD_TRUE@ $(am__objects_3)
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_FALSE@am__objects_8 = $(am__objects_4) \
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_FALSE@ $(am__objects_3) \
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_FALSE@ os/libusb_1_0_la-linux_netlink.lo
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_TRUE@am__objects_8 = $(am__objects_4) \
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_TRUE@ $(am__objects_3) \
@OS_DARWIN_FALSE@@OS_LINUX_TRUE@@USE_UDEV_TRUE@ os/libusb_1_0_la-linux_udev.lo
@OS_DARWIN_TRUE@am__objects_8 = $(am__objects_2) $(am__objects_3)
am_libusb_1_0_la_OBJECTS = libusb_1_0_la-core.lo \
libusb_1_0_la-descriptor.lo libusb_1_0_la-io.lo \
libusb_1_0_la-strerror.lo libusb_1_0_la-sync.lo \
libusb_1_0_la-hotplug.lo $(am__objects_1) $(am__objects_8)
libusb_1_0_la_OBJECTS = $(am_libusb_1_0_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
libusb_1_0_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libusb_1_0_la_CFLAGS) \
$(CFLAGS) $(libusb_1_0_la_LDFLAGS) $(LDFLAGS) -o $@
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libusb_1_0_la_SOURCES)
DIST_SOURCES = $(am__libusb_1_0_la_SOURCES_DIST)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
HEADERS = $(hdr_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_CFLAGS = @AM_CFLAGS@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLDFLAGS = @LTLDFLAGS@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OS_DARWIN = @OS_DARWIN@
OS_LINUX = @OS_LINUX@
OS_NETBSD = @OS_NETBSD@
OS_OPENBSD = @OS_OPENBSD@
OS_WINDOWS = @OS_WINDOWS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
RC = @RC@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
USE_UDEV = @USE_UDEV@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = subdir-objects
lib_LTLIBRARIES = libusb-1.0.la
POSIX_POLL_SRC = os/poll_posix.c
LINUX_USBFS_SRC = os/linux_usbfs.c
DARWIN_USB_SRC = os/darwin_usb.c
OPENBSD_USB_SRC = os/openbsd_usb.c
NETBSD_USB_SRC = os/netbsd_usb.c
WINDOWS_USB_SRC = os/poll_windows.c os/windows_usb.c libusb-1.0.rc libusb-1.0.def
WINCE_USB_SRC = os/wince_usb.c os/wince_usb.h
EXTRA_DIST = $(LINUX_USBFS_SRC) $(DARWIN_USB_SRC) $(OPENBSD_USB_SRC) \
$(NETBSD_USB_SRC) $(WINDOWS_USB_SRC) $(WINCE_USB_SRC) \
$(POSIX_POLL_SRC) \
os/threads_posix.c os/threads_windows.c \
os/linux_udev.c os/linux_netlink.c
@OS_DARWIN_TRUE@OS_SRC = $(DARWIN_USB_SRC) $(POSIX_POLL_SRC)
@OS_LINUX_TRUE@@USE_UDEV_FALSE@OS_SRC = $(LINUX_USBFS_SRC) $(POSIX_POLL_SRC) \
@OS_LINUX_TRUE@@USE_UDEV_FALSE@ os/linux_netlink.c
@OS_LINUX_TRUE@@USE_UDEV_TRUE@OS_SRC = $(LINUX_USBFS_SRC) $(POSIX_POLL_SRC) \
@OS_LINUX_TRUE@@USE_UDEV_TRUE@ os/linux_udev.c
@OS_NETBSD_TRUE@OS_SRC = $(NETBSD_USB_SRC) $(POSIX_POLL_SRC)
@OS_OPENBSD_TRUE@OS_SRC = $(OPENBSD_USB_SRC) $(POSIX_POLL_SRC)
@OS_WINDOWS_TRUE@OS_SRC = $(WINDOWS_USB_SRC)
@OS_DARWIN_TRUE@AM_CFLAGS_EXT = -no-cpp-precomp
@THREADS_POSIX_FALSE@THREADS_SRC = os/threads_windows.h os/threads_windows.c
@THREADS_POSIX_TRUE@THREADS_SRC = os/threads_posix.h os/threads_posix.c
libusb_1_0_la_CFLAGS = $(AM_CFLAGS)
libusb_1_0_la_LDFLAGS = $(LTLDFLAGS)
libusb_1_0_la_SOURCES = libusbi.h core.c descriptor.c io.c strerror.c sync.c \
os/linux_usbfs.h os/darwin_usb.h os/windows_usb.h os/windows_common.h \
hotplug.h hotplug.c $(THREADS_SRC) $(OS_SRC) \
os/poll_posix.h os/poll_windows.h
hdrdir = $(includedir)/libusb-1.0
hdr_HEADERS = libusb.h
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj .rc
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libusb/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu libusb/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
list2="$$list2 $$p"; \
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
os/$(am__dirstamp):
@$(MKDIR_P) os
@: > os/$(am__dirstamp)
os/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) os/$(DEPDIR)
@: > os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-threads_windows.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-threads_posix.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-darwin_usb.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-poll_posix.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-linux_usbfs.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-linux_netlink.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-linux_udev.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-netbsd_usb.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-openbsd_usb.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-poll_windows.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp)
os/libusb_1_0_la-windows_usb.lo: os/$(am__dirstamp) \
os/$(DEPDIR)/$(am__dirstamp)
libusb-1.0.la: $(libusb_1_0_la_OBJECTS) $(libusb_1_0_la_DEPENDENCIES) $(EXTRA_libusb_1_0_la_DEPENDENCIES)
$(AM_V_CCLD)$(libusb_1_0_la_LINK) -rpath $(libdir) $(libusb_1_0_la_OBJECTS) $(libusb_1_0_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
-rm -f os/*.$(OBJEXT)
-rm -f os/*.lo
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-core.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-descriptor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-hotplug.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-io.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-strerror.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusb_1_0_la-sync.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-darwin_usb.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-linux_netlink.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-linux_udev.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-linux_usbfs.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-netbsd_usb.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-openbsd_usb.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-poll_posix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-poll_windows.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-threads_posix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-threads_windows.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@os/$(DEPDIR)/libusb_1_0_la-windows_usb.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
libusb_1_0_la-core.lo: core.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-core.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-core.Tpo -c -o libusb_1_0_la-core.lo `test -f 'core.c' || echo '$(srcdir)/'`core.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-core.Tpo $(DEPDIR)/libusb_1_0_la-core.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='core.c' object='libusb_1_0_la-core.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-core.lo `test -f 'core.c' || echo '$(srcdir)/'`core.c
libusb_1_0_la-descriptor.lo: descriptor.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-descriptor.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-descriptor.Tpo -c -o libusb_1_0_la-descriptor.lo `test -f 'descriptor.c' || echo '$(srcdir)/'`descriptor.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-descriptor.Tpo $(DEPDIR)/libusb_1_0_la-descriptor.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='descriptor.c' object='libusb_1_0_la-descriptor.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-descriptor.lo `test -f 'descriptor.c' || echo '$(srcdir)/'`descriptor.c
libusb_1_0_la-io.lo: io.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-io.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-io.Tpo -c -o libusb_1_0_la-io.lo `test -f 'io.c' || echo '$(srcdir)/'`io.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-io.Tpo $(DEPDIR)/libusb_1_0_la-io.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='io.c' object='libusb_1_0_la-io.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-io.lo `test -f 'io.c' || echo '$(srcdir)/'`io.c
libusb_1_0_la-strerror.lo: strerror.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-strerror.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-strerror.Tpo -c -o libusb_1_0_la-strerror.lo `test -f 'strerror.c' || echo '$(srcdir)/'`strerror.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-strerror.Tpo $(DEPDIR)/libusb_1_0_la-strerror.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strerror.c' object='libusb_1_0_la-strerror.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-strerror.lo `test -f 'strerror.c' || echo '$(srcdir)/'`strerror.c
libusb_1_0_la-sync.lo: sync.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-sync.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-sync.Tpo -c -o libusb_1_0_la-sync.lo `test -f 'sync.c' || echo '$(srcdir)/'`sync.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-sync.Tpo $(DEPDIR)/libusb_1_0_la-sync.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sync.c' object='libusb_1_0_la-sync.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-sync.lo `test -f 'sync.c' || echo '$(srcdir)/'`sync.c
libusb_1_0_la-hotplug.lo: hotplug.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT libusb_1_0_la-hotplug.lo -MD -MP -MF $(DEPDIR)/libusb_1_0_la-hotplug.Tpo -c -o libusb_1_0_la-hotplug.lo `test -f 'hotplug.c' || echo '$(srcdir)/'`hotplug.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libusb_1_0_la-hotplug.Tpo $(DEPDIR)/libusb_1_0_la-hotplug.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hotplug.c' object='libusb_1_0_la-hotplug.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o libusb_1_0_la-hotplug.lo `test -f 'hotplug.c' || echo '$(srcdir)/'`hotplug.c
os/libusb_1_0_la-threads_windows.lo: os/threads_windows.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-threads_windows.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-threads_windows.Tpo -c -o os/libusb_1_0_la-threads_windows.lo `test -f 'os/threads_windows.c' || echo '$(srcdir)/'`os/threads_windows.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-threads_windows.Tpo os/$(DEPDIR)/libusb_1_0_la-threads_windows.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/threads_windows.c' object='os/libusb_1_0_la-threads_windows.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-threads_windows.lo `test -f 'os/threads_windows.c' || echo '$(srcdir)/'`os/threads_windows.c
os/libusb_1_0_la-threads_posix.lo: os/threads_posix.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-threads_posix.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-threads_posix.Tpo -c -o os/libusb_1_0_la-threads_posix.lo `test -f 'os/threads_posix.c' || echo '$(srcdir)/'`os/threads_posix.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-threads_posix.Tpo os/$(DEPDIR)/libusb_1_0_la-threads_posix.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/threads_posix.c' object='os/libusb_1_0_la-threads_posix.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-threads_posix.lo `test -f 'os/threads_posix.c' || echo '$(srcdir)/'`os/threads_posix.c
os/libusb_1_0_la-darwin_usb.lo: os/darwin_usb.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-darwin_usb.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-darwin_usb.Tpo -c -o os/libusb_1_0_la-darwin_usb.lo `test -f 'os/darwin_usb.c' || echo '$(srcdir)/'`os/darwin_usb.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-darwin_usb.Tpo os/$(DEPDIR)/libusb_1_0_la-darwin_usb.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/darwin_usb.c' object='os/libusb_1_0_la-darwin_usb.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-darwin_usb.lo `test -f 'os/darwin_usb.c' || echo '$(srcdir)/'`os/darwin_usb.c
os/libusb_1_0_la-poll_posix.lo: os/poll_posix.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-poll_posix.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-poll_posix.Tpo -c -o os/libusb_1_0_la-poll_posix.lo `test -f 'os/poll_posix.c' || echo '$(srcdir)/'`os/poll_posix.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-poll_posix.Tpo os/$(DEPDIR)/libusb_1_0_la-poll_posix.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/poll_posix.c' object='os/libusb_1_0_la-poll_posix.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-poll_posix.lo `test -f 'os/poll_posix.c' || echo '$(srcdir)/'`os/poll_posix.c
os/libusb_1_0_la-linux_usbfs.lo: os/linux_usbfs.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-linux_usbfs.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-linux_usbfs.Tpo -c -o os/libusb_1_0_la-linux_usbfs.lo `test -f 'os/linux_usbfs.c' || echo '$(srcdir)/'`os/linux_usbfs.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-linux_usbfs.Tpo os/$(DEPDIR)/libusb_1_0_la-linux_usbfs.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/linux_usbfs.c' object='os/libusb_1_0_la-linux_usbfs.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-linux_usbfs.lo `test -f 'os/linux_usbfs.c' || echo '$(srcdir)/'`os/linux_usbfs.c
os/libusb_1_0_la-linux_netlink.lo: os/linux_netlink.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-linux_netlink.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-linux_netlink.Tpo -c -o os/libusb_1_0_la-linux_netlink.lo `test -f 'os/linux_netlink.c' || echo '$(srcdir)/'`os/linux_netlink.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-linux_netlink.Tpo os/$(DEPDIR)/libusb_1_0_la-linux_netlink.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/linux_netlink.c' object='os/libusb_1_0_la-linux_netlink.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-linux_netlink.lo `test -f 'os/linux_netlink.c' || echo '$(srcdir)/'`os/linux_netlink.c
os/libusb_1_0_la-linux_udev.lo: os/linux_udev.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-linux_udev.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-linux_udev.Tpo -c -o os/libusb_1_0_la-linux_udev.lo `test -f 'os/linux_udev.c' || echo '$(srcdir)/'`os/linux_udev.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-linux_udev.Tpo os/$(DEPDIR)/libusb_1_0_la-linux_udev.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/linux_udev.c' object='os/libusb_1_0_la-linux_udev.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-linux_udev.lo `test -f 'os/linux_udev.c' || echo '$(srcdir)/'`os/linux_udev.c
os/libusb_1_0_la-netbsd_usb.lo: os/netbsd_usb.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-netbsd_usb.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-netbsd_usb.Tpo -c -o os/libusb_1_0_la-netbsd_usb.lo `test -f 'os/netbsd_usb.c' || echo '$(srcdir)/'`os/netbsd_usb.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-netbsd_usb.Tpo os/$(DEPDIR)/libusb_1_0_la-netbsd_usb.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/netbsd_usb.c' object='os/libusb_1_0_la-netbsd_usb.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-netbsd_usb.lo `test -f 'os/netbsd_usb.c' || echo '$(srcdir)/'`os/netbsd_usb.c
os/libusb_1_0_la-openbsd_usb.lo: os/openbsd_usb.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-openbsd_usb.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-openbsd_usb.Tpo -c -o os/libusb_1_0_la-openbsd_usb.lo `test -f 'os/openbsd_usb.c' || echo '$(srcdir)/'`os/openbsd_usb.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-openbsd_usb.Tpo os/$(DEPDIR)/libusb_1_0_la-openbsd_usb.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/openbsd_usb.c' object='os/libusb_1_0_la-openbsd_usb.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-openbsd_usb.lo `test -f 'os/openbsd_usb.c' || echo '$(srcdir)/'`os/openbsd_usb.c
os/libusb_1_0_la-poll_windows.lo: os/poll_windows.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-poll_windows.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-poll_windows.Tpo -c -o os/libusb_1_0_la-poll_windows.lo `test -f 'os/poll_windows.c' || echo '$(srcdir)/'`os/poll_windows.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-poll_windows.Tpo os/$(DEPDIR)/libusb_1_0_la-poll_windows.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/poll_windows.c' object='os/libusb_1_0_la-poll_windows.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-poll_windows.lo `test -f 'os/poll_windows.c' || echo '$(srcdir)/'`os/poll_windows.c
os/libusb_1_0_la-windows_usb.lo: os/windows_usb.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -MT os/libusb_1_0_la-windows_usb.lo -MD -MP -MF os/$(DEPDIR)/libusb_1_0_la-windows_usb.Tpo -c -o os/libusb_1_0_la-windows_usb.lo `test -f 'os/windows_usb.c' || echo '$(srcdir)/'`os/windows_usb.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) os/$(DEPDIR)/libusb_1_0_la-windows_usb.Tpo os/$(DEPDIR)/libusb_1_0_la-windows_usb.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='os/windows_usb.c' object='os/libusb_1_0_la-windows_usb.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libusb_1_0_la_CFLAGS) $(CFLAGS) -c -o os/libusb_1_0_la-windows_usb.lo `test -f 'os/windows_usb.c' || echo '$(srcdir)/'`os/windows_usb.c
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
-rm -rf os/.libs os/_libs
install-hdrHEADERS: $(hdr_HEADERS)
@$(NORMAL_INSTALL)
@list='$(hdr_HEADERS)'; test -n "$(hdrdir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(hdrdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(hdrdir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(hdrdir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(hdrdir)" || exit $$?; \
done
uninstall-hdrHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(hdr_HEADERS)'; test -n "$(hdrdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(hdrdir)'; $(am__uninstall_files_from_dir)
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(hdrdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-rm -f os/$(DEPDIR)/$(am__dirstamp)
-rm -f os/$(am__dirstamp)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR) os/$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-hdrHEADERS
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR) os/$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-hdrHEADERS uninstall-libLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \
ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-hdrHEADERS install-html \
install-html-am install-info install-info-am \
install-libLTLIBRARIES install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am uninstall-hdrHEADERS \
uninstall-libLTLIBRARIES
all: libusb-1.0.la libusb-1.0.dll
@OS_WINDOWS_TRUE@.rc.lo:
@OS_WINDOWS_TRUE@ $(AM_V_GEN)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(RCFLAGS) -i $< -o $@
@OS_WINDOWS_TRUE@libusb-1.0.rc: version.h version_nano.h
libusb-1.0.dll: libusb-1.0.def libusb-1.0.la
# Rebuild the import lib from the .def so that MS and MinGW DLLs can be interchanged
@CREATE_IMPORT_LIB_TRUE@ $(AM_V_GEN)$(DLLTOOL) $(DLLTOOLFLAGS) --kill-at --input-def $(srcdir)/libusb-1.0.def --dllname $@ --output-lib .libs/$@.a
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,327 @@
/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
/*
* Hotplug functions for libusb
* Copyright © 2012-2013 Nathan Hjelm <hjelmn@mac.com>
* Copyright © 2012-2013 Peter Stuge <peter@stuge.se>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <config.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <assert.h>
#include "libusbi.h"
#include "hotplug.h"
/**
* @defgroup hotplug Device hotplug event notification
* This page details how to use the libusb hotplug interface, where available.
*
* Be mindful that not all platforms currently implement hotplug notification and
* that you should first call on \ref libusb_has_capability() with parameter
* \ref LIBUSB_CAP_HAS_HOTPLUG to confirm that hotplug support is available.
*
* \page hotplug Device hotplug event notification
*
* \section intro Introduction
*
* Version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102, has added support
* for hotplug events on <b>some</b> platforms (you should test if your platform
* supports hotplug notification by calling \ref libusb_has_capability() with
* parameter \ref LIBUSB_CAP_HAS_HOTPLUG).
*
* This interface allows you to request notification for the arrival and departure
* of matching USB devices.
*
* To receive hotplug notification you register a callback by calling
* \ref libusb_hotplug_register_callback(). This function will optionally return
* a handle that can be passed to \ref libusb_hotplug_deregister_callback().
*
* A callback function must return an int (0 or 1) indicating whether the callback is
* expecting additional events. Returning 0 will rearm the callback and 1 will cause
* the callback to be deregistered. Note that when callbacks are called from
* libusb_hotplug_register_callback() because of the \ref LIBUSB_HOTPLUG_ENUMERATE
* flag, the callback return value is ignored, iow you cannot cause a callback
* to be deregistered by returning 1 when it is called from
* libusb_hotplug_register_callback().
*
* Callbacks for a particular context are automatically deregistered by libusb_exit().
*
* As of 1.0.16 there are two supported hotplug events:
* - LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED: A device has arrived and is ready to use
* - LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT: A device has left and is no longer available
*
* A hotplug event can listen for either or both of these events.
*
* Note: If you receive notification that a device has left and you have any
* a libusb_device_handles for the device it is up to you to call libusb_close()
* on each handle to free up any remaining resources associated with the device.
* Once a device has left any libusb_device_handle associated with the device
* are invalid and will remain so even if the device comes back.
*
* When handling a LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED event it is considered
* safe to call any libusb function that takes a libusb_device. On the other hand,
* when handling a LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT event the only safe function
* is libusb_get_device_descriptor().
*
* The following code provides an example of the usage of the hotplug interface:
\code
#include <stdio.h>
#include <stdlib.h>
#include <libusb.h>
static int count = 0;
int hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev,
libusb_hotplug_event event, void *user_data) {
static libusb_device_handle *handle = NULL;
struct libusb_device_descriptor desc;
int rc;
(void)libusb_get_device_descriptor(dev, &desc);
if (LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED == event) {
rc = libusb_open(dev, &handle);
if (LIBUSB_SUCCESS != rc) {
printf("Could not open USB device\n");
}
} else if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == event) {
if (handle) {
libusb_close(handle);
handle = NULL;
}
} else {
printf("Unhandled event %d\n", event);
}
count++;
return 0;
}
int main (void) {
libusb_hotplug_callback_handle handle;
int rc;
libusb_init(NULL);
rc = libusb_hotplug_register_callback(NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, 0x045a, 0x5005,
LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, NULL,
&handle);
if (LIBUSB_SUCCESS != rc) {
printf("Error creating a hotplug callback\n");
libusb_exit(NULL);
return EXIT_FAILURE;
}
while (count < 2) {
libusb_handle_events_completed(NULL, NULL);
usleep(10000);
}
libusb_hotplug_deregister_callback(NULL, handle);
libusb_exit(NULL);
return 0;
}
\endcode
*/
static int usbi_hotplug_match_cb (struct libusb_context *ctx,
struct libusb_device *dev, libusb_hotplug_event event,
struct libusb_hotplug_callback *hotplug_cb)
{
/* Handle lazy deregistration of callback */
if (hotplug_cb->needs_free) {
/* Free callback */
return 1;
}
if (!(hotplug_cb->events & event)) {
return 0;
}
if (LIBUSB_HOTPLUG_MATCH_ANY != hotplug_cb->vendor_id &&
hotplug_cb->vendor_id != dev->device_descriptor.idVendor) {
return 0;
}
if (LIBUSB_HOTPLUG_MATCH_ANY != hotplug_cb->product_id &&
hotplug_cb->product_id != dev->device_descriptor.idProduct) {
return 0;
}
if (LIBUSB_HOTPLUG_MATCH_ANY != hotplug_cb->dev_class &&
hotplug_cb->dev_class != dev->device_descriptor.bDeviceClass) {
return 0;
}
return hotplug_cb->cb (ctx, dev, event, hotplug_cb->user_data);
}
void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev,
libusb_hotplug_event event)
{
struct libusb_hotplug_callback *hotplug_cb, *next;
int ret;
usbi_mutex_lock(&ctx->hotplug_cbs_lock);
list_for_each_entry_safe(hotplug_cb, next, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) {
usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
ret = usbi_hotplug_match_cb (ctx, dev, event, hotplug_cb);
usbi_mutex_lock(&ctx->hotplug_cbs_lock);
if (ret) {
list_del(&hotplug_cb->list);
free(hotplug_cb);
}
}
usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
/* the backend is expected to call the callback for each active transfer */
}
int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx,
libusb_hotplug_event events, libusb_hotplug_flag flags,
int vendor_id, int product_id, int dev_class,
libusb_hotplug_callback_fn cb_fn, void *user_data,
libusb_hotplug_callback_handle *handle)
{
libusb_hotplug_callback *new_callback;
static int handle_id = 1;
/* check for hotplug support */
if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
return LIBUSB_ERROR_NOT_SUPPORTED;
}
/* check for sane values */
if ((LIBUSB_HOTPLUG_MATCH_ANY != vendor_id && (~0xffff & vendor_id)) ||
(LIBUSB_HOTPLUG_MATCH_ANY != product_id && (~0xffff & product_id)) ||
(LIBUSB_HOTPLUG_MATCH_ANY != dev_class && (~0xff & dev_class)) ||
!cb_fn) {
return LIBUSB_ERROR_INVALID_PARAM;
}
USBI_GET_CONTEXT(ctx);
new_callback = (libusb_hotplug_callback *)calloc(1, sizeof (*new_callback));
if (!new_callback) {
return LIBUSB_ERROR_NO_MEM;
}
new_callback->ctx = ctx;
new_callback->vendor_id = vendor_id;
new_callback->product_id = product_id;
new_callback->dev_class = dev_class;
new_callback->flags = flags;
new_callback->events = events;
new_callback->cb = cb_fn;
new_callback->user_data = user_data;
new_callback->needs_free = 0;
usbi_mutex_lock(&ctx->hotplug_cbs_lock);
/* protect the handle by the context hotplug lock. it doesn't matter if the same handle
* is used for different contexts only that the handle is unique for this context */
new_callback->handle = handle_id++;
list_add(&new_callback->list, &ctx->hotplug_cbs);
usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
if (flags & LIBUSB_HOTPLUG_ENUMERATE) {
int i, len;
struct libusb_device **devs;
len = (int) libusb_get_device_list(ctx, &devs);
if (len < 0) {
libusb_hotplug_deregister_callback(ctx,
new_callback->handle);
return len;
}
for (i = 0; i < len; i++) {
usbi_hotplug_match_cb(ctx, devs[i],
LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED,
new_callback);
}
libusb_free_device_list(devs, 1);
}
if (handle) {
*handle = new_callback->handle;
}
return LIBUSB_SUCCESS;
}
void API_EXPORTED libusb_hotplug_deregister_callback (struct libusb_context *ctx,
libusb_hotplug_callback_handle handle)
{
struct libusb_hotplug_callback *hotplug_cb;
libusb_hotplug_message message;
ssize_t ret;
/* check for hotplug support */
if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
return;
}
USBI_GET_CONTEXT(ctx);
usbi_mutex_lock(&ctx->hotplug_cbs_lock);
list_for_each_entry(hotplug_cb, &ctx->hotplug_cbs, list,
struct libusb_hotplug_callback) {
if (handle == hotplug_cb->handle) {
/* Mark this callback for deregistration */
hotplug_cb->needs_free = 1;
}
}
usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
/* wakeup handle_events to do the actual free */
memset(&message, 0, sizeof(message));
ret = usbi_write(ctx->hotplug_pipe[1], &message, sizeof(message));
if (sizeof(message) != ret) {
usbi_err(ctx, "error writing hotplug message");
}
}
void usbi_hotplug_deregister_all(struct libusb_context *ctx) {
struct libusb_hotplug_callback *hotplug_cb, *next;
usbi_mutex_lock(&ctx->hotplug_cbs_lock);
list_for_each_entry_safe(hotplug_cb, next, &ctx->hotplug_cbs, list,
struct libusb_hotplug_callback) {
list_del(&hotplug_cb->list);
free(hotplug_cb);
}
usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
}

View File

@ -0,0 +1,82 @@
/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
/*
* Hotplug support for libusb
* Copyright © 2012-2013 Nathan Hjelm <hjelmn@mac.com>
* Copyright © 2012-2013 Peter Stuge <peter@stuge.se>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if !defined(USBI_HOTPLUG_H)
#define USBI_HOTPLUG_H
#ifndef LIBUSBI_H
#include "libusbi.h"
#endif
/** \ingroup hotplug
* The hotplug callback structure. The user populates this structure with
* libusb_hotplug_prepare_callback() and then calls libusb_hotplug_register_callback()
* to receive notification of hotplug events.
*/
struct libusb_hotplug_callback {
/** Context this callback is associated with */
struct libusb_context *ctx;
/** Vendor ID to match or LIBUSB_HOTPLUG_MATCH_ANY */
int vendor_id;
/** Product ID to match or LIBUSB_HOTPLUG_MATCH_ANY */
int product_id;
/** Device class to match or LIBUSB_HOTPLUG_MATCH_ANY */
int dev_class;
/** Hotplug callback flags */
libusb_hotplug_flag flags;
/** Event(s) that will trigger this callback */
libusb_hotplug_event events;
/** Callback function to invoke for matching event/device */
libusb_hotplug_callback_fn cb;
/** Handle for this callback (used to match on deregister) */
libusb_hotplug_callback_handle handle;
/** User data that will be passed to the callback function */
void *user_data;
/** Callback is marked for deletion */
int needs_free;
/** List this callback is registered in (ctx->hotplug_cbs) */
struct list_head list;
};
typedef struct libusb_hotplug_callback libusb_hotplug_callback;
struct libusb_hotplug_message {
libusb_hotplug_event event;
struct libusb_device *device;
};
typedef struct libusb_hotplug_message libusb_hotplug_message;
void usbi_hotplug_deregister_all(struct libusb_context *ctx);
void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev,
libusb_hotplug_event event);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,166 @@
LIBRARY "libusb-1.0.dll"
EXPORTS
libusb_alloc_streams
libusb_alloc_streams@16 = libusb_alloc_streams
libusb_alloc_transfer
libusb_alloc_transfer@4 = libusb_alloc_transfer
libusb_attach_kernel_driver
libusb_attach_kernel_driver@8 = libusb_attach_kernel_driver
libusb_bulk_transfer
libusb_bulk_transfer@24 = libusb_bulk_transfer
libusb_cancel_transfer
libusb_cancel_transfer@4 = libusb_cancel_transfer
libusb_claim_interface
libusb_claim_interface@8 = libusb_claim_interface
libusb_clear_halt
libusb_clear_halt@8 = libusb_clear_halt
libusb_close
libusb_close@4 = libusb_close
libusb_control_transfer
libusb_control_transfer@32 = libusb_control_transfer
libusb_detach_kernel_driver
libusb_detach_kernel_driver@8 = libusb_detach_kernel_driver
libusb_error_name
libusb_error_name@4 = libusb_error_name
libusb_event_handler_active
libusb_event_handler_active@4 = libusb_event_handler_active
libusb_event_handling_ok
libusb_event_handling_ok@4 = libusb_event_handling_ok
libusb_exit
libusb_exit@4 = libusb_exit
libusb_free_bos_descriptor
libusb_free_bos_descriptor@4 = libusb_free_bos_descriptor
libusb_free_config_descriptor
libusb_free_config_descriptor@4 = libusb_free_config_descriptor
libusb_free_container_id_descriptor
libusb_free_container_id_descriptor@4 = libusb_free_container_id_descriptor
libusb_free_device_list
libusb_free_device_list@8 = libusb_free_device_list
libusb_free_ss_endpoint_companion_descriptor
libusb_free_ss_endpoint_companion_descriptor@4 = libusb_free_ss_endpoint_companion_descriptor
libusb_free_ss_usb_device_capability_descriptor
libusb_free_ss_usb_device_capability_descriptor@4 = libusb_free_ss_usb_device_capability_descriptor
libusb_free_streams
libusb_free_streams@12 = libusb_free_streams
libusb_free_transfer
libusb_free_transfer@4 = libusb_free_transfer
libusb_free_usb_2_0_extension_descriptor
libusb_free_usb_2_0_extension_descriptor@4 = libusb_free_usb_2_0_extension_descriptor
libusb_get_active_config_descriptor
libusb_get_active_config_descriptor@8 = libusb_get_active_config_descriptor
libusb_get_bos_descriptor
libusb_get_bos_descriptor@8 = libusb_get_bos_descriptor
libusb_get_bus_number
libusb_get_bus_number@4 = libusb_get_bus_number
libusb_get_config_descriptor
libusb_get_config_descriptor@12 = libusb_get_config_descriptor
libusb_get_config_descriptor_by_value
libusb_get_config_descriptor_by_value@12 = libusb_get_config_descriptor_by_value
libusb_get_configuration
libusb_get_configuration@8 = libusb_get_configuration
libusb_get_container_id_descriptor
libusb_get_container_id_descriptor@12 = libusb_get_container_id_descriptor
libusb_get_device
libusb_get_device@4 = libusb_get_device
libusb_get_device_address
libusb_get_device_address@4 = libusb_get_device_address
libusb_get_device_descriptor
libusb_get_device_descriptor@8 = libusb_get_device_descriptor
libusb_get_device_list
libusb_get_device_list@8 = libusb_get_device_list
libusb_get_device_speed
libusb_get_device_speed@4 = libusb_get_device_speed
libusb_get_max_iso_packet_size
libusb_get_max_iso_packet_size@8 = libusb_get_max_iso_packet_size
libusb_get_max_packet_size
libusb_get_max_packet_size@8 = libusb_get_max_packet_size
libusb_get_next_timeout
libusb_get_next_timeout@8 = libusb_get_next_timeout
libusb_get_parent
libusb_get_parent@4 = libusb_get_parent
libusb_get_pollfds
libusb_get_pollfds@4 = libusb_get_pollfds
libusb_get_port_number
libusb_get_port_number@4 = libusb_get_port_number
libusb_get_port_numbers
libusb_get_port_numbers@12 = libusb_get_port_numbers
libusb_get_port_path
libusb_get_port_path@16 = libusb_get_port_path
libusb_get_ss_endpoint_companion_descriptor
libusb_get_ss_endpoint_companion_descriptor@12 = libusb_get_ss_endpoint_companion_descriptor
libusb_get_ss_usb_device_capability_descriptor
libusb_get_ss_usb_device_capability_descriptor@12 = libusb_get_ss_usb_device_capability_descriptor
libusb_get_string_descriptor_ascii
libusb_get_string_descriptor_ascii@16 = libusb_get_string_descriptor_ascii
libusb_get_usb_2_0_extension_descriptor
libusb_get_usb_2_0_extension_descriptor@12 = libusb_get_usb_2_0_extension_descriptor
libusb_get_version
libusb_get_version@0 = libusb_get_version
libusb_handle_events
libusb_handle_events@4 = libusb_handle_events
libusb_handle_events_completed
libusb_handle_events_completed@8 = libusb_handle_events_completed
libusb_handle_events_locked
libusb_handle_events_locked@8 = libusb_handle_events_locked
libusb_handle_events_timeout
libusb_handle_events_timeout@8 = libusb_handle_events_timeout
libusb_handle_events_timeout_completed
libusb_handle_events_timeout_completed@12 = libusb_handle_events_timeout_completed
libusb_has_capability
libusb_has_capability@4 = libusb_has_capability
libusb_hotplug_deregister_callback
libusb_hotplug_deregister_callback@8 = libusb_hotplug_deregister_callback
libusb_hotplug_register_callback
libusb_hotplug_register_callback@36 = libusb_hotplug_register_callback
libusb_init
libusb_init@4 = libusb_init
libusb_interrupt_transfer
libusb_interrupt_transfer@24 = libusb_interrupt_transfer
libusb_kernel_driver_active
libusb_kernel_driver_active@8 = libusb_kernel_driver_active
libusb_lock_event_waiters
libusb_lock_event_waiters@4 = libusb_lock_event_waiters
libusb_lock_events
libusb_lock_events@4 = libusb_lock_events
libusb_open
libusb_open@8 = libusb_open
libusb_open_device_with_vid_pid
libusb_open_device_with_vid_pid@12 = libusb_open_device_with_vid_pid
libusb_pollfds_handle_timeouts
libusb_pollfds_handle_timeouts@4 = libusb_pollfds_handle_timeouts
libusb_ref_device
libusb_ref_device@4 = libusb_ref_device
libusb_release_interface
libusb_release_interface@8 = libusb_release_interface
libusb_reset_device
libusb_reset_device@4 = libusb_reset_device
libusb_set_auto_detach_kernel_driver
libusb_set_auto_detach_kernel_driver@8 = libusb_set_auto_detach_kernel_driver
libusb_set_configuration
libusb_set_configuration@8 = libusb_set_configuration
libusb_set_debug
libusb_set_debug@8 = libusb_set_debug
libusb_set_interface_alt_setting
libusb_set_interface_alt_setting@12 = libusb_set_interface_alt_setting
libusb_set_pollfd_notifiers
libusb_set_pollfd_notifiers@16 = libusb_set_pollfd_notifiers
libusb_setlocale
libusb_setlocale@4 = libusb_setlocale
libusb_strerror
libusb_strerror@4 = libusb_strerror
libusb_submit_transfer
libusb_submit_transfer@4 = libusb_submit_transfer
libusb_transfer_get_stream_id
libusb_transfer_get_stream_id@4 = libusb_transfer_get_stream_id
libusb_transfer_set_stream_id
libusb_transfer_set_stream_id@8 = libusb_transfer_set_stream_id
libusb_try_lock_events
libusb_try_lock_events@4 = libusb_try_lock_events
libusb_unlock_event_waiters
libusb_unlock_event_waiters@4 = libusb_unlock_event_waiters
libusb_unlock_events
libusb_unlock_events@4 = libusb_unlock_events
libusb_unref_device
libusb_unref_device@4 = libusb_unref_device
libusb_wait_for_event
libusb_wait_for_event@8 = libusb_wait_for_event

View File

@ -0,0 +1,61 @@
/*
* For Windows: input this file to the Resoure Compiler to produce a binary
* .res file. This is then embedded in the resultant library (like any other
* compilation object).
* The information can then be queried using standard APIs and can also be
* viewed with utilities such as Windows Explorer.
*/
#ifndef _WIN32_WCE
#include "winresrc.h"
#endif
#include "version.h"
#ifndef LIBUSB_VERSIONSTRING
#define LU_STR(s) #s
#define LU_XSTR(s) LU_STR(s)
#if LIBUSB_NANO > 0
#define LIBUSB_VERSIONSTRING \
LU_XSTR(LIBUSB_MAJOR) "." LU_XSTR(LIBUSB_MINOR) "." \
LU_XSTR(LIBUSB_MICRO) "." LU_XSTR(LIBUSB_NANO) LIBUSB_RC "\0"
#else
#define LIBUSB_VERSIONSTRING \
LU_XSTR(LIBUSB_MAJOR) "." LU_XSTR(LIBUSB_MINOR) "." \
LU_XSTR(LIBUSB_MICRO) LIBUSB_RC "\0"
#endif
#endif
VS_VERSION_INFO VERSIONINFO
FILEVERSION LIBUSB_MAJOR,LIBUSB_MINOR,LIBUSB_MICRO,LIBUSB_NANO
PRODUCTVERSION LIBUSB_MAJOR,LIBUSB_MINOR,LIBUSB_MICRO,LIBUSB_NANO
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "libusb.info\0"
VALUE "FileDescription", "C library for writing portable USB drivers in userspace\0"
VALUE "FileVersion", LIBUSB_VERSIONSTRING
VALUE "InternalName", "libusb\0"
VALUE "LegalCopyright", "See individual source files, GNU LGPL v2.1 or later.\0"
VALUE "LegalTrademarks", "http://www.gnu.org/licenses/lgpl-2.1.html\0"
VALUE "OriginalFilename", "libusb-1.0.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "libusb-1.0\0"
VALUE "ProductVersion", LIBUSB_VERSIONSTRING
VALUE "SpecialBuild", "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,42 @@
/* config.h. Manual config for MSVC. */
#ifndef _MSC_VER
#warn "msvc/config.h shouldn't be included for your development environment."
#error "Please make sure the msvc/ directory is removed from your build path."
#endif
/* Disable: warning C4200: nonstandard extension used : zero-sized array in struct/union */
#pragma warning(disable:4200)
/* Disable: warning C6258: Using TerminateThread does not allow proper thread clean up */
#pragma warning(disable: 6258)
#if defined(_PREFAST_)
/* Disable "Banned API" errors when using the MS's WDK OACR/Prefast */
#pragma warning(disable:28719)
/* Disable "The function 'InitializeCriticalSection' must be called from within a try/except block" */
#pragma warning(disable:28125)
#endif
/* Default visibility */
#define DEFAULT_VISIBILITY /**/
/* Enable global message logging */
#define ENABLE_LOGGING 1
/* Uncomment to start with debug message logging enabled */
// #define ENABLE_DEBUG_LOGGING 1
/* Uncomment to enabling logging to system log */
// #define USE_SYSTEM_LOGGING_FACILITY
/* type of second poll() argument */
#define POLL_NFDS_TYPE unsigned int
/* Windows/WinCE backend */
#if defined(_WIN32_WCE)
#define OS_WINCE 1
#define HAVE_MISSING_H
#else
#define OS_WINDOWS 1
#define HAVE_SIGNAL_H 1
#define HAVE_SYS_TYPES_H 1
#endif

View File

@ -0,0 +1,102 @@
/*
* errno.h
* This file has no copyright assigned and is placed in the Public Domain.
* This file is a part of the mingw-runtime package.
* No warranty is given; refer to the file DISCLAIMER within the package.
*
* Error numbers and access to error reporting.
*
*/
#ifndef _ERRNO_H_
#define _ERRNO_H_
#include <crtdefs.h>
/*
* Error numbers.
* TODO: Can't be sure of some of these assignments, I guessed from the
* names given by strerror and the defines in the Cygnus errno.h. A lot
* of the names from the Cygnus errno.h are not represented, and a few
* of the descriptions returned by strerror do not obviously match
* their error naming.
*/
#define EPERM 1 /* Operation not permitted */
#define ENOFILE 2 /* No such file or directory */
#define ENOENT 2
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted function call */
#define EIO 5 /* Input/output error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Arg list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file descriptor */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Resource temporarily unavailable */
#define ENOMEM 12 /* Not enough space */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
/* 15 - Unknown Error */
#define EBUSY 16 /* strerror reports "Resource device" */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Improper link (cross-device link?) */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* Too many open files in system */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Inappropriate I/O control operation */
/* 26 - Unknown Error */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Invalid seek (seek on a pipe?) */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Domain error (math functions) */
#define ERANGE 34 /* Result too large (possibly too small) */
/* 35 - Unknown Error */
#define EDEADLOCK 36 /* Resource deadlock avoided (non-Cyg) */
#define EDEADLK 36
#if 0
/* 37 - Unknown Error */
#define ENAMETOOLONG 38 /* Filename too long (91 in Cyg?) */
#define ENOLCK 39 /* No locks available (46 in Cyg?) */
#define ENOSYS 40 /* Function not implemented (88 in Cyg?) */
#define ENOTEMPTY 41 /* Directory not empty (90 in Cyg?) */
#define EILSEQ 42 /* Illegal byte sequence */
#endif
/*
* NOTE: ENAMETOOLONG and ENOTEMPTY conflict with definitions in the
* sockets.h header provided with windows32api-0.1.2.
* You should go and put an #if 0 ... #endif around the whole block
* of errors (look at the comment above them).
*/
#ifndef RC_INVOKED
#ifdef __cplusplus
extern "C" {
#endif
/*
* Definitions of errno. For _doserrno, sys_nerr and * sys_errlist, see
* stdlib.h.
*/
#if defined(_UWIN) || defined(_WIN32_WCE)
#undef errno
extern int errno;
#else
_CRTIMP int* __cdecl _errno(void);
#define errno (*_errno())
#endif
#ifdef __cplusplus
}
#endif
#endif /* Not RC_INVOKED */
#endif /* Not _ERRNO_H_ */

View File

@ -0,0 +1,295 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file was original part of the w64 mingw-runtime package.
*/
/*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* Modified for libusb/MSVC: Pete Batard <pbatard@gmail.com>
*
* This source code is offered for use in the public domain. You may
* use, modify or distribute it freely.
*
* This code is distributed in the hope that it will be useful but
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
* DISCLAIMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Date: 2010-04-02
*/
#ifndef _MSC_VER
#error This header should only be used with Microsoft compilers
#endif
/* 7.8 Format conversion of integer types <inttypes.h> */
#ifndef _INTTYPES_H_
#define _INTTYPES_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
intmax_t quot;
intmax_t rem;
} imaxdiv_t;
/* 7.8.1 Macros for format specifiers
*
* MS runtime does not yet understand C9x standard "ll"
* length specifier. It appears to treat "ll" as "l".
* The non-standard I64 length specifier causes warning in GCC,
* but understood by MS runtime functions.
*/
/* fprintf macros for signed types */
#define PRId8 "d"
#define PRId16 "d"
#define PRId32 "d"
#define PRId64 "I64d"
#define PRIdLEAST8 "d"
#define PRIdLEAST16 "d"
#define PRIdLEAST32 "d"
#define PRIdLEAST64 "I64d"
#define PRIdFAST8 "d"
#define PRIdFAST16 "d"
#define PRIdFAST32 "d"
#define PRIdFAST64 "I64d"
#define PRIdMAX "I64d"
#define PRIi8 "i"
#define PRIi16 "i"
#define PRIi32 "i"
#define PRIi64 "I64i"
#define PRIiLEAST8 "i"
#define PRIiLEAST16 "i"
#define PRIiLEAST32 "i"
#define PRIiLEAST64 "I64i"
#define PRIiFAST8 "i"
#define PRIiFAST16 "i"
#define PRIiFAST32 "i"
#define PRIiFAST64 "I64i"
#define PRIiMAX "I64i"
#define PRIo8 "o"
#define PRIo16 "o"
#define PRIo32 "o"
#define PRIo64 "I64o"
#define PRIoLEAST8 "o"
#define PRIoLEAST16 "o"
#define PRIoLEAST32 "o"
#define PRIoLEAST64 "I64o"
#define PRIoFAST8 "o"
#define PRIoFAST16 "o"
#define PRIoFAST32 "o"
#define PRIoFAST64 "I64o"
#define PRIoMAX "I64o"
/* fprintf macros for unsigned types */
#define PRIu8 "u"
#define PRIu16 "u"
#define PRIu32 "u"
#define PRIu64 "I64u"
#define PRIuLEAST8 "u"
#define PRIuLEAST16 "u"
#define PRIuLEAST32 "u"
#define PRIuLEAST64 "I64u"
#define PRIuFAST8 "u"
#define PRIuFAST16 "u"
#define PRIuFAST32 "u"
#define PRIuFAST64 "I64u"
#define PRIuMAX "I64u"
#define PRIx8 "x"
#define PRIx16 "x"
#define PRIx32 "x"
#define PRIx64 "I64x"
#define PRIxLEAST8 "x"
#define PRIxLEAST16 "x"
#define PRIxLEAST32 "x"
#define PRIxLEAST64 "I64x"
#define PRIxFAST8 "x"
#define PRIxFAST16 "x"
#define PRIxFAST32 "x"
#define PRIxFAST64 "I64x"
#define PRIxMAX "I64x"
#define PRIX8 "X"
#define PRIX16 "X"
#define PRIX32 "X"
#define PRIX64 "I64X"
#define PRIXLEAST8 "X"
#define PRIXLEAST16 "X"
#define PRIXLEAST32 "X"
#define PRIXLEAST64 "I64X"
#define PRIXFAST8 "X"
#define PRIXFAST16 "X"
#define PRIXFAST32 "X"
#define PRIXFAST64 "I64X"
#define PRIXMAX "I64X"
/*
* fscanf macros for signed int types
* NOTE: if 32-bit int is used for int_fast8_t and int_fast16_t
* (see stdint.h, 7.18.1.3), FAST8 and FAST16 should have
* no length identifiers
*/
#define SCNd16 "hd"
#define SCNd32 "d"
#define SCNd64 "I64d"
#define SCNdLEAST16 "hd"
#define SCNdLEAST32 "d"
#define SCNdLEAST64 "I64d"
#define SCNdFAST16 "hd"
#define SCNdFAST32 "d"
#define SCNdFAST64 "I64d"
#define SCNdMAX "I64d"
#define SCNi16 "hi"
#define SCNi32 "i"
#define SCNi64 "I64i"
#define SCNiLEAST16 "hi"
#define SCNiLEAST32 "i"
#define SCNiLEAST64 "I64i"
#define SCNiFAST16 "hi"
#define SCNiFAST32 "i"
#define SCNiFAST64 "I64i"
#define SCNiMAX "I64i"
#define SCNo16 "ho"
#define SCNo32 "o"
#define SCNo64 "I64o"
#define SCNoLEAST16 "ho"
#define SCNoLEAST32 "o"
#define SCNoLEAST64 "I64o"
#define SCNoFAST16 "ho"
#define SCNoFAST32 "o"
#define SCNoFAST64 "I64o"
#define SCNoMAX "I64o"
#define SCNx16 "hx"
#define SCNx32 "x"
#define SCNx64 "I64x"
#define SCNxLEAST16 "hx"
#define SCNxLEAST32 "x"
#define SCNxLEAST64 "I64x"
#define SCNxFAST16 "hx"
#define SCNxFAST32 "x"
#define SCNxFAST64 "I64x"
#define SCNxMAX "I64x"
/* fscanf macros for unsigned int types */
#define SCNu16 "hu"
#define SCNu32 "u"
#define SCNu64 "I64u"
#define SCNuLEAST16 "hu"
#define SCNuLEAST32 "u"
#define SCNuLEAST64 "I64u"
#define SCNuFAST16 "hu"
#define SCNuFAST32 "u"
#define SCNuFAST64 "I64u"
#define SCNuMAX "I64u"
#ifdef _WIN64
#define PRIdPTR "I64d"
#define PRIiPTR "I64i"
#define PRIoPTR "I64o"
#define PRIuPTR "I64u"
#define PRIxPTR "I64x"
#define PRIXPTR "I64X"
#define SCNdPTR "I64d"
#define SCNiPTR "I64i"
#define SCNoPTR "I64o"
#define SCNxPTR "I64x"
#define SCNuPTR "I64u"
#else
#define PRIdPTR "d"
#define PRIiPTR "i"
#define PRIoPTR "o"
#define PRIuPTR "u"
#define PRIxPTR "x"
#define PRIXPTR "X"
#define SCNdPTR "d"
#define SCNiPTR "i"
#define SCNoPTR "o"
#define SCNxPTR "x"
#define SCNuPTR "u"
#endif
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
/*
* no length modifier for char types prior to C9x
* MS runtime scanf appears to treat "hh" as "h"
*/
/* signed char */
#define SCNd8 "hhd"
#define SCNdLEAST8 "hhd"
#define SCNdFAST8 "hhd"
#define SCNi8 "hhi"
#define SCNiLEAST8 "hhi"
#define SCNiFAST8 "hhi"
#define SCNo8 "hho"
#define SCNoLEAST8 "hho"
#define SCNoFAST8 "hho"
#define SCNx8 "hhx"
#define SCNxLEAST8 "hhx"
#define SCNxFAST8 "hhx"
/* unsigned char */
#define SCNu8 "hhu"
#define SCNuLEAST8 "hhu"
#define SCNuFAST8 "hhu"
#endif /* __STDC_VERSION__ >= 199901 */
#ifdef __cplusplus
}
#endif
#endif /* ndef _INTTYPES_H */

View File

@ -0,0 +1,32 @@
/*
* Header file for missing WinCE functionality
* Copyright © 2012-2013 RealVNC Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef MISSING_H
#define MISSING_H
/* Windows CE doesn't have SleepEx() - Fallback to Sleep() */
#define SleepEx(m, a) Sleep(m)
/* Windows CE doesn't have any APIs to query environment variables.
*
* This contains a registry based implementation of getenv.
*/
char *getenv(const char *name);
#endif

View File

@ -0,0 +1,256 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file was originally part of the w64 mingw-runtime package.
*/
/* ISO C9x 7.18 Integer types <stdint.h>
* Based on ISO/IEC SC22/WG14 9899 Committee draft (SC22 N2794)
*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* Contributor: Danny Smith <danny_r_smith_2001@yahoo.co.nz>
* Modified for libusb/MSVC: Pete Batard <pbatard@gmail.com>
*
* This source code is offered for use in the public domain. You may
* use, modify or distribute it freely.
*
* This code is distributed in the hope that it will be useful but
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
* DISCLAIMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Date: 2010-04-02
*/
#ifndef _MSC_VER
#error This header should only be used with Microsoft compilers
#endif
#ifndef _STDINT_H
#define _STDINT_H
#ifndef _INTPTR_T_DEFINED
#define _INTPTR_T_DEFINED
#ifndef __intptr_t_defined
#define __intptr_t_defined
#undef intptr_t
#ifdef _WIN64
typedef __int64 intptr_t;
#else
typedef int intptr_t;
#endif /* _WIN64 */
#endif /* __intptr_t_defined */
#endif /* _INTPTR_T_DEFINED */
#ifndef _UINTPTR_T_DEFINED
#define _UINTPTR_T_DEFINED
#ifndef __uintptr_t_defined
#define __uintptr_t_defined
#undef uintptr_t
#ifdef _WIN64
typedef unsigned __int64 uintptr_t;
#else
typedef unsigned int uintptr_t;
#endif /* _WIN64 */
#endif /* __uintptr_t_defined */
#endif /* _UINTPTR_T_DEFINED */
#ifndef _PTRDIFF_T_DEFINED
#define _PTRDIFF_T_DEFINED
#ifndef _PTRDIFF_T_
#define _PTRDIFF_T_
#undef ptrdiff_t
#ifdef _WIN64
typedef __int64 ptrdiff_t;
#else
typedef int ptrdiff_t;
#endif /* _WIN64 */
#endif /* _PTRDIFF_T_ */
#endif /* _PTRDIFF_T_DEFINED */
#ifndef _WCHAR_T_DEFINED
#define _WCHAR_T_DEFINED
#ifndef __cplusplus
typedef unsigned short wchar_t;
#endif /* C++ */
#endif /* _WCHAR_T_DEFINED */
#ifndef _WCTYPE_T_DEFINED
#define _WCTYPE_T_DEFINED
#ifndef _WINT_T
#define _WINT_T
typedef unsigned short wint_t;
typedef unsigned short wctype_t;
#endif /* _WINT_T */
#endif /* _WCTYPE_T_DEFINED */
/* 7.18.1.1 Exact-width integer types */
typedef __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
/* 7.18.1.2 Minimum-width integer types */
typedef signed char int_least8_t;
typedef unsigned char uint_least8_t;
typedef short int_least16_t;
typedef unsigned short uint_least16_t;
typedef int int_least32_t;
typedef unsigned uint_least32_t;
typedef __int64 int_least64_t;
typedef unsigned __int64 uint_least64_t;
/* 7.18.1.3 Fastest minimum-width integer types
* Not actually guaranteed to be fastest for all purposes
* Here we use the exact-width types for 8 and 16-bit ints.
*/
typedef __int8 int_fast8_t;
typedef unsigned __int8 uint_fast8_t;
typedef __int16 int_fast16_t;
typedef unsigned __int16 uint_fast16_t;
typedef __int32 int_fast32_t;
typedef unsigned __int32 uint_fast32_t;
typedef __int64 int_fast64_t;
typedef unsigned __int64 uint_fast64_t;
/* 7.18.1.5 Greatest-width integer types */
typedef __int64 intmax_t;
typedef unsigned __int64 uintmax_t;
/* 7.18.2 Limits of specified-width integer types */
/* 7.18.2.1 Limits of exact-width integer types */
#define INT8_MIN (-128)
#define INT16_MIN (-32768)
#define INT32_MIN (-2147483647 - 1)
#define INT64_MIN (-9223372036854775807LL - 1)
#define INT8_MAX 127
#define INT16_MAX 32767
#define INT32_MAX 2147483647
#define INT64_MAX 9223372036854775807LL
#define UINT8_MAX 255
#define UINT16_MAX 65535
#define UINT32_MAX 0xffffffffU /* 4294967295U */
#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */
/* 7.18.2.2 Limits of minimum-width integer types */
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
/* 7.18.2.3 Limits of fastest minimum-width integer types */
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
/* 7.18.2.4 Limits of integer types capable of holding
object pointers */
#ifdef _WIN64
#define INTPTR_MIN INT64_MIN
#define INTPTR_MAX INT64_MAX
#define UINTPTR_MAX UINT64_MAX
#else
#define INTPTR_MIN INT32_MIN
#define INTPTR_MAX INT32_MAX
#define UINTPTR_MAX UINT32_MAX
#endif
/* 7.18.2.5 Limits of greatest-width integer types */
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
/* 7.18.3 Limits of other integer types */
#ifdef _WIN64
#define PTRDIFF_MIN INT64_MIN
#define PTRDIFF_MAX INT64_MAX
#else
#define PTRDIFF_MIN INT32_MIN
#define PTRDIFF_MAX INT32_MAX
#endif
#define SIG_ATOMIC_MIN INT32_MIN
#define SIG_ATOMIC_MAX INT32_MAX
#ifndef SIZE_MAX
#ifdef _WIN64
#define SIZE_MAX UINT64_MAX
#else
#define SIZE_MAX UINT32_MAX
#endif
#endif
#ifndef WCHAR_MIN /* also in wchar.h */
#define WCHAR_MIN 0U
#define WCHAR_MAX 0xffffU
#endif
/*
* wint_t is unsigned short for compatibility with MS runtime
*/
#define WINT_MIN 0U
#define WINT_MAX 0xffffU
/* 7.18.4 Macros for integer constants */
/* 7.18.4.1 Macros for minimum-width integer constants
Accoding to Douglas Gwyn <gwyn@arl.mil>:
"This spec was changed in ISO/IEC 9899:1999 TC1; in ISO/IEC
9899:1999 as initially published, the expansion was required
to be an integer constant of precisely matching type, which
is impossible to accomplish for the shorter types on most
platforms, because C99 provides no standard way to designate
an integer constant with width less than that of type int.
TC1 changed this to require just an integer constant
*expression* with *promoted* type."
The trick used here is from Clive D W Feather.
*/
#define INT8_C(val) (INT_LEAST8_MAX-INT_LEAST8_MAX+(val))
#define INT16_C(val) (INT_LEAST16_MAX-INT_LEAST16_MAX+(val))
#define INT32_C(val) (INT_LEAST32_MAX-INT_LEAST32_MAX+(val))
/* The 'trick' doesn't work in C89 for long long because, without
suffix, (val) will be evaluated as int, not intmax_t */
#define INT64_C(val) val##i64
#define UINT8_C(val) (val)
#define UINT16_C(val) (val)
#define UINT32_C(val) (val##i32)
#define UINT64_C(val) val##ui64
/* 7.18.4.2 Macros for greatest-width integer constants */
#define INTMAX_C(val) val##i64
#define UINTMAX_C(val) val##ui64
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,162 @@
/*
* darwin backend for libusb 1.0
* Copyright © 2008-2013 Nathan Hjelm <hjelmn@users.sourceforge.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if !defined(LIBUSB_DARWIN_H)
#define LIBUSB_DARWIN_H
#include "libusbi.h"
#include <IOKit/IOTypes.h>
#include <IOKit/IOCFBundle.h>
#include <IOKit/usb/IOUSBLib.h>
#include <IOKit/IOCFPlugIn.h>
/* IOUSBInterfaceInferface */
#if defined (kIOUSBInterfaceInterfaceID550)
#define usb_interface_t IOUSBInterfaceInterface550
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID550
#define InterfaceVersion 550
#elif defined (kIOUSBInterfaceInterfaceID500)
#define usb_interface_t IOUSBInterfaceInterface500
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID500
#define InterfaceVersion 500
#elif defined (kIOUSBInterfaceInterfaceID300)
#define usb_interface_t IOUSBInterfaceInterface300
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID300
#define InterfaceVersion 300
#elif defined (kIOUSBInterfaceInterfaceID245)
#define usb_interface_t IOUSBInterfaceInterface245
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID245
#define InterfaceVersion 245
#elif defined (kIOUSBInterfaceInterfaceID220)
#define usb_interface_t IOUSBInterfaceInterface220
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID220
#define InterfaceVersion 220
#else
#error "IOUSBFamily is too old. Please upgrade your OS"
#endif
/* IOUSBDeviceInterface */
#if defined (kIOUSBDeviceInterfaceID500)
#define usb_device_t IOUSBDeviceInterface500
#define DeviceInterfaceID kIOUSBDeviceInterfaceID500
#define DeviceVersion 500
#elif defined (kIOUSBDeviceInterfaceID320)
#define usb_device_t IOUSBDeviceInterface320
#define DeviceInterfaceID kIOUSBDeviceInterfaceID320
#define DeviceVersion 320
#elif defined (kIOUSBDeviceInterfaceID300)
#define usb_device_t IOUSBDeviceInterface300
#define DeviceInterfaceID kIOUSBDeviceInterfaceID300
#define DeviceVersion 300
#elif defined (kIOUSBDeviceInterfaceID245)
#define usb_device_t IOUSBDeviceInterface245
#define DeviceInterfaceID kIOUSBDeviceInterfaceID245
#define DeviceVersion 245
#elif defined (kIOUSBDeviceInterfaceID220)
#define usb_device_t IOUSBDeviceInterface197
#define DeviceInterfaceID kIOUSBDeviceInterfaceID197
#define DeviceVersion 197
#else
#error "IOUSBFamily is too old. Please upgrade your OS"
#endif
#if !defined(IO_OBJECT_NULL)
#define IO_OBJECT_NULL ((io_object_t) 0)
#endif
typedef IOCFPlugInInterface *io_cf_plugin_ref_t;
typedef IONotificationPortRef io_notification_port_t;
/* private structures */
struct darwin_cached_device {
struct list_head list;
IOUSBDeviceDescriptor dev_descriptor;
UInt32 location;
UInt64 parent_session;
UInt64 session;
UInt16 address;
char sys_path[21];
usb_device_t **device;
int open_count;
UInt8 first_config, active_config, port;
int can_enumerate;
int refcount;
};
struct darwin_device_priv {
struct darwin_cached_device *dev;
};
struct darwin_device_handle_priv {
int is_open;
CFRunLoopSourceRef cfSource;
int fds[2];
struct darwin_interface {
usb_interface_t **interface;
uint8_t num_endpoints;
CFRunLoopSourceRef cfSource;
uint64_t frames[256];
uint8_t endpoint_addrs[USB_MAXENDPOINTS];
} interfaces[USB_MAXINTERFACES];
};
struct darwin_transfer_priv {
/* Isoc */
IOUSBIsocFrame *isoc_framelist;
int num_iso_packets;
/* Control */
IOUSBDevRequestTO req;
/* Bulk */
};
/* structure for signaling io completion */
struct darwin_msg_async_io_complete {
struct usbi_transfer *itransfer;
IOReturn result;
UInt32 size;
};
#endif

View File

@ -0,0 +1,369 @@
/* -*- Mode: C; c-basic-offset:8 ; indent-tabs-mode:t -*- */
/*
* Linux usbfs backend for libusb
* Copyright (C) 2007-2009 Daniel Drake <dsd@gentoo.org>
* Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com>
* Copyright (c) 2013 Nathan Hjelm <hjelmn@mac.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "libusb.h"
#include "libusbi.h"
#include "linux_usbfs.h"
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#ifdef HAVE_ASM_TYPES_H
#include <asm/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#include <arpa/inet.h>
#ifdef HAVE_LINUX_NETLINK_H
#include <linux/netlink.h>
#endif
#ifdef HAVE_LINUX_FILTER_H
#include <linux/filter.h>
#endif
#define KERNEL 1
static int linux_netlink_socket = -1;
static int netlink_control_pipe[2] = { -1, -1 };
static pthread_t libusb_linux_event_thread;
static void *linux_netlink_event_thread_main(void *arg);
struct sockaddr_nl snl = { .nl_family=AF_NETLINK, .nl_groups=KERNEL };
static int set_fd_cloexec_nb (int fd)
{
int flags;
#if defined(FD_CLOEXEC)
flags = fcntl (linux_netlink_socket, F_GETFD);
if (0 > flags) {
return -1;
}
if (!(flags & FD_CLOEXEC)) {
fcntl (linux_netlink_socket, F_SETFD, flags | FD_CLOEXEC);
}
#endif
flags = fcntl (linux_netlink_socket, F_GETFL);
if (0 > flags) {
return -1;
}
if (!(flags & O_NONBLOCK)) {
fcntl (linux_netlink_socket, F_SETFL, flags | O_NONBLOCK);
}
return 0;
}
int linux_netlink_start_event_monitor(void)
{
int socktype = SOCK_RAW;
int ret;
snl.nl_groups = KERNEL;
#if defined(SOCK_CLOEXEC)
socktype |= SOCK_CLOEXEC;
#endif
#if defined(SOCK_NONBLOCK)
socktype |= SOCK_NONBLOCK;
#endif
linux_netlink_socket = socket(PF_NETLINK, socktype, NETLINK_KOBJECT_UEVENT);
if (-1 == linux_netlink_socket && EINVAL == errno) {
linux_netlink_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
}
if (-1 == linux_netlink_socket) {
return LIBUSB_ERROR_OTHER;
}
ret = set_fd_cloexec_nb (linux_netlink_socket);
if (0 != ret) {
close (linux_netlink_socket);
linux_netlink_socket = -1;
return LIBUSB_ERROR_OTHER;
}
ret = bind(linux_netlink_socket, (struct sockaddr *) &snl, sizeof(snl));
if (0 != ret) {
close(linux_netlink_socket);
return LIBUSB_ERROR_OTHER;
}
/* TODO -- add authentication */
/* setsockopt(linux_netlink_socket, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)); */
ret = usbi_pipe(netlink_control_pipe);
if (ret) {
usbi_err(NULL, "could not create netlink control pipe");
close(linux_netlink_socket);
return LIBUSB_ERROR_OTHER;
}
ret = pthread_create(&libusb_linux_event_thread, NULL, linux_netlink_event_thread_main, NULL);
if (0 != ret) {
close(netlink_control_pipe[0]);
close(netlink_control_pipe[1]);
close(linux_netlink_socket);
return LIBUSB_ERROR_OTHER;
}
return LIBUSB_SUCCESS;
}
int linux_netlink_stop_event_monitor(void)
{
int r;
char dummy = 1;
if (-1 == linux_netlink_socket) {
/* already closed. nothing to do */
return LIBUSB_SUCCESS;
}
/* Write some dummy data to the control pipe and
* wait for the thread to exit */
r = usbi_write(netlink_control_pipe[1], &dummy, sizeof(dummy));
if (r <= 0) {
usbi_warn(NULL, "netlink control pipe signal failed");
}
pthread_join(libusb_linux_event_thread, NULL);
close(linux_netlink_socket);
linux_netlink_socket = -1;
/* close and reset control pipe */
close(netlink_control_pipe[0]);
close(netlink_control_pipe[1]);
netlink_control_pipe[0] = -1;
netlink_control_pipe[1] = -1;
return LIBUSB_SUCCESS;
}
static const char *netlink_message_parse (const char *buffer, size_t len, const char *key)
{
size_t keylen = strlen(key);
size_t offset;
for (offset = 0 ; offset < len && '\0' != buffer[offset] ; offset += strlen(buffer + offset) + 1) {
if (0 == strncmp(buffer + offset, key, keylen) &&
'=' == buffer[offset + keylen]) {
return buffer + offset + keylen + 1;
}
}
return NULL;
}
/* parse parts of netlink message common to both libudev and the kernel */
static int linux_netlink_parse(char *buffer, size_t len, int *detached, const char **sys_name,
uint8_t *busnum, uint8_t *devaddr) {
const char *tmp;
int i;
errno = 0;
*sys_name = NULL;
*detached = 0;
*busnum = 0;
*devaddr = 0;
tmp = netlink_message_parse((const char *) buffer, len, "ACTION");
if (tmp == NULL)
return -1;
if (0 == strcmp(tmp, "remove")) {
*detached = 1;
} else if (0 != strcmp(tmp, "add")) {
usbi_dbg("unknown device action %s", tmp);
return -1;
}
/* check that this is a usb message */
tmp = netlink_message_parse(buffer, len, "SUBSYSTEM");
if (NULL == tmp || 0 != strcmp(tmp, "usb")) {
/* not usb. ignore */
return -1;
}
tmp = netlink_message_parse(buffer, len, "BUSNUM");
if (NULL == tmp) {
/* no bus number. try "DEVICE" */
tmp = netlink_message_parse(buffer, len, "DEVICE");
if (NULL == tmp) {
/* not usb. ignore */
return -1;
}
/* Parse a device path such as /dev/bus/usb/003/004 */
char *pLastSlash = (char*)strrchr(tmp,'/');
if(NULL == pLastSlash) {
return -1;
}
*devaddr = strtoul(pLastSlash + 1, NULL, 10);
if (errno) {
errno = 0;
return -1;
}
*busnum = strtoul(pLastSlash - 3, NULL, 10);
if (errno) {
errno = 0;
return -1;
}
return 0;
}
*busnum = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff);
if (errno) {
errno = 0;
return -1;
}
tmp = netlink_message_parse(buffer, len, "DEVNUM");
if (NULL == tmp) {
return -1;
}
*devaddr = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff);
if (errno) {
errno = 0;
return -1;
}
tmp = netlink_message_parse(buffer, len, "DEVPATH");
if (NULL == tmp) {
return -1;
}
for (i = strlen(tmp) - 1 ; i ; --i) {
if ('/' ==tmp[i]) {
*sys_name = tmp + i + 1;
break;
}
}
/* found a usb device */
return 0;
}
static int linux_netlink_read_message(void)
{
unsigned char buffer[1024];
struct iovec iov = {.iov_base = buffer, .iov_len = sizeof(buffer)};
struct msghdr meh = { .msg_iov=&iov, .msg_iovlen=1,
.msg_name=&snl, .msg_namelen=sizeof(snl) };
const char *sys_name = NULL;
uint8_t busnum, devaddr;
int detached, r;
size_t len;
/* read netlink message */
memset(buffer, 0, sizeof(buffer));
len = recvmsg(linux_netlink_socket, &meh, 0);
if (len < 32) {
if (errno != EAGAIN)
usbi_dbg("error recieving message from netlink");
return -1;
}
/* TODO -- authenticate this message is from the kernel or udevd */
r = linux_netlink_parse(buffer, len, &detached, &sys_name,
&busnum, &devaddr);
if (r)
return r;
usbi_dbg("netlink hotplug found device busnum: %hhu, devaddr: %hhu, sys_name: %s, removed: %s",
busnum, devaddr, sys_name, detached ? "yes" : "no");
/* signal device is available (or not) to all contexts */
if (detached)
linux_device_disconnected(busnum, devaddr, sys_name);
else
linux_hotplug_enumerate(busnum, devaddr, sys_name);
return 0;
}
static void *linux_netlink_event_thread_main(void *arg)
{
char dummy;
int r;
struct pollfd fds[] = {
{ .fd = netlink_control_pipe[0],
.events = POLLIN },
{ .fd = linux_netlink_socket,
.events = POLLIN },
};
/* silence compiler warning */
(void) arg;
while (poll(fds, 2, -1) >= 0) {
if (fds[0].revents & POLLIN) {
/* activity on control pipe, read the byte and exit */
r = usbi_read(netlink_control_pipe[0], &dummy, sizeof(dummy));
if (r <= 0) {
usbi_warn(NULL, "netlink control pipe read failed");
}
break;
}
if (fds[1].revents & POLLIN) {
usbi_mutex_static_lock(&linux_hotplug_lock);
linux_netlink_read_message();
usbi_mutex_static_unlock(&linux_hotplug_lock);
}
}
return NULL;
}
void linux_netlink_hotplug_poll(void)
{
int r;
usbi_mutex_static_lock(&linux_hotplug_lock);
do {
r = linux_netlink_read_message();
} while (r == 0);
usbi_mutex_static_unlock(&linux_hotplug_lock);
}

View File

@ -0,0 +1,307 @@
/* -*- Mode: C; c-basic-offset:8 ; indent-tabs-mode:t -*- */
/*
* Linux usbfs backend for libusb
* Copyright (C) 2007-2009 Daniel Drake <dsd@gentoo.org>
* Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com>
* Copyright (c) 2012-2013 Nathan Hjelm <hjelmn@mac.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include <assert.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/socket.h>
#include <unistd.h>
#include <libudev.h>
#include "libusb.h"
#include "libusbi.h"
#include "linux_usbfs.h"
/* udev context */
static struct udev *udev_ctx = NULL;
static int udev_monitor_fd = -1;
static int udev_control_pipe[2] = {-1, -1};
static struct udev_monitor *udev_monitor = NULL;
static pthread_t linux_event_thread;
static void udev_hotplug_event(struct udev_device* udev_dev);
static void *linux_udev_event_thread_main(void *arg);
int linux_udev_start_event_monitor(void)
{
int r;
assert(udev_ctx == NULL);
udev_ctx = udev_new();
if (!udev_ctx) {
usbi_err(NULL, "could not create udev context");
goto err;
}
udev_monitor = udev_monitor_new_from_netlink(udev_ctx, "udev");
if (!udev_monitor) {
usbi_err(NULL, "could not initialize udev monitor");
goto err_free_ctx;
}
r = udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb", 0);
if (r) {
usbi_err(NULL, "could not initialize udev monitor filter for \"usb\" subsystem");
goto err_free_monitor;
}
if (udev_monitor_enable_receiving(udev_monitor)) {
usbi_err(NULL, "failed to enable the udev monitor");
goto err_free_monitor;
}
udev_monitor_fd = udev_monitor_get_fd(udev_monitor);
/* Some older versions of udev are not non-blocking by default,
* so make sure this is set */
r = fcntl(udev_monitor_fd, F_GETFL);
if (r == -1) {
usbi_err(NULL, "getting udev monitor fd flags (%d)", errno);
goto err_free_monitor;
}
r = fcntl(udev_monitor_fd, F_SETFL, r | O_NONBLOCK);
if (r) {
usbi_err(NULL, "setting udev monitor fd flags (%d)", errno);
goto err_free_monitor;
}
r = usbi_pipe(udev_control_pipe);
if (r) {
usbi_err(NULL, "could not create udev control pipe");
goto err_free_monitor;
}
r = pthread_create(&linux_event_thread, NULL, linux_udev_event_thread_main, NULL);
if (r) {
usbi_err(NULL, "creating hotplug event thread (%d)", r);
goto err_close_pipe;
}
return LIBUSB_SUCCESS;
err_close_pipe:
close(udev_control_pipe[0]);
close(udev_control_pipe[1]);
err_free_monitor:
udev_monitor_unref(udev_monitor);
udev_monitor = NULL;
udev_monitor_fd = -1;
err_free_ctx:
udev_unref(udev_ctx);
err:
udev_ctx = NULL;
return LIBUSB_ERROR_OTHER;
}
int linux_udev_stop_event_monitor(void)
{
char dummy = 1;
int r;
assert(udev_ctx != NULL);
assert(udev_monitor != NULL);
assert(udev_monitor_fd != -1);
/* Write some dummy data to the control pipe and
* wait for the thread to exit */
r = usbi_write(udev_control_pipe[1], &dummy, sizeof(dummy));
if (r <= 0) {
usbi_warn(NULL, "udev control pipe signal failed");
}
pthread_join(linux_event_thread, NULL);
/* Release the udev monitor */
udev_monitor_unref(udev_monitor);
udev_monitor = NULL;
udev_monitor_fd = -1;
/* Clean up the udev context */
udev_unref(udev_ctx);
udev_ctx = NULL;
/* close and reset control pipe */
close(udev_control_pipe[0]);
close(udev_control_pipe[1]);
udev_control_pipe[0] = -1;
udev_control_pipe[1] = -1;
return LIBUSB_SUCCESS;
}
static void *linux_udev_event_thread_main(void *arg)
{
char dummy;
int r;
struct udev_device* udev_dev;
struct pollfd fds[] = {
{.fd = udev_control_pipe[0],
.events = POLLIN},
{.fd = udev_monitor_fd,
.events = POLLIN},
};
usbi_dbg("udev event thread entering.");
while (poll(fds, 2, -1) >= 0) {
if (fds[0].revents & POLLIN) {
/* activity on control pipe, read the byte and exit */
r = usbi_read(udev_control_pipe[0], &dummy, sizeof(dummy));
if (r <= 0) {
usbi_warn(NULL, "udev control pipe read failed");
}
break;
}
if (fds[1].revents & POLLIN) {
usbi_mutex_static_lock(&linux_hotplug_lock);
udev_dev = udev_monitor_receive_device(udev_monitor);
if (udev_dev)
udev_hotplug_event(udev_dev);
usbi_mutex_static_unlock(&linux_hotplug_lock);
}
}
usbi_dbg("udev event thread exiting");
return NULL;
}
static int udev_device_info(struct libusb_context *ctx, int detached,
struct udev_device *udev_dev, uint8_t *busnum,
uint8_t *devaddr, const char **sys_name) {
const char *dev_node;
dev_node = udev_device_get_devnode(udev_dev);
if (!dev_node) {
return LIBUSB_ERROR_OTHER;
}
*sys_name = udev_device_get_sysname(udev_dev);
if (!*sys_name) {
return LIBUSB_ERROR_OTHER;
}
return linux_get_device_address(ctx, detached, busnum, devaddr,
dev_node, *sys_name);
}
static void udev_hotplug_event(struct udev_device* udev_dev)
{
const char* udev_action;
const char* sys_name = NULL;
uint8_t busnum = 0, devaddr = 0;
int detached;
int r;
do {
udev_action = udev_device_get_action(udev_dev);
if (!udev_action) {
break;
}
detached = !strncmp(udev_action, "remove", 6);
r = udev_device_info(NULL, detached, udev_dev, &busnum, &devaddr, &sys_name);
if (LIBUSB_SUCCESS != r) {
break;
}
usbi_dbg("udev hotplug event. action: %s.", udev_action);
if (strncmp(udev_action, "add", 3) == 0) {
linux_hotplug_enumerate(busnum, devaddr, sys_name);
} else if (detached) {
linux_device_disconnected(busnum, devaddr, sys_name);
} else {
usbi_err(NULL, "ignoring udev action %s", udev_action);
}
} while (0);
udev_device_unref(udev_dev);
}
int linux_udev_scan_devices(struct libusb_context *ctx)
{
struct udev_enumerate *enumerator;
struct udev_list_entry *devices, *entry;
struct udev_device *udev_dev;
const char *sys_name;
int r;
assert(udev_ctx != NULL);
enumerator = udev_enumerate_new(udev_ctx);
if (NULL == enumerator) {
usbi_err(ctx, "error creating udev enumerator");
return LIBUSB_ERROR_OTHER;
}
udev_enumerate_add_match_subsystem(enumerator, "usb");
udev_enumerate_scan_devices(enumerator);
devices = udev_enumerate_get_list_entry(enumerator);
udev_list_entry_foreach(entry, devices) {
const char *path = udev_list_entry_get_name(entry);
uint8_t busnum = 0, devaddr = 0;
udev_dev = udev_device_new_from_syspath(udev_ctx, path);
r = udev_device_info(ctx, 0, udev_dev, &busnum, &devaddr, &sys_name);
if (r) {
udev_device_unref(udev_dev);
continue;
}
linux_enumerate_device(ctx, busnum, devaddr, sys_name);
udev_device_unref(udev_dev);
}
udev_enumerate_unref(enumerator);
return LIBUSB_SUCCESS;
}
void linux_udev_hotplug_poll(void)
{
struct udev_device* udev_dev;
usbi_mutex_static_lock(&linux_hotplug_lock);
do {
udev_dev = udev_monitor_receive_device(udev_monitor);
if (udev_dev) {
usbi_dbg("Handling hotplug event from hotplug_poll");
udev_hotplug_event(udev_dev);
}
} while (udev_dev);
usbi_mutex_static_unlock(&linux_hotplug_lock);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,192 @@
/*
* usbfs header structures
* Copyright © 2007 Daniel Drake <dsd@gentoo.org>
* Copyright © 2001 Johannes Erdfelt <johannes@erdfelt.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef LIBUSB_USBFS_H
#define LIBUSB_USBFS_H
#include <linux/types.h>
#define SYSFS_DEVICE_PATH "/sys/bus/usb/devices"
struct usbfs_ctrltransfer {
/* keep in sync with usbdevice_fs.h:usbdevfs_ctrltransfer */
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
uint32_t timeout; /* in milliseconds */
/* pointer to data */
void *data;
};
struct usbfs_bulktransfer {
/* keep in sync with usbdevice_fs.h:usbdevfs_bulktransfer */
unsigned int ep;
unsigned int len;
unsigned int timeout; /* in milliseconds */
/* pointer to data */
void *data;
};
struct usbfs_setinterface {
/* keep in sync with usbdevice_fs.h:usbdevfs_setinterface */
unsigned int interface;
unsigned int altsetting;
};
#define USBFS_MAXDRIVERNAME 255
struct usbfs_getdriver {
unsigned int interface;
char driver[USBFS_MAXDRIVERNAME + 1];
};
#define USBFS_URB_SHORT_NOT_OK 0x01
#define USBFS_URB_ISO_ASAP 0x02
#define USBFS_URB_BULK_CONTINUATION 0x04
#define USBFS_URB_QUEUE_BULK 0x10
#define USBFS_URB_ZERO_PACKET 0x40
enum usbfs_urb_type {
USBFS_URB_TYPE_ISO = 0,
USBFS_URB_TYPE_INTERRUPT = 1,
USBFS_URB_TYPE_CONTROL = 2,
USBFS_URB_TYPE_BULK = 3,
};
struct usbfs_iso_packet_desc {
unsigned int length;
unsigned int actual_length;
unsigned int status;
};
#define MAX_ISO_BUFFER_LENGTH 32768
#define MAX_BULK_BUFFER_LENGTH 16384
#define MAX_CTRL_BUFFER_LENGTH 4096
struct usbfs_urb {
unsigned char type;
unsigned char endpoint;
int status;
unsigned int flags;
void *buffer;
int buffer_length;
int actual_length;
int start_frame;
union {
int number_of_packets; /* Only used for isoc urbs */
unsigned int stream_id; /* Only used with bulk streams */
};
int error_count;
unsigned int signr;
void *usercontext;
struct usbfs_iso_packet_desc iso_frame_desc[0];
};
struct usbfs_connectinfo {
unsigned int devnum;
unsigned char slow;
};
struct usbfs_ioctl {
int ifno; /* interface 0..N ; negative numbers reserved */
int ioctl_code; /* MUST encode size + direction of data so the
* macros in <asm/ioctl.h> give correct values */
void *data; /* param buffer (in, or out) */
};
struct usbfs_hub_portinfo {
unsigned char numports;
unsigned char port[127]; /* port to device num mapping */
};
#define USBFS_CAP_ZERO_PACKET 0x01
#define USBFS_CAP_BULK_CONTINUATION 0x02
#define USBFS_CAP_NO_PACKET_SIZE_LIM 0x04
#define USBFS_CAP_BULK_SCATTER_GATHER 0x08
#define USBFS_DISCONNECT_CLAIM_IF_DRIVER 0x01
#define USBFS_DISCONNECT_CLAIM_EXCEPT_DRIVER 0x02
struct usbfs_disconnect_claim {
unsigned int interface;
unsigned int flags;
char driver[USBFS_MAXDRIVERNAME + 1];
};
struct usbfs_streams {
unsigned int num_streams; /* Not used by USBDEVFS_FREE_STREAMS */
unsigned int num_eps;
unsigned char eps[0];
};
#define IOCTL_USBFS_CONTROL _IOWR('U', 0, struct usbfs_ctrltransfer)
#define IOCTL_USBFS_BULK _IOWR('U', 2, struct usbfs_bulktransfer)
#define IOCTL_USBFS_RESETEP _IOR('U', 3, unsigned int)
#define IOCTL_USBFS_SETINTF _IOR('U', 4, struct usbfs_setinterface)
#define IOCTL_USBFS_SETCONFIG _IOR('U', 5, unsigned int)
#define IOCTL_USBFS_GETDRIVER _IOW('U', 8, struct usbfs_getdriver)
#define IOCTL_USBFS_SUBMITURB _IOR('U', 10, struct usbfs_urb)
#define IOCTL_USBFS_DISCARDURB _IO('U', 11)
#define IOCTL_USBFS_REAPURB _IOW('U', 12, void *)
#define IOCTL_USBFS_REAPURBNDELAY _IOW('U', 13, void *)
#define IOCTL_USBFS_CLAIMINTF _IOR('U', 15, unsigned int)
#define IOCTL_USBFS_RELEASEINTF _IOR('U', 16, unsigned int)
#define IOCTL_USBFS_CONNECTINFO _IOW('U', 17, struct usbfs_connectinfo)
#define IOCTL_USBFS_IOCTL _IOWR('U', 18, struct usbfs_ioctl)
#define IOCTL_USBFS_HUB_PORTINFO _IOR('U', 19, struct usbfs_hub_portinfo)
#define IOCTL_USBFS_RESET _IO('U', 20)
#define IOCTL_USBFS_CLEAR_HALT _IOR('U', 21, unsigned int)
#define IOCTL_USBFS_DISCONNECT _IO('U', 22)
#define IOCTL_USBFS_CONNECT _IO('U', 23)
#define IOCTL_USBFS_CLAIM_PORT _IOR('U', 24, unsigned int)
#define IOCTL_USBFS_RELEASE_PORT _IOR('U', 25, unsigned int)
#define IOCTL_USBFS_GET_CAPABILITIES _IOR('U', 26, __u32)
#define IOCTL_USBFS_DISCONNECT_CLAIM _IOR('U', 27, struct usbfs_disconnect_claim)
#define IOCTL_USBFS_ALLOC_STREAMS _IOR('U', 28, struct usbfs_streams)
#define IOCTL_USBFS_FREE_STREAMS _IOR('U', 29, struct usbfs_streams)
extern usbi_mutex_static_t linux_hotplug_lock;
#if defined(HAVE_LIBUDEV)
int linux_udev_start_event_monitor(void);
int linux_udev_stop_event_monitor(void);
int linux_udev_scan_devices(struct libusb_context *ctx);
void linux_udev_hotplug_poll(void);
#else
int linux_netlink_start_event_monitor(void);
int linux_netlink_stop_event_monitor(void);
void linux_netlink_hotplug_poll(void);
#endif
void linux_hotplug_enumerate(uint8_t busnum, uint8_t devaddr, const char *sys_name);
void linux_device_disconnected(uint8_t busnum, uint8_t devaddr, const char *sys_name);
int linux_get_device_address (struct libusb_context *ctx, int detached,
uint8_t *busnum, uint8_t *devaddr, const char *dev_node,
const char *sys_name);
int linux_enumerate_device(struct libusb_context *ctx,
uint8_t busnum, uint8_t devaddr, const char *sysfs_dir);
#endif

View File

@ -0,0 +1,738 @@
/*
* Copyright © 2011 Martin Pieuchot <mpi@openbsd.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <sys/time.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dev/usb/usb.h>
#include "libusb.h"
#include "libusbi.h"
struct device_priv {
char devnode[16];
int fd;
unsigned char *cdesc; /* active config descriptor */
usb_device_descriptor_t ddesc; /* usb device descriptor */
};
struct handle_priv {
int pipe[2]; /* for event notification */
int endpoints[USB_MAX_ENDPOINTS];
};
/*
* Backend functions
*/
static int netbsd_get_device_list(struct libusb_context *,
struct discovered_devs **);
static int netbsd_open(struct libusb_device_handle *);
static void netbsd_close(struct libusb_device_handle *);
static int netbsd_get_device_descriptor(struct libusb_device *, unsigned char *,
int *);
static int netbsd_get_active_config_descriptor(struct libusb_device *,
unsigned char *, size_t, int *);
static int netbsd_get_config_descriptor(struct libusb_device *, uint8_t,
unsigned char *, size_t, int *);
static int netbsd_get_configuration(struct libusb_device_handle *, int *);
static int netbsd_set_configuration(struct libusb_device_handle *, int);
static int netbsd_claim_interface(struct libusb_device_handle *, int);
static int netbsd_release_interface(struct libusb_device_handle *, int);
static int netbsd_set_interface_altsetting(struct libusb_device_handle *, int,
int);
static int netbsd_clear_halt(struct libusb_device_handle *, unsigned char);
static int netbsd_reset_device(struct libusb_device_handle *);
static void netbsd_destroy_device(struct libusb_device *);
static int netbsd_submit_transfer(struct usbi_transfer *);
static int netbsd_cancel_transfer(struct usbi_transfer *);
static void netbsd_clear_transfer_priv(struct usbi_transfer *);
static int netbsd_handle_events(struct libusb_context *ctx, struct pollfd *,
nfds_t, int);
static int netbsd_clock_gettime(int, struct timespec *);
/*
* Private functions
*/
static int _errno_to_libusb(int);
static int _cache_active_config_descriptor(struct libusb_device *, int);
static int _sync_control_transfer(struct usbi_transfer *);
static int _sync_gen_transfer(struct usbi_transfer *);
static int _access_endpoint(struct libusb_transfer *);
const struct usbi_os_backend netbsd_backend = {
"Synchronous NetBSD backend",
0,
NULL, /* init() */
NULL, /* exit() */
netbsd_get_device_list,
NULL, /* hotplug_poll */
netbsd_open,
netbsd_close,
netbsd_get_device_descriptor,
netbsd_get_active_config_descriptor,
netbsd_get_config_descriptor,
NULL, /* get_config_descriptor_by_value() */
netbsd_get_configuration,
netbsd_set_configuration,
netbsd_claim_interface,
netbsd_release_interface,
netbsd_set_interface_altsetting,
netbsd_clear_halt,
netbsd_reset_device,
NULL, /* alloc_streams */
NULL, /* free_streams */
NULL, /* kernel_driver_active() */
NULL, /* detach_kernel_driver() */
NULL, /* attach_kernel_driver() */
netbsd_destroy_device,
netbsd_submit_transfer,
netbsd_cancel_transfer,
netbsd_clear_transfer_priv,
netbsd_handle_events,
netbsd_clock_gettime,
sizeof(struct device_priv),
sizeof(struct handle_priv),
0, /* transfer_priv_size */
0, /* add_iso_packet_size */
};
int
netbsd_get_device_list(struct libusb_context * ctx,
struct discovered_devs **discdevs)
{
struct libusb_device *dev;
struct device_priv *dpriv;
struct usb_device_info di;
unsigned long session_id;
char devnode[16];
int fd, err, i;
usbi_dbg("");
/* Only ugen(4) is supported */
for (i = 0; i < USB_MAX_DEVICES; i++) {
/* Control endpoint is always .00 */
snprintf(devnode, sizeof(devnode), "/dev/ugen%d.00", i);
if ((fd = open(devnode, O_RDONLY)) < 0) {
if (errno != ENOENT && errno != ENXIO)
usbi_err(ctx, "could not open %s", devnode);
continue;
}
if (ioctl(fd, USB_GET_DEVICEINFO, &di) < 0)
continue;
session_id = (di.udi_bus << 8 | di.udi_addr);
dev = usbi_get_device_by_session_id(ctx, session_id);
if (dev == NULL) {
dev = usbi_alloc_device(ctx, session_id);
if (dev == NULL)
return (LIBUSB_ERROR_NO_MEM);
dev->bus_number = di.udi_bus;
dev->device_address = di.udi_addr;
dev->speed = di.udi_speed;
dpriv = (struct device_priv *)dev->os_priv;
strlcpy(dpriv->devnode, devnode, sizeof(devnode));
dpriv->fd = -1;
if (ioctl(fd, USB_GET_DEVICE_DESC, &dpriv->ddesc) < 0) {
err = errno;
goto error;
}
dpriv->cdesc = NULL;
if (_cache_active_config_descriptor(dev, fd)) {
err = errno;
goto error;
}
if ((err = usbi_sanitize_device(dev)))
goto error;
}
close(fd);
if (discovered_devs_append(*discdevs, dev) == NULL)
return (LIBUSB_ERROR_NO_MEM);
libusb_unref_device(dev);
}
return (LIBUSB_SUCCESS);
error:
close(fd);
libusb_unref_device(dev);
return _errno_to_libusb(err);
}
int
netbsd_open(struct libusb_device_handle *handle)
{
struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
dpriv->fd = open(dpriv->devnode, O_RDWR);
if (dpriv->fd < 0) {
dpriv->fd = open(dpriv->devnode, O_RDONLY);
if (dpriv->fd < 0)
return _errno_to_libusb(errno);
}
usbi_dbg("open %s: fd %d", dpriv->devnode, dpriv->fd);
if (pipe(hpriv->pipe) < 0)
return _errno_to_libusb(errno);
return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->pipe[0], POLLIN);
}
void
netbsd_close(struct libusb_device_handle *handle)
{
struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
usbi_dbg("close: fd %d", dpriv->fd);
close(dpriv->fd);
dpriv->fd = -1;
usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]);
close(hpriv->pipe[0]);
close(hpriv->pipe[1]);
}
int
netbsd_get_device_descriptor(struct libusb_device *dev, unsigned char *buf,
int *host_endian)
{
struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
usbi_dbg("");
memcpy(buf, &dpriv->ddesc, DEVICE_DESC_LENGTH);
*host_endian = 0;
return (LIBUSB_SUCCESS);
}
int
netbsd_get_active_config_descriptor(struct libusb_device *dev,
unsigned char *buf, size_t len, int *host_endian)
{
struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
usb_config_descriptor_t *ucd;
ucd = (usb_config_descriptor_t *) dpriv->cdesc;
len = MIN(len, UGETW(ucd->wTotalLength));
usbi_dbg("len %d", len);
memcpy(buf, dpriv->cdesc, len);
*host_endian = 0;
return len;
}
int
netbsd_get_config_descriptor(struct libusb_device *dev, uint8_t idx,
unsigned char *buf, size_t len, int *host_endian)
{
struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
struct usb_full_desc ufd;
int fd, err;
usbi_dbg("index %d, len %d", idx, len);
/* A config descriptor may be requested before opening the device */
if (dpriv->fd >= 0) {
fd = dpriv->fd;
} else {
fd = open(dpriv->devnode, O_RDONLY);
if (fd < 0)
return _errno_to_libusb(errno);
}
ufd.ufd_config_index = idx;
ufd.ufd_size = len;
ufd.ufd_data = buf;
if ((ioctl(fd, USB_GET_FULL_DESC, &ufd)) < 0) {
err = errno;
if (dpriv->fd < 0)
close(fd);
return _errno_to_libusb(err);
}
if (dpriv->fd < 0)
close(fd);
*host_endian = 0;
return len;
}
int
netbsd_get_configuration(struct libusb_device_handle *handle, int *config)
{
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
usbi_dbg("");
if (ioctl(dpriv->fd, USB_GET_CONFIG, config) < 0)
return _errno_to_libusb(errno);
usbi_dbg("configuration %d", *config);
return (LIBUSB_SUCCESS);
}
int
netbsd_set_configuration(struct libusb_device_handle *handle, int config)
{
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
usbi_dbg("configuration %d", config);
if (ioctl(dpriv->fd, USB_SET_CONFIG, &config) < 0)
return _errno_to_libusb(errno);
return _cache_active_config_descriptor(handle->dev, dpriv->fd);
}
int
netbsd_claim_interface(struct libusb_device_handle *handle, int iface)
{
struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
int i;
for (i = 0; i < USB_MAX_ENDPOINTS; i++)
hpriv->endpoints[i] = -1;
return (LIBUSB_SUCCESS);
}
int
netbsd_release_interface(struct libusb_device_handle *handle, int iface)
{
struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
int i;
for (i = 0; i < USB_MAX_ENDPOINTS; i++)
if (hpriv->endpoints[i] >= 0)
close(hpriv->endpoints[i]);
return (LIBUSB_SUCCESS);
}
int
netbsd_set_interface_altsetting(struct libusb_device_handle *handle, int iface,
int altsetting)
{
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
struct usb_alt_interface intf;
usbi_dbg("iface %d, setting %d", iface, altsetting);
memset(&intf, 0, sizeof(intf));
intf.uai_interface_index = iface;
intf.uai_alt_no = altsetting;
if (ioctl(dpriv->fd, USB_SET_ALTINTERFACE, &intf) < 0)
return _errno_to_libusb(errno);
return (LIBUSB_SUCCESS);
}
int
netbsd_clear_halt(struct libusb_device_handle *handle, unsigned char endpoint)
{
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
struct usb_ctl_request req;
usbi_dbg("");
req.ucr_request.bmRequestType = UT_WRITE_ENDPOINT;
req.ucr_request.bRequest = UR_CLEAR_FEATURE;
USETW(req.ucr_request.wValue, UF_ENDPOINT_HALT);
USETW(req.ucr_request.wIndex, endpoint);
USETW(req.ucr_request.wLength, 0);
if (ioctl(dpriv->fd, USB_DO_REQUEST, &req) < 0)
return _errno_to_libusb(errno);
return (LIBUSB_SUCCESS);
}
int
netbsd_reset_device(struct libusb_device_handle *handle)
{
usbi_dbg("");
return (LIBUSB_ERROR_NOT_SUPPORTED);
}
void
netbsd_destroy_device(struct libusb_device *dev)
{
struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
usbi_dbg("");
free(dpriv->cdesc);
}
int
netbsd_submit_transfer(struct usbi_transfer *itransfer)
{
struct libusb_transfer *transfer;
struct handle_priv *hpriv;
int err = 0;
usbi_dbg("");
transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
hpriv = (struct handle_priv *)transfer->dev_handle->os_priv;
switch (transfer->type) {
case LIBUSB_TRANSFER_TYPE_CONTROL:
err = _sync_control_transfer(itransfer);
break;
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
if (IS_XFEROUT(transfer)) {
/* Isochronous write is not supported */
err = LIBUSB_ERROR_NOT_SUPPORTED;
break;
}
err = _sync_gen_transfer(itransfer);
break;
case LIBUSB_TRANSFER_TYPE_BULK:
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
if (IS_XFEROUT(transfer) &&
transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
err = LIBUSB_ERROR_NOT_SUPPORTED;
break;
}
err = _sync_gen_transfer(itransfer);
break;
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
err = LIBUSB_ERROR_NOT_SUPPORTED;
break;
}
if (err)
return (err);
if (write(hpriv->pipe[1], &itransfer, sizeof(itransfer)) < 0)
return _errno_to_libusb(errno);
return (LIBUSB_SUCCESS);
}
int
netbsd_cancel_transfer(struct usbi_transfer *itransfer)
{
usbi_dbg("");
return (LIBUSB_ERROR_NOT_SUPPORTED);
}
void
netbsd_clear_transfer_priv(struct usbi_transfer *itransfer)
{
usbi_dbg("");
/* Nothing to do */
}
int
netbsd_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds_t nfds,
int num_ready)
{
struct libusb_device_handle *handle;
struct handle_priv *hpriv = NULL;
struct usbi_transfer *itransfer;
struct pollfd *pollfd;
int i, err = 0;
usbi_dbg("");
pthread_mutex_lock(&ctx->open_devs_lock);
for (i = 0; i < nfds && num_ready > 0; i++) {
pollfd = &fds[i];
if (!pollfd->revents)
continue;
hpriv = NULL;
num_ready--;
list_for_each_entry(handle, &ctx->open_devs, list,
struct libusb_device_handle) {
hpriv = (struct handle_priv *)handle->os_priv;
if (hpriv->pipe[0] == pollfd->fd)
break;
hpriv = NULL;
}
if (NULL == hpriv) {
usbi_dbg("fd %d is not an event pipe!", pollfd->fd);
err = ENOENT;
break;
}
if (pollfd->revents & POLLERR) {
usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]);
usbi_handle_disconnect(handle);
continue;
}
if (read(hpriv->pipe[0], &itransfer, sizeof(itransfer)) < 0) {
err = errno;
break;
}
if ((err = usbi_handle_transfer_completion(itransfer,
LIBUSB_TRANSFER_COMPLETED)))
break;
}
pthread_mutex_unlock(&ctx->open_devs_lock);
if (err)
return _errno_to_libusb(err);
return (LIBUSB_SUCCESS);
}
int
netbsd_clock_gettime(int clkid, struct timespec *tp)
{
usbi_dbg("clock %d", clkid);
if (clkid == USBI_CLOCK_REALTIME)
return clock_gettime(CLOCK_REALTIME, tp);
if (clkid == USBI_CLOCK_MONOTONIC)
return clock_gettime(CLOCK_MONOTONIC, tp);
return (LIBUSB_ERROR_INVALID_PARAM);
}
int
_errno_to_libusb(int err)
{
switch (err) {
case EIO:
return (LIBUSB_ERROR_IO);
case EACCES:
return (LIBUSB_ERROR_ACCESS);
case ENOENT:
return (LIBUSB_ERROR_NO_DEVICE);
case ENOMEM:
return (LIBUSB_ERROR_NO_MEM);
}
usbi_dbg("error: %s", strerror(err));
return (LIBUSB_ERROR_OTHER);
}
int
_cache_active_config_descriptor(struct libusb_device *dev, int fd)
{
struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
struct usb_config_desc ucd;
struct usb_full_desc ufd;
unsigned char* buf;
int len;
usbi_dbg("fd %d", fd);
ucd.ucd_config_index = USB_CURRENT_CONFIG_INDEX;
if ((ioctl(fd, USB_GET_CONFIG_DESC, &ucd)) < 0)
return _errno_to_libusb(errno);
usbi_dbg("active bLength %d", ucd.ucd_desc.bLength);
len = UGETW(ucd.ucd_desc.wTotalLength);
buf = malloc(len);
if (buf == NULL)
return (LIBUSB_ERROR_NO_MEM);
ufd.ufd_config_index = ucd.ucd_config_index;
ufd.ufd_size = len;
ufd.ufd_data = buf;
usbi_dbg("index %d, len %d", ufd.ufd_config_index, len);
if ((ioctl(fd, USB_GET_FULL_DESC, &ufd)) < 0) {
free(buf);
return _errno_to_libusb(errno);
}
if (dpriv->cdesc)
free(dpriv->cdesc);
dpriv->cdesc = buf;
return (0);
}
int
_sync_control_transfer(struct usbi_transfer *itransfer)
{
struct libusb_transfer *transfer;
struct libusb_control_setup *setup;
struct device_priv *dpriv;
struct usb_ctl_request req;
transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv;
setup = (struct libusb_control_setup *)transfer->buffer;
usbi_dbg("type %d request %d value %d index %d length %d timeout %d",
setup->bmRequestType, setup->bRequest,
libusb_le16_to_cpu(setup->wValue),
libusb_le16_to_cpu(setup->wIndex),
libusb_le16_to_cpu(setup->wLength), transfer->timeout);
req.ucr_request.bmRequestType = setup->bmRequestType;
req.ucr_request.bRequest = setup->bRequest;
/* Don't use USETW, libusb already deals with the endianness */
(*(uint16_t *)req.ucr_request.wValue) = setup->wValue;
(*(uint16_t *)req.ucr_request.wIndex) = setup->wIndex;
(*(uint16_t *)req.ucr_request.wLength) = setup->wLength;
req.ucr_data = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0)
req.ucr_flags = USBD_SHORT_XFER_OK;
if ((ioctl(dpriv->fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0)
return _errno_to_libusb(errno);
if ((ioctl(dpriv->fd, USB_DO_REQUEST, &req)) < 0)
return _errno_to_libusb(errno);
itransfer->transferred = req.ucr_actlen;
usbi_dbg("transferred %d", itransfer->transferred);
return (0);
}
int
_access_endpoint(struct libusb_transfer *transfer)
{
struct handle_priv *hpriv;
struct device_priv *dpriv;
char *s, devnode[16];
int fd, endpt;
mode_t mode;
hpriv = (struct handle_priv *)transfer->dev_handle->os_priv;
dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv;
endpt = UE_GET_ADDR(transfer->endpoint);
mode = IS_XFERIN(transfer) ? O_RDONLY : O_WRONLY;
usbi_dbg("endpoint %d mode %d", endpt, mode);
if (hpriv->endpoints[endpt] < 0) {
/* Pick the right node given the control one */
strlcpy(devnode, dpriv->devnode, sizeof(devnode));
s = strchr(devnode, '.');
snprintf(s, 4, ".%02d", endpt);
/* We may need to read/write to the same endpoint later. */
if (((fd = open(devnode, O_RDWR)) < 0) && (errno == ENXIO))
if ((fd = open(devnode, mode)) < 0)
return (-1);
hpriv->endpoints[endpt] = fd;
}
return (hpriv->endpoints[endpt]);
}
int
_sync_gen_transfer(struct usbi_transfer *itransfer)
{
struct libusb_transfer *transfer;
int fd, nr = 1;
transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
/*
* Bulk, Interrupt or Isochronous transfer depends on the
* endpoint and thus the node to open.
*/
if ((fd = _access_endpoint(transfer)) < 0)
return _errno_to_libusb(errno);
if ((ioctl(fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0)
return _errno_to_libusb(errno);
if (IS_XFERIN(transfer)) {
if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0)
if ((ioctl(fd, USB_SET_SHORT_XFER, &nr)) < 0)
return _errno_to_libusb(errno);
nr = read(fd, transfer->buffer, transfer->length);
} else {
nr = write(fd, transfer->buffer, transfer->length);
}
if (nr < 0)
return _errno_to_libusb(errno);
itransfer->transferred = nr;
return (0);
}

View File

@ -0,0 +1,832 @@
/*
* Copyright © 2011-2013 Martin Pieuchot <mpi@openbsd.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <sys/time.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dev/usb/usb.h>
#include "libusb.h"
#include "libusbi.h"
struct device_priv {
char *devname; /* name of the ugen(4) node */
int fd; /* device file descriptor */
unsigned char *cdesc; /* active config descriptor */
usb_device_descriptor_t ddesc; /* usb device descriptor */
};
struct handle_priv {
int pipe[2]; /* for event notification */
int endpoints[USB_MAX_ENDPOINTS];
};
/*
* Backend functions
*/
static int obsd_get_device_list(struct libusb_context *,
struct discovered_devs **);
static int obsd_open(struct libusb_device_handle *);
static void obsd_close(struct libusb_device_handle *);
static int obsd_get_device_descriptor(struct libusb_device *, unsigned char *,
int *);
static int obsd_get_active_config_descriptor(struct libusb_device *,
unsigned char *, size_t, int *);
static int obsd_get_config_descriptor(struct libusb_device *, uint8_t,
unsigned char *, size_t, int *);
static int obsd_get_configuration(struct libusb_device_handle *, int *);
static int obsd_set_configuration(struct libusb_device_handle *, int);
static int obsd_claim_interface(struct libusb_device_handle *, int);
static int obsd_release_interface(struct libusb_device_handle *, int);
static int obsd_set_interface_altsetting(struct libusb_device_handle *, int,
int);
static int obsd_clear_halt(struct libusb_device_handle *, unsigned char);
static int obsd_reset_device(struct libusb_device_handle *);
static void obsd_destroy_device(struct libusb_device *);
static int obsd_submit_transfer(struct usbi_transfer *);
static int obsd_cancel_transfer(struct usbi_transfer *);
static void obsd_clear_transfer_priv(struct usbi_transfer *);
static int obsd_handle_events(struct libusb_context *ctx, struct pollfd *,
nfds_t, int);
static int obsd_clock_gettime(int, struct timespec *);
/*
* Private functions
*/
static int _errno_to_libusb(int);
static int _cache_active_config_descriptor(struct libusb_device *);
static int _sync_control_transfer(struct usbi_transfer *);
static int _sync_gen_transfer(struct usbi_transfer *);
static int _access_endpoint(struct libusb_transfer *);
static int _bus_open(int);
const struct usbi_os_backend openbsd_backend = {
"Synchronous OpenBSD backend",
0,
NULL, /* init() */
NULL, /* exit() */
obsd_get_device_list,
NULL, /* hotplug_poll */
obsd_open,
obsd_close,
obsd_get_device_descriptor,
obsd_get_active_config_descriptor,
obsd_get_config_descriptor,
NULL, /* get_config_descriptor_by_value() */
obsd_get_configuration,
obsd_set_configuration,
obsd_claim_interface,
obsd_release_interface,
obsd_set_interface_altsetting,
obsd_clear_halt,
obsd_reset_device,
NULL, /* alloc_streams */
NULL, /* free_streams */
NULL, /* kernel_driver_active() */
NULL, /* detach_kernel_driver() */
NULL, /* attach_kernel_driver() */
obsd_destroy_device,
obsd_submit_transfer,
obsd_cancel_transfer,
obsd_clear_transfer_priv,
obsd_handle_events,
obsd_clock_gettime,
sizeof(struct device_priv),
sizeof(struct handle_priv),
0, /* transfer_priv_size */
0, /* add_iso_packet_size */
};
#define DEVPATH "/dev/"
#define USBDEV DEVPATH "usb"
int
obsd_get_device_list(struct libusb_context * ctx,
struct discovered_devs **discdevs)
{
struct discovered_devs *ddd;
struct libusb_device *dev;
struct device_priv *dpriv;
struct usb_device_info di;
struct usb_device_ddesc dd;
unsigned long session_id;
char devices[USB_MAX_DEVICES];
char busnode[16];
char *udevname;
int fd, addr, i, j;
usbi_dbg("");
for (i = 0; i < 8; i++) {
snprintf(busnode, sizeof(busnode), USBDEV "%d", i);
if ((fd = open(busnode, O_RDWR)) < 0) {
if (errno != ENOENT && errno != ENXIO)
usbi_err(ctx, "could not open %s", busnode);
continue;
}
bzero(devices, sizeof(devices));
for (addr = 1; addr < USB_MAX_DEVICES; addr++) {
if (devices[addr])
continue;
di.udi_addr = addr;
if (ioctl(fd, USB_DEVICEINFO, &di) < 0)
continue;
/*
* XXX If ugen(4) is attached to the USB device
* it will be used.
*/
udevname = NULL;
for (j = 0; j < USB_MAX_DEVNAMES; j++)
if (!strncmp("ugen", di.udi_devnames[j], 4)) {
udevname = strdup(di.udi_devnames[j]);
break;
}
session_id = (di.udi_bus << 8 | di.udi_addr);
dev = usbi_get_device_by_session_id(ctx, session_id);
if (dev == NULL) {
dev = usbi_alloc_device(ctx, session_id);
if (dev == NULL) {
close(fd);
return (LIBUSB_ERROR_NO_MEM);
}
dev->bus_number = di.udi_bus;
dev->device_address = di.udi_addr;
dev->speed = di.udi_speed;
dpriv = (struct device_priv *)dev->os_priv;
dpriv->fd = -1;
dpriv->cdesc = NULL;
dpriv->devname = udevname;
dd.udd_bus = di.udi_bus;
dd.udd_addr = di.udi_addr;
if (ioctl(fd, USB_DEVICE_GET_DDESC, &dd) < 0) {
libusb_unref_device(dev);
continue;
}
dpriv->ddesc = dd.udd_desc;
if (_cache_active_config_descriptor(dev)) {
libusb_unref_device(dev);
continue;
}
if (usbi_sanitize_device(dev)) {
libusb_unref_device(dev);
continue;
}
}
ddd = discovered_devs_append(*discdevs, dev);
if (ddd == NULL) {
close(fd);
return (LIBUSB_ERROR_NO_MEM);
}
libusb_unref_device(dev);
*discdevs = ddd;
devices[addr] = 1;
}
close(fd);
}
return (LIBUSB_SUCCESS);
}
int
obsd_open(struct libusb_device_handle *handle)
{
struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
char devnode[16];
if (dpriv->devname) {
/*
* Only open ugen(4) attached devices read-write, all
* read-only operations are done through the bus node.
*/
snprintf(devnode, sizeof(devnode), DEVPATH "%s.00",
dpriv->devname);
dpriv->fd = open(devnode, O_RDWR);
if (dpriv->fd < 0)
return _errno_to_libusb(errno);
usbi_dbg("open %s: fd %d", devnode, dpriv->fd);
}
if (pipe(hpriv->pipe) < 0)
return _errno_to_libusb(errno);
return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->pipe[0], POLLIN);
}
void
obsd_close(struct libusb_device_handle *handle)
{
struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
if (dpriv->devname) {
usbi_dbg("close: fd %d", dpriv->fd);
close(dpriv->fd);
dpriv->fd = -1;
}
usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]);
close(hpriv->pipe[0]);
close(hpriv->pipe[1]);
}
int
obsd_get_device_descriptor(struct libusb_device *dev, unsigned char *buf,
int *host_endian)
{
struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
usbi_dbg("");
memcpy(buf, &dpriv->ddesc, DEVICE_DESC_LENGTH);
*host_endian = 0;
return (LIBUSB_SUCCESS);
}
int
obsd_get_active_config_descriptor(struct libusb_device *dev,
unsigned char *buf, size_t len, int *host_endian)
{
struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
usb_config_descriptor_t *ucd = (usb_config_descriptor_t *)dpriv->cdesc;
len = MIN(len, UGETW(ucd->wTotalLength));
usbi_dbg("len %d", len);
memcpy(buf, dpriv->cdesc, len);
*host_endian = 0;
return (len);
}
int
obsd_get_config_descriptor(struct libusb_device *dev, uint8_t idx,
unsigned char *buf, size_t len, int *host_endian)
{
struct usb_device_fdesc udf;
int fd, err;
if ((fd = _bus_open(dev->bus_number)) < 0)
return _errno_to_libusb(errno);
udf.udf_bus = dev->bus_number;
udf.udf_addr = dev->device_address;
udf.udf_config_index = idx;
udf.udf_size = len;
udf.udf_data = buf;
usbi_dbg("index %d, len %d", udf.udf_config_index, len);
if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) {
err = errno;
close(fd);
return _errno_to_libusb(err);
}
close(fd);
*host_endian = 0;
return (len);
}
int
obsd_get_configuration(struct libusb_device_handle *handle, int *config)
{
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
usb_config_descriptor_t *ucd = (usb_config_descriptor_t *)dpriv->cdesc;
*config = ucd->bConfigurationValue;
usbi_dbg("bConfigurationValue %d", *config);
return (LIBUSB_SUCCESS);
}
int
obsd_set_configuration(struct libusb_device_handle *handle, int config)
{
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
if (dpriv->devname == NULL)
return (LIBUSB_ERROR_NOT_SUPPORTED);
usbi_dbg("bConfigurationValue %d", config);
if (ioctl(dpriv->fd, USB_SET_CONFIG, &config) < 0)
return _errno_to_libusb(errno);
return _cache_active_config_descriptor(handle->dev);
}
int
obsd_claim_interface(struct libusb_device_handle *handle, int iface)
{
struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
int i;
for (i = 0; i < USB_MAX_ENDPOINTS; i++)
hpriv->endpoints[i] = -1;
return (LIBUSB_SUCCESS);
}
int
obsd_release_interface(struct libusb_device_handle *handle, int iface)
{
struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
int i;
for (i = 0; i < USB_MAX_ENDPOINTS; i++)
if (hpriv->endpoints[i] >= 0)
close(hpriv->endpoints[i]);
return (LIBUSB_SUCCESS);
}
int
obsd_set_interface_altsetting(struct libusb_device_handle *handle, int iface,
int altsetting)
{
struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
struct usb_alt_interface intf;
if (dpriv->devname == NULL)
return (LIBUSB_ERROR_NOT_SUPPORTED);
usbi_dbg("iface %d, setting %d", iface, altsetting);
memset(&intf, 0, sizeof(intf));
intf.uai_interface_index = iface;
intf.uai_alt_no = altsetting;
if (ioctl(dpriv->fd, USB_SET_ALTINTERFACE, &intf) < 0)
return _errno_to_libusb(errno);
return (LIBUSB_SUCCESS);
}
int
obsd_clear_halt(struct libusb_device_handle *handle, unsigned char endpoint)
{
struct usb_ctl_request req;
int fd, err;
if ((fd = _bus_open(handle->dev->bus_number)) < 0)
return _errno_to_libusb(errno);
usbi_dbg("");
req.ucr_addr = handle->dev->device_address;
req.ucr_request.bmRequestType = UT_WRITE_ENDPOINT;
req.ucr_request.bRequest = UR_CLEAR_FEATURE;
USETW(req.ucr_request.wValue, UF_ENDPOINT_HALT);
USETW(req.ucr_request.wIndex, endpoint);
USETW(req.ucr_request.wLength, 0);
if (ioctl(fd, USB_REQUEST, &req) < 0) {
err = errno;
close(fd);
return _errno_to_libusb(err);
}
close(fd);
return (LIBUSB_SUCCESS);
}
int
obsd_reset_device(struct libusb_device_handle *handle)
{
usbi_dbg("");
return (LIBUSB_ERROR_NOT_SUPPORTED);
}
void
obsd_destroy_device(struct libusb_device *dev)
{
struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
usbi_dbg("");
free(dpriv->cdesc);
free(dpriv->devname);
}
int
obsd_submit_transfer(struct usbi_transfer *itransfer)
{
struct libusb_transfer *transfer;
struct handle_priv *hpriv;
int err = 0;
usbi_dbg("");
transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
hpriv = (struct handle_priv *)transfer->dev_handle->os_priv;
switch (transfer->type) {
case LIBUSB_TRANSFER_TYPE_CONTROL:
err = _sync_control_transfer(itransfer);
break;
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
if (IS_XFEROUT(transfer)) {
/* Isochronous write is not supported */
err = LIBUSB_ERROR_NOT_SUPPORTED;
break;
}
err = _sync_gen_transfer(itransfer);
break;
case LIBUSB_TRANSFER_TYPE_BULK:
case LIBUSB_TRANSFER_TYPE_INTERRUPT:
if (IS_XFEROUT(transfer) &&
transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
err = LIBUSB_ERROR_NOT_SUPPORTED;
break;
}
err = _sync_gen_transfer(itransfer);
break;
case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
err = LIBUSB_ERROR_NOT_SUPPORTED;
break;
}
if (err)
return (err);
if (write(hpriv->pipe[1], &itransfer, sizeof(itransfer)) < 0)
return _errno_to_libusb(errno);
return (LIBUSB_SUCCESS);
}
int
obsd_cancel_transfer(struct usbi_transfer *itransfer)
{
usbi_dbg("");
return (LIBUSB_ERROR_NOT_SUPPORTED);
}
void
obsd_clear_transfer_priv(struct usbi_transfer *itransfer)
{
usbi_dbg("");
/* Nothing to do */
}
int
obsd_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds_t nfds,
int num_ready)
{
struct libusb_device_handle *handle;
struct handle_priv *hpriv = NULL;
struct usbi_transfer *itransfer;
struct pollfd *pollfd;
int i, err = 0;
usbi_dbg("");
pthread_mutex_lock(&ctx->open_devs_lock);
for (i = 0; i < nfds && num_ready > 0; i++) {
pollfd = &fds[i];
if (!pollfd->revents)
continue;
hpriv = NULL;
num_ready--;
list_for_each_entry(handle, &ctx->open_devs, list,
struct libusb_device_handle) {
hpriv = (struct handle_priv *)handle->os_priv;
if (hpriv->pipe[0] == pollfd->fd)
break;
hpriv = NULL;
}
if (NULL == hpriv) {
usbi_dbg("fd %d is not an event pipe!", pollfd->fd);
err = ENOENT;
break;
}
if (pollfd->revents & POLLERR) {
usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]);
usbi_handle_disconnect(handle);
continue;
}
if (read(hpriv->pipe[0], &itransfer, sizeof(itransfer)) < 0) {
err = errno;
break;
}
if ((err = usbi_handle_transfer_completion(itransfer,
LIBUSB_TRANSFER_COMPLETED)))
break;
}
pthread_mutex_unlock(&ctx->open_devs_lock);
if (err)
return _errno_to_libusb(err);
return (LIBUSB_SUCCESS);
}
int
obsd_clock_gettime(int clkid, struct timespec *tp)
{
usbi_dbg("clock %d", clkid);
if (clkid == USBI_CLOCK_REALTIME)
return clock_gettime(CLOCK_REALTIME, tp);
if (clkid == USBI_CLOCK_MONOTONIC)
return clock_gettime(CLOCK_MONOTONIC, tp);
return (LIBUSB_ERROR_INVALID_PARAM);
}
int
_errno_to_libusb(int err)
{
usbi_dbg("error: %s (%d)", strerror(err), err);
switch (err) {
case EIO:
return (LIBUSB_ERROR_IO);
case EACCES:
return (LIBUSB_ERROR_ACCESS);
case ENOENT:
return (LIBUSB_ERROR_NO_DEVICE);
case ENOMEM:
return (LIBUSB_ERROR_NO_MEM);
case ETIMEDOUT:
return (LIBUSB_ERROR_TIMEOUT);
}
return (LIBUSB_ERROR_OTHER);
}
int
_cache_active_config_descriptor(struct libusb_device *dev)
{
struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
struct usb_device_cdesc udc;
struct usb_device_fdesc udf;
unsigned char* buf;
int fd, len, err;
if ((fd = _bus_open(dev->bus_number)) < 0)
return _errno_to_libusb(errno);
usbi_dbg("fd %d, addr %d", fd, dev->device_address);
udc.udc_bus = dev->bus_number;
udc.udc_addr = dev->device_address;
udc.udc_config_index = USB_CURRENT_CONFIG_INDEX;
if (ioctl(fd, USB_DEVICE_GET_CDESC, &udc) < 0) {
err = errno;
close(fd);
return _errno_to_libusb(errno);
}
usbi_dbg("active bLength %d", udc.udc_desc.bLength);
len = UGETW(udc.udc_desc.wTotalLength);
buf = malloc(len);
if (buf == NULL)
return (LIBUSB_ERROR_NO_MEM);
udf.udf_bus = dev->bus_number;
udf.udf_addr = dev->device_address;
udf.udf_config_index = udc.udc_config_index;
udf.udf_size = len;
udf.udf_data = buf;
usbi_dbg("index %d, len %d", udf.udf_config_index, len);
if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) {
err = errno;
close(fd);
free(buf);
return _errno_to_libusb(err);
}
close(fd);
if (dpriv->cdesc)
free(dpriv->cdesc);
dpriv->cdesc = buf;
return (LIBUSB_SUCCESS);
}
int
_sync_control_transfer(struct usbi_transfer *itransfer)
{
struct libusb_transfer *transfer;
struct libusb_control_setup *setup;
struct device_priv *dpriv;
struct usb_ctl_request req;
transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv;
setup = (struct libusb_control_setup *)transfer->buffer;
usbi_dbg("type %x request %x value %x index %d length %d timeout %d",
setup->bmRequestType, setup->bRequest,
libusb_le16_to_cpu(setup->wValue),
libusb_le16_to_cpu(setup->wIndex),
libusb_le16_to_cpu(setup->wLength), transfer->timeout);
req.ucr_addr = transfer->dev_handle->dev->device_address;
req.ucr_request.bmRequestType = setup->bmRequestType;
req.ucr_request.bRequest = setup->bRequest;
/* Don't use USETW, libusb already deals with the endianness */
(*(uint16_t *)req.ucr_request.wValue) = setup->wValue;
(*(uint16_t *)req.ucr_request.wIndex) = setup->wIndex;
(*(uint16_t *)req.ucr_request.wLength) = setup->wLength;
req.ucr_data = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0)
req.ucr_flags = USBD_SHORT_XFER_OK;
if (dpriv->devname == NULL) {
/*
* XXX If the device is not attached to ugen(4) it is
* XXX still possible to submit a control transfer but
* XXX with the default timeout only.
*/
int fd, err;
if ((fd = _bus_open(transfer->dev_handle->dev->bus_number)) < 0)
return _errno_to_libusb(errno);
if ((ioctl(fd, USB_REQUEST, &req)) < 0) {
err = errno;
close(fd);
return _errno_to_libusb(err);
}
close(fd);
} else {
if ((ioctl(dpriv->fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0)
return _errno_to_libusb(errno);
if ((ioctl(dpriv->fd, USB_DO_REQUEST, &req)) < 0)
return _errno_to_libusb(errno);
}
itransfer->transferred = req.ucr_actlen;
usbi_dbg("transferred %d", itransfer->transferred);
return (0);
}
int
_access_endpoint(struct libusb_transfer *transfer)
{
struct handle_priv *hpriv;
struct device_priv *dpriv;
char devnode[16];
int fd, endpt;
mode_t mode;
hpriv = (struct handle_priv *)transfer->dev_handle->os_priv;
dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv;
endpt = UE_GET_ADDR(transfer->endpoint);
mode = IS_XFERIN(transfer) ? O_RDONLY : O_WRONLY;
usbi_dbg("endpoint %d mode %d", endpt, mode);
if (hpriv->endpoints[endpt] < 0) {
/* Pick the right endpoint node */
snprintf(devnode, sizeof(devnode), DEVPATH "%s.%02d",
dpriv->devname, endpt);
/* We may need to read/write to the same endpoint later. */
if (((fd = open(devnode, O_RDWR)) < 0) && (errno == ENXIO))
if ((fd = open(devnode, mode)) < 0)
return (-1);
hpriv->endpoints[endpt] = fd;
}
return (hpriv->endpoints[endpt]);
}
int
_sync_gen_transfer(struct usbi_transfer *itransfer)
{
struct libusb_transfer *transfer;
struct device_priv *dpriv;
int fd, nr = 1;
transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv;
if (dpriv->devname == NULL)
return (LIBUSB_ERROR_NOT_SUPPORTED);
/*
* Bulk, Interrupt or Isochronous transfer depends on the
* endpoint and thus the node to open.
*/
if ((fd = _access_endpoint(transfer)) < 0)
return _errno_to_libusb(errno);
if ((ioctl(fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0)
return _errno_to_libusb(errno);
if (IS_XFERIN(transfer)) {
if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0)
if ((ioctl(fd, USB_SET_SHORT_XFER, &nr)) < 0)
return _errno_to_libusb(errno);
nr = read(fd, transfer->buffer, transfer->length);
} else {
nr = write(fd, transfer->buffer, transfer->length);
}
if (nr < 0)
return _errno_to_libusb(errno);
itransfer->transferred = nr;
return (0);
}
int
_bus_open(int number)
{
char busnode[16];
snprintf(busnode, sizeof(busnode), USBDEV "%d", number);
return open(busnode, O_RDWR);
}

View File

@ -0,0 +1,51 @@
/*
* poll_posix: poll compatibility wrapper for POSIX systems
* Copyright © 2013 RealVNC Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include "libusbi.h"
int usbi_pipe(int pipefd[2])
{
int ret = pipe(pipefd);
if (ret != 0) {
return ret;
}
ret = fcntl(pipefd[1], F_GETFL);
if (ret == -1) {
usbi_dbg("Failed to get pipe fd flags: %d", errno);
goto err_close_pipe;
}
ret = fcntl(pipefd[1], F_SETFL, ret | O_NONBLOCK);
if (ret != 0) {
usbi_dbg("Failed to set non-blocking on new pipe: %d", errno);
goto err_close_pipe;
}
return 0;
err_close_pipe:
usbi_close(pipefd[0]);
usbi_close(pipefd[1]);
return ret;
}

View File

@ -0,0 +1,11 @@
#ifndef LIBUSB_POLL_POSIX_H
#define LIBUSB_POLL_POSIX_H
#define usbi_write write
#define usbi_read read
#define usbi_close close
#define usbi_poll poll
int usbi_pipe(int pipefd[2]);
#endif /* LIBUSB_POLL_POSIX_H */

View File

@ -0,0 +1,764 @@
/*
* poll_windows: poll compatibility wrapper for Windows
* Copyright © 2012-2013 RealVNC Ltd.
* Copyright © 2009-2010 Pete Batard <pete@akeo.ie>
* With contributions from Michael Plante, Orin Eman et al.
* Parts of poll implementation from libusb-win32, by Stephan Meyer et al.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
/*
* poll() and pipe() Windows compatibility layer for libusb 1.0
*
* The way this layer works is by using OVERLAPPED with async I/O transfers, as
* OVERLAPPED have an associated event which is flagged for I/O completion.
*
* For USB pollable async I/O, you would typically:
* - obtain a Windows HANDLE to a file or device that has been opened in
* OVERLAPPED mode
* - call usbi_create_fd with this handle to obtain a custom fd.
* Note that if you need simultaneous R/W access, you need to call create_fd
* twice, once in RW_READ and once in RW_WRITE mode to obtain 2 separate
* pollable fds
* - leave the core functions call the poll routine and flag POLLIN/POLLOUT
*
* The pipe pollable synchronous I/O works using the overlapped event associated
* with a fake pipe. The read/write functions are only meant to be used in that
* context.
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include "libusb-1.0/libusbi.h"
// Uncomment to debug the polling layer
//#define DEBUG_POLL_WINDOWS
#if defined(DEBUG_POLL_WINDOWS)
#define poll_dbg usbi_dbg
#else
// MSVC++ < 2005 cannot use a variadic argument and non MSVC
// compilers produce warnings if parenthesis are ommitted.
#if defined(_MSC_VER) && (_MSC_VER < 1400)
#define poll_dbg
#else
#define poll_dbg(...)
#endif
#endif
#if defined(_PREFAST_)
#pragma warning(disable:28719)
#endif
#define CHECK_INIT_POLLING do {if(!is_polling_set) init_polling();} while(0)
// public fd data
const struct winfd INVALID_WINFD = {-1, INVALID_HANDLE_VALUE, NULL, NULL, NULL, RW_NONE};
struct winfd poll_fd[MAX_FDS];
// internal fd data
struct {
CRITICAL_SECTION mutex; // lock for fds
// Additional variables for XP CancelIoEx partial emulation
HANDLE original_handle;
DWORD thread_id;
HANDLE waitEvent;
} _poll_fd[MAX_FDS];
// globals
BOOLEAN is_polling_set = FALSE;
LONG pipe_number = 0;
static volatile LONG compat_spinlock = 0;
static HANDLE wait_event;
static VOID CALLBACK cb_wait_event(PVOID lpParameter, BOOLEAN TimerOrWaitFired) {
SetEvent(wait_event);
}
#if !defined(_WIN32_WCE)
// CancelIoEx, available on Vista and later only, provides the ability to cancel
// a single transfer (OVERLAPPED) when used. As it may not be part of any of the
// platform headers, we hook into the Kernel32 system DLL directly to seek it.
static BOOL (__stdcall *pCancelIoEx)(HANDLE, LPOVERLAPPED) = NULL;
#define Use_Duplicate_Handles (pCancelIoEx == NULL)
static inline void setup_cancel_io(void)
{
HMODULE hKernel32 = GetModuleHandleA("KERNEL32");
if (hKernel32 != NULL) {
pCancelIoEx = (BOOL (__stdcall *)(HANDLE,LPOVERLAPPED))
GetProcAddress(hKernel32, "CancelIoEx");
}
usbi_dbg("Will use CancelIo%s for I/O cancellation",
Use_Duplicate_Handles?"":"Ex");
}
static inline BOOL cancel_io(int _index)
{
if ((_index < 0) || (_index >= MAX_FDS)) {
return FALSE;
}
if ( (poll_fd[_index].fd < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE)
|| (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL) ) {
return TRUE;
}
if (poll_fd[_index].itransfer && poll_fd[_index].cancel_fn) {
// Cancel outstanding transfer via the specific callback
(*poll_fd[_index].cancel_fn)(poll_fd[_index].itransfer);
return TRUE;
}
if (pCancelIoEx != NULL) {
return (*pCancelIoEx)(poll_fd[_index].handle, poll_fd[_index].overlapped);
}
if (_poll_fd[_index].thread_id == GetCurrentThreadId()) {
return CancelIo(poll_fd[_index].handle);
}
usbi_warn(NULL, "Unable to cancel I/O that was started from another thread");
return FALSE;
}
#else
#define Use_Duplicate_Handles FALSE
static __inline void setup_cancel_io()
{
// No setup needed on WinCE
}
static __inline BOOL cancel_io(int _index)
{
if ((_index < 0) || (_index >= MAX_FDS)) {
return FALSE;
}
if ( (poll_fd[_index].fd < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE)
|| (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL) ) {
return TRUE;
}
if (poll_fd[_index].itransfer && poll_fd[_index].cancel_fn) {
// Cancel outstanding transfer via the specific callback
(*poll_fd[_index].cancel_fn)(poll_fd[_index].itransfer);
}
return TRUE;
}
#endif
// Init
void init_polling(void)
{
int i;
while (InterlockedExchange((LONG *)&compat_spinlock, 1) == 1) {
SleepEx(0, TRUE);
}
if (!is_polling_set) {
setup_cancel_io();
for (i=0; i<MAX_FDS; i++) {
poll_fd[i] = INVALID_WINFD;
_poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
_poll_fd[i].thread_id = 0;
InitializeCriticalSection(&_poll_fd[i].mutex);
_poll_fd[i].waitEvent = INVALID_HANDLE_VALUE;
}
wait_event = CreateEvent(NULL, TRUE, FALSE, NULL);
is_polling_set = TRUE;
}
InterlockedExchange((LONG *)&compat_spinlock, 0);
}
// Internal function to retrieve the table index (and lock the fd mutex)
static int _fd_to_index_and_lock(int fd)
{
int i;
if (fd < 0)
return -1;
for (i=0; i<MAX_FDS; i++) {
if (poll_fd[i].fd == fd) {
EnterCriticalSection(&_poll_fd[i].mutex);
// fd might have changed before we got to critical
if (poll_fd[i].fd != fd) {
LeaveCriticalSection(&_poll_fd[i].mutex);
continue;
}
return i;
}
}
return -1;
}
static OVERLAPPED *create_overlapped(void)
{
OVERLAPPED *overlapped = (OVERLAPPED*) calloc(1, sizeof(OVERLAPPED));
if (overlapped == NULL) {
return NULL;
}
overlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if(overlapped->hEvent == NULL) {
free (overlapped);
return NULL;
}
return overlapped;
}
static void free_overlapped(OVERLAPPED *overlapped)
{
if (overlapped == NULL)
return;
if ( (overlapped->hEvent != 0)
&& (overlapped->hEvent != INVALID_HANDLE_VALUE) ) {
CloseHandle(overlapped->hEvent);
}
free(overlapped);
}
void exit_polling(void)
{
int i;
while (InterlockedExchange((LONG *)&compat_spinlock, 1) == 1) {
SleepEx(0, TRUE);
}
if (is_polling_set) {
is_polling_set = FALSE;
for (i=0; i<MAX_FDS; i++) {
// Cancel any async I/O (handle can be invalid)
cancel_io(i);
// If anything was pending on that I/O, it should be
// terminating, and we should be able to access the fd
// mutex lock before too long
EnterCriticalSection(&_poll_fd[i].mutex);
free_overlapped(poll_fd[i].overlapped);
if (Use_Duplicate_Handles) {
// Close duplicate handle
if (_poll_fd[i].original_handle != INVALID_HANDLE_VALUE) {
CloseHandle(poll_fd[i].handle);
}
}
poll_fd[i] = INVALID_WINFD;
LeaveCriticalSection(&_poll_fd[i].mutex);
DeleteCriticalSection(&_poll_fd[i].mutex);
}
}
InterlockedExchange((LONG *)&compat_spinlock, 0);
}
/*
* Create a fake pipe.
* As libusb only uses pipes for signaling, all we need from a pipe is an
* event. To that extent, we create a single wfd and overlapped as a means
* to access that event.
*/
int usbi_pipe(int filedes[2])
{
int i;
OVERLAPPED* overlapped;
CHECK_INIT_POLLING;
overlapped = create_overlapped();
if (overlapped == NULL) {
return -1;
}
// The overlapped must have status pending for signaling to work in poll
overlapped->Internal = STATUS_PENDING;
overlapped->InternalHigh = 0;
for (i=0; i<MAX_FDS; i++) {
if (poll_fd[i].fd < 0) {
EnterCriticalSection(&_poll_fd[i].mutex);
// fd might have been allocated before we got to critical
if (poll_fd[i].fd >= 0) {
LeaveCriticalSection(&_poll_fd[i].mutex);
continue;
}
// Use index as the unique fd number
poll_fd[i].fd = i;
// Read end of the "pipe"
filedes[0] = poll_fd[i].fd;
// We can use the same handle for both ends
filedes[1] = filedes[0];
poll_fd[i].handle = DUMMY_HANDLE;
poll_fd[i].overlapped = overlapped;
// There's no polling on the write end, so we just use READ for our needs
poll_fd[i].rw = RW_READ;
_poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
LeaveCriticalSection(&_poll_fd[i].mutex);
return 0;
}
}
free_overlapped(overlapped);
return -1;
}
/*
* Create both an fd and an OVERLAPPED from an open Windows handle, so that
* it can be used with our polling function
* The handle MUST support overlapped transfers (usually requires CreateFile
* with FILE_FLAG_OVERLAPPED)
* Return a pollable file descriptor struct, or INVALID_WINFD on error
*
* Note that the fd returned by this function is a per-transfer fd, rather
* than a per-session fd and cannot be used for anything else but our
* custom functions (the fd itself points to the NUL: device)
* if you plan to do R/W on the same handle, you MUST create 2 fds: one for
* read and one for write. Using a single R/W fd is unsupported and will
* produce unexpected results
*/
struct winfd usbi_create_fd(HANDLE handle, int access_mode, struct usbi_transfer *itransfer, cancel_transfer *cancel_fn)
{
int i;
struct winfd wfd = INVALID_WINFD;
OVERLAPPED* overlapped = NULL;
CHECK_INIT_POLLING;
if ((handle == 0) || (handle == INVALID_HANDLE_VALUE)) {
return INVALID_WINFD;
}
wfd.itransfer = itransfer;
wfd.cancel_fn = cancel_fn;
if ((access_mode != RW_READ) && (access_mode != RW_WRITE)) {
usbi_warn(NULL, "only one of RW_READ or RW_WRITE are supported.\n"
"If you want to poll for R/W simultaneously, create multiple fds from the same handle.");
return INVALID_WINFD;
}
if (access_mode == RW_READ) {
wfd.rw = RW_READ;
} else {
wfd.rw = RW_WRITE;
}
overlapped = create_overlapped();
if(overlapped == NULL) {
return INVALID_WINFD;
}
for (i=0; i<MAX_FDS; i++) {
if (poll_fd[i].fd < 0) {
EnterCriticalSection(&_poll_fd[i].mutex);
// fd might have been removed before we got to critical
if (poll_fd[i].fd >= 0) {
LeaveCriticalSection(&_poll_fd[i].mutex);
continue;
}
// Use index as the unique fd number
wfd.fd = i;
// Attempt to emulate some of the CancelIoEx behaviour on platforms
// that don't have it
if (Use_Duplicate_Handles) {
_poll_fd[i].thread_id = GetCurrentThreadId();
if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(),
&wfd.handle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
usbi_dbg("could not duplicate handle for CancelIo - using original one");
wfd.handle = handle;
// Make sure we won't close the original handle on fd deletion then
_poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
} else {
_poll_fd[i].original_handle = handle;
}
} else {
wfd.handle = handle;
}
wfd.overlapped = overlapped;
memcpy(&poll_fd[i], &wfd, sizeof(struct winfd));
LeaveCriticalSection(&_poll_fd[i].mutex);
return wfd;
}
}
free_overlapped(overlapped);
return INVALID_WINFD;
}
static void _free_index(int _index)
{
// Cancel any async IO (Don't care about the validity of our handles for this)
cancel_io(_index);
// close the duplicate handle (if we have an actual duplicate)
if (Use_Duplicate_Handles) {
if (_poll_fd[_index].original_handle != INVALID_HANDLE_VALUE) {
CloseHandle(poll_fd[_index].handle);
}
_poll_fd[_index].original_handle = INVALID_HANDLE_VALUE;
_poll_fd[_index].thread_id = 0;
}
if (_poll_fd[_index].waitEvent != INVALID_HANDLE_VALUE) {
UnregisterWait(_poll_fd[_index].waitEvent);
_poll_fd[_index].waitEvent = INVALID_HANDLE_VALUE;
}
free_overlapped(poll_fd[_index].overlapped);
poll_fd[_index] = INVALID_WINFD;
}
/*
* Release a pollable file descriptor.
*
* Note that the associated Windows handle is not closed by this call
*/
void usbi_free_fd(struct winfd *wfd)
{
int _index;
CHECK_INIT_POLLING;
_index = _fd_to_index_and_lock(wfd->fd);
if (_index < 0) {
return;
}
_free_index(_index);
*wfd = INVALID_WINFD;
LeaveCriticalSection(&_poll_fd[_index].mutex);
}
/*
* The functions below perform various conversions between fd, handle and OVERLAPPED
*/
struct winfd fd_to_winfd(int fd)
{
int i;
struct winfd wfd;
CHECK_INIT_POLLING;
if (fd < 0)
return INVALID_WINFD;
for (i=0; i<MAX_FDS; i++) {
if (poll_fd[i].fd == fd) {
EnterCriticalSection(&_poll_fd[i].mutex);
// fd might have been deleted before we got to critical
if (poll_fd[i].fd != fd) {
LeaveCriticalSection(&_poll_fd[i].mutex);
continue;
}
memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
LeaveCriticalSection(&_poll_fd[i].mutex);
return wfd;
}
}
return INVALID_WINFD;
}
struct winfd handle_to_winfd(HANDLE handle)
{
int i;
struct winfd wfd;
CHECK_INIT_POLLING;
if ((handle == 0) || (handle == INVALID_HANDLE_VALUE))
return INVALID_WINFD;
for (i=0; i<MAX_FDS; i++) {
if (poll_fd[i].handle == handle) {
EnterCriticalSection(&_poll_fd[i].mutex);
// fd might have been deleted before we got to critical
if (poll_fd[i].handle != handle) {
LeaveCriticalSection(&_poll_fd[i].mutex);
continue;
}
memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
LeaveCriticalSection(&_poll_fd[i].mutex);
return wfd;
}
}
return INVALID_WINFD;
}
struct winfd overlapped_to_winfd(OVERLAPPED* overlapped)
{
int i;
struct winfd wfd;
CHECK_INIT_POLLING;
if (overlapped == NULL)
return INVALID_WINFD;
for (i=0; i<MAX_FDS; i++) {
if (poll_fd[i].overlapped == overlapped) {
EnterCriticalSection(&_poll_fd[i].mutex);
// fd might have been deleted before we got to critical
if (poll_fd[i].overlapped != overlapped) {
LeaveCriticalSection(&_poll_fd[i].mutex);
continue;
}
memcpy(&wfd, &poll_fd[i], sizeof(struct winfd));
LeaveCriticalSection(&_poll_fd[i].mutex);
return wfd;
}
}
return INVALID_WINFD;
}
/*
* POSIX poll equivalent, using Windows OVERLAPPED
* Currently, this function only accepts one of POLLIN or POLLOUT per fd
* (but you can create multiple fds from the same handle for read and write)
*/
int usbi_poll(struct pollfd *fds, unsigned int nfds, int timeout)
{
unsigned i;
int _index, object_index, triggered;
HANDLE *handles_to_wait_on;
int *handle_to_index;
DWORD nb_handles_to_wait_on = 0;
DWORD ret;
CHECK_INIT_POLLING;
triggered = 0;
handles_to_wait_on = (HANDLE*) calloc(nfds+1, sizeof(HANDLE)); // +1 for fd_update
handle_to_index = (int*) calloc(nfds, sizeof(int));
if ((handles_to_wait_on == NULL) || (handle_to_index == NULL)) {
errno = ENOMEM;
triggered = -1;
goto poll_exit;
}
for (i = 0; i < nfds; ++i) {
fds[i].revents = 0;
// Only one of POLLIN or POLLOUT can be selected with this version of poll (not both)
if ((fds[i].events & ~POLLIN) && (!(fds[i].events & POLLOUT))) {
fds[i].revents |= POLLERR;
errno = EACCES;
usbi_warn(NULL, "unsupported set of events");
triggered = -1;
goto poll_exit;
}
_index = _fd_to_index_and_lock(fds[i].fd);
poll_dbg("fd[%d]=%d: (overlapped=%p) got events %04X", i, poll_fd[_index].fd, poll_fd[_index].overlapped, fds[i].events);
if ( (_index < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE)
|| (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL)) {
fds[i].revents |= POLLNVAL | POLLERR;
errno = EBADF;
if (_index >= 0) {
LeaveCriticalSection(&_poll_fd[_index].mutex);
}
usbi_warn(NULL, "invalid fd");
triggered = -1;
goto poll_exit;
}
// IN or OUT must match our fd direction
if ((fds[i].events & POLLIN) && (poll_fd[_index].rw != RW_READ)) {
fds[i].revents |= POLLNVAL | POLLERR;
errno = EBADF;
usbi_warn(NULL, "attempted POLLIN on fd without READ access");
LeaveCriticalSection(&_poll_fd[_index].mutex);
triggered = -1;
goto poll_exit;
}
if ((fds[i].events & POLLOUT) && (poll_fd[_index].rw != RW_WRITE)) {
fds[i].revents |= POLLNVAL | POLLERR;
errno = EBADF;
usbi_warn(NULL, "attempted POLLOUT on fd without WRITE access");
LeaveCriticalSection(&_poll_fd[_index].mutex);
triggered = -1;
goto poll_exit;
}
// The following macro only works if overlapped I/O was reported pending
if ( (HasOverlappedIoCompleted(poll_fd[_index].overlapped))
|| (HasOverlappedIoCompletedSync(poll_fd[_index].overlapped)) ) {
poll_dbg(" completed");
// checks above should ensure this works:
fds[i].revents = fds[i].events;
triggered++;
} else {
if (_poll_fd[_index].waitEvent == INVALID_HANDLE_VALUE) {
if (!RegisterWaitForSingleObject(&_poll_fd[_index].waitEvent,
poll_fd[_index].overlapped->hEvent,
cb_wait_event,
NULL, INFINITE, WT_EXECUTEONLYONCE)) {
LeaveCriticalSection(&_poll_fd[_index].mutex);
triggered = -1;
goto poll_exit;
}
}
handles_to_wait_on[nb_handles_to_wait_on] = poll_fd[_index].overlapped->hEvent;
handle_to_index[nb_handles_to_wait_on] = i;
nb_handles_to_wait_on++;
}
LeaveCriticalSection(&_poll_fd[_index].mutex);
}
// If nothing was triggered, wait on all fds that require it
if ((timeout != 0) && (triggered == 0) && (nb_handles_to_wait_on != 0)) {
if (timeout < 0) {
poll_dbg("starting infinite wait for %d handles...", (int)nb_handles_to_wait_on);
} else {
poll_dbg("starting %d ms wait for %d handles...", timeout, (int)nb_handles_to_wait_on);
}
if ((ret = WaitForSingleObject(wait_event, timeout)) == WAIT_OBJECT_0) {
ResetEvent(wait_event);
for (object_index = 0; object_index < (int)nb_handles_to_wait_on; object_index++) {
if (WaitForSingleObject(handles_to_wait_on[object_index], 0) == WAIT_OBJECT_0) {
i = handle_to_index[object_index];
_index = _fd_to_index_and_lock(fds[i].fd);
fds[i].revents = fds[i].events;
UnregisterWait(_poll_fd[_index].waitEvent);
_poll_fd[_index].waitEvent = INVALID_HANDLE_VALUE;
triggered++;
if (_index >= 0) {
LeaveCriticalSection(&_poll_fd[_index].mutex);
}
}
}
} else if (ret == WAIT_TIMEOUT) {
poll_dbg(" timed out");
//triggered = 0; // 0 = timeout
} else {
DWORD err = GetLastError();
errno = EIO;
triggered = -1; // error
poll_dbg("err = 0x%08X", err);
}
}
poll_exit:
if (handles_to_wait_on != NULL) {
free(handles_to_wait_on);
}
if (handle_to_index != NULL) {
free(handle_to_index);
}
return triggered;
}
/*
* close a fake pipe fd
*/
int usbi_close(int fd)
{
int _index;
int r = -1;
CHECK_INIT_POLLING;
_index = _fd_to_index_and_lock(fd);
if (_index < 0) {
errno = EBADF;
} else {
free_overlapped(poll_fd[_index].overlapped);
poll_fd[_index] = INVALID_WINFD;
LeaveCriticalSection(&_poll_fd[_index].mutex);
}
return r;
}
/*
* synchronous write for fake "pipe" signaling
*/
ssize_t usbi_write(int fd, const void *buf, size_t count)
{
int _index;
UNUSED(buf);
CHECK_INIT_POLLING;
if (count != sizeof(unsigned char)) {
usbi_err(NULL, "this function should only used for signaling");
return -1;
}
_index = _fd_to_index_and_lock(fd);
if ( (_index < 0) || (poll_fd[_index].overlapped == NULL) ) {
errno = EBADF;
if (_index >= 0) {
LeaveCriticalSection(&_poll_fd[_index].mutex);
}
return -1;
}
poll_dbg("set pipe event (fd = %d, thread = %08X)", _index, GetCurrentThreadId());
SetEvent(poll_fd[_index].overlapped->hEvent);
poll_fd[_index].overlapped->Internal = STATUS_WAIT_0;
// If two threads write on the pipe at the same time, we need to
// process two separate reads => use the overlapped as a counter
poll_fd[_index].overlapped->InternalHigh++;
LeaveCriticalSection(&_poll_fd[_index].mutex);
return sizeof(unsigned char);
}
/*
* synchronous read for fake "pipe" signaling
*/
ssize_t usbi_read(int fd, void *buf, size_t count)
{
int _index;
ssize_t r = -1;
UNUSED(buf);
CHECK_INIT_POLLING;
if (count != sizeof(unsigned char)) {
usbi_err(NULL, "this function should only used for signaling");
return -1;
}
_index = _fd_to_index_and_lock(fd);
if (_index < 0) {
errno = EBADF;
return -1;
}
if (WaitForSingleObject(poll_fd[_index].overlapped->hEvent, INFINITE) != WAIT_OBJECT_0) {
usbi_warn(NULL, "waiting for event failed: %d", (int)GetLastError());
errno = EIO;
goto out;
}
poll_dbg("clr pipe event (fd = %d, thread = %08X)", _index, GetCurrentThreadId());
poll_fd[_index].overlapped->InternalHigh--;
// Don't reset unless we don't have any more events to process
if (poll_fd[_index].overlapped->InternalHigh <= 0) {
ResetEvent(poll_fd[_index].overlapped->hEvent);
poll_fd[_index].overlapped->Internal = STATUS_PENDING;
}
r = sizeof(unsigned char);
out:
LeaveCriticalSection(&_poll_fd[_index].mutex);
return r;
}

View File

@ -0,0 +1,131 @@
/*
* Windows compat: POSIX compatibility wrapper
* Copyright © 2012-2013 RealVNC Ltd.
* Copyright © 2009-2010 Pete Batard <pete@akeo.ie>
* With contributions from Michael Plante, Orin Eman et al.
* Parts of poll implementation from libusb-win32, by Stephan Meyer et al.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#pragma once
#if defined(_MSC_VER)
// disable /W4 MSVC warnings that are benign
#pragma warning(disable:4127) // conditional expression is constant
#endif
// Handle synchronous completion through the overlapped structure
#if !defined(STATUS_REPARSE) // reuse the REPARSE status code
#define STATUS_REPARSE ((LONG)0x00000104L)
#endif
#define STATUS_COMPLETED_SYNCHRONOUSLY STATUS_REPARSE
#if defined(_WIN32_WCE)
// WinCE doesn't have a HasOverlappedIoCompleted() macro, so attempt to emulate it
#define HasOverlappedIoCompleted(lpOverlapped) (((DWORD)(lpOverlapped)->Internal) != STATUS_PENDING)
#endif
#define HasOverlappedIoCompletedSync(lpOverlapped) (((DWORD)(lpOverlapped)->Internal) == STATUS_COMPLETED_SYNCHRONOUSLY)
#define DUMMY_HANDLE ((HANDLE)(LONG_PTR)-2)
/* Windows versions */
enum windows_version {
WINDOWS_CE = -2,
WINDOWS_UNDEFINED = -1,
WINDOWS_UNSUPPORTED = 0,
WINDOWS_XP = 0x51,
WINDOWS_2003 = 0x52, // Also XP x64
WINDOWS_VISTA = 0x60,
WINDOWS_7 = 0x61,
WINDOWS_8 = 0x62,
WINDOWS_8_1_OR_LATER = 0x63,
WINDOWS_MAX
};
extern int windows_version;
#define MAX_FDS (256*32)
#define POLLIN 0x0001 /* There is data to read */
#define POLLPRI 0x0002 /* There is urgent data to read */
#define POLLOUT 0x0004 /* Writing now will not block */
#define POLLERR 0x0008 /* Error condition */
#define POLLHUP 0x0010 /* Hung up */
#define POLLNVAL 0x0020 /* Invalid request: fd not open */
struct pollfd {
int fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */
};
// access modes
enum rw_type {
RW_NONE,
RW_READ,
RW_WRITE,
};
// fd struct that can be used for polling on Windows
typedef int cancel_transfer(struct usbi_transfer *itransfer);
struct winfd {
int fd; // what's exposed to libusb core
HANDLE handle; // what we need to attach overlapped to the I/O op, so we can poll it
OVERLAPPED* overlapped; // what will report our I/O status
struct usbi_transfer *itransfer; // Associated transfer, or NULL if completed
cancel_transfer *cancel_fn; // Function pointer to cancel transfer API
enum rw_type rw; // I/O transfer direction: read *XOR* write (NOT BOTH)
};
extern const struct winfd INVALID_WINFD;
int usbi_pipe(int pipefd[2]);
int usbi_poll(struct pollfd *fds, unsigned int nfds, int timeout);
ssize_t usbi_write(int fd, const void *buf, size_t count);
ssize_t usbi_read(int fd, void *buf, size_t count);
int usbi_close(int fd);
void init_polling(void);
void exit_polling(void);
struct winfd usbi_create_fd(HANDLE handle, int access_mode,
struct usbi_transfer *transfer, cancel_transfer *cancel_fn);
void usbi_free_fd(struct winfd* winfd);
struct winfd fd_to_winfd(int fd);
struct winfd handle_to_winfd(HANDLE handle);
struct winfd overlapped_to_winfd(OVERLAPPED* overlapped);
/*
* Timeval operations
*/
#if defined(DDKBUILD)
#include <winsock.h> // defines timeval functions on DDK
#endif
#if !defined(TIMESPEC_TO_TIMEVAL)
#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
(tv)->tv_sec = (long)(ts)->tv_sec; \
(tv)->tv_usec = (long)(ts)->tv_nsec / 1000; \
}
#endif
#if !defined(timersub)
#define timersub(a, b, result) \
do { \
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
if ((result)->tv_usec < 0) { \
--(result)->tv_sec; \
(result)->tv_usec += 1000000; \
} \
} while (0)
#endif

View File

@ -0,0 +1,82 @@
/*
* libusb synchronization using POSIX Threads
*
* Copyright © 2011 Vitali Lovich <vlovich@aliph.com>
* Copyright © 2011 Peter Stuge <peter@stuge.se>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if defined(__linux__) || defined(__OpenBSD__)
# if defined(__linux__)
# define _GNU_SOURCE
# else
# define _BSD_SOURCE
# endif
# include <unistd.h>
# include <sys/syscall.h>
#elif defined(__APPLE__)
# include <mach/mach.h>
#elif defined(__CYGWIN__)
# include <windows.h>
#endif
#include "threads_posix.h"
int usbi_mutex_init_recursive(pthread_mutex_t *mutex, pthread_mutexattr_t *attr)
{
int err;
pthread_mutexattr_t stack_attr;
if (!attr) {
attr = &stack_attr;
err = pthread_mutexattr_init(&stack_attr);
if (err != 0)
return err;
}
/* mutexattr_settype requires _GNU_SOURCE or _XOPEN_SOURCE >= 500 on Linux */
err = pthread_mutexattr_settype(attr, PTHREAD_MUTEX_RECURSIVE);
if (err != 0)
goto finish;
err = pthread_mutex_init(mutex, attr);
finish:
if (attr == &stack_attr)
pthread_mutexattr_destroy(&stack_attr);
return err;
}
int usbi_get_tid(void)
{
int ret = -1;
#if defined(__ANDROID__)
ret = gettid();
#elif defined(__linux__)
ret = syscall(SYS_gettid);
#elif defined(__OpenBSD__)
/* The following only works with OpenBSD > 5.1 as it requires
real thread support. For 5.1 and earlier, -1 is returned. */
ret = syscall(SYS_getthrid);
#elif defined(__APPLE__)
ret = mach_thread_self();
mach_port_deallocate(mach_task_self(), ret);
#elif defined(__CYGWIN__)
ret = GetCurrentThreadId();
#endif
/* TODO: NetBSD thread ID support */
return ret;
}

View File

@ -0,0 +1,50 @@
/*
* libusb synchronization using POSIX Threads
*
* Copyright © 2010 Peter Stuge <peter@stuge.se>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef LIBUSB_THREADS_POSIX_H
#define LIBUSB_THREADS_POSIX_H
#include <pthread.h>
#define usbi_mutex_static_t pthread_mutex_t
#define USBI_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
#define usbi_mutex_static_lock pthread_mutex_lock
#define usbi_mutex_static_unlock pthread_mutex_unlock
#define usbi_mutex_t pthread_mutex_t
#define usbi_mutex_init pthread_mutex_init
#define usbi_mutex_lock pthread_mutex_lock
#define usbi_mutex_unlock pthread_mutex_unlock
#define usbi_mutex_trylock pthread_mutex_trylock
#define usbi_mutex_destroy pthread_mutex_destroy
#define usbi_cond_t pthread_cond_t
#define usbi_cond_init pthread_cond_init
#define usbi_cond_wait pthread_cond_wait
#define usbi_cond_timedwait pthread_cond_timedwait
#define usbi_cond_broadcast pthread_cond_broadcast
#define usbi_cond_destroy pthread_cond_destroy
#define usbi_cond_signal pthread_cond_signal
extern int usbi_mutex_init_recursive(pthread_mutex_t *mutex, pthread_mutexattr_t *attr);
int usbi_get_tid(void);
#endif /* LIBUSB_THREADS_POSIX_H */

View File

@ -0,0 +1,212 @@
/*
* libusb synchronization on Microsoft Windows
*
* Copyright © 2010 Michael Plante <michael.plante@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <config.h>
#include <objbase.h>
#include <errno.h>
#include <stdarg.h>
#include "libusb-1.0/libusbi.h"
extern const uint64_t epoch_time;
int usbi_mutex_init(usbi_mutex_t *mutex,
const usbi_mutexattr_t *attr) {
UNUSED(attr);
if(! mutex) return ((errno=EINVAL));
*mutex = CreateMutex(NULL, FALSE, NULL);
if(!*mutex) return ((errno=ENOMEM));
return 0;
}
int usbi_mutex_destroy(usbi_mutex_t *mutex) {
// It is not clear if CloseHandle failure is due to failure to unlock.
// If so, this should be errno=EBUSY.
if(!mutex || !CloseHandle(*mutex)) return ((errno=EINVAL));
*mutex = NULL;
return 0;
}
int usbi_mutex_trylock(usbi_mutex_t *mutex) {
DWORD result;
if(!mutex) return ((errno=EINVAL));
result = WaitForSingleObject(*mutex, 0);
if(result == WAIT_OBJECT_0 || result == WAIT_ABANDONED)
return 0; // acquired (ToDo: check that abandoned is ok)
if(result == WAIT_TIMEOUT)
return ((errno=EBUSY));
return ((errno=EINVAL)); // don't know how this would happen
// so don't know proper errno
}
int usbi_mutex_lock(usbi_mutex_t *mutex) {
DWORD result;
if(!mutex) return ((errno=EINVAL));
result = WaitForSingleObject(*mutex, INFINITE);
if(result == WAIT_OBJECT_0 || result == WAIT_ABANDONED)
return 0; // acquired (ToDo: check that abandoned is ok)
return ((errno=EINVAL)); // don't know how this would happen
// so don't know proper errno
}
int usbi_mutex_unlock(usbi_mutex_t *mutex) {
if(!mutex) return ((errno=EINVAL));
if(!ReleaseMutex(*mutex)) return ((errno=EPERM ));
return 0;
}
int usbi_mutex_static_lock(usbi_mutex_static_t *mutex) {
if(!mutex) return ((errno=EINVAL));
while (InterlockedExchange((LONG *)mutex, 1) == 1) {
SleepEx(0, TRUE);
}
return 0;
}
int usbi_mutex_static_unlock(usbi_mutex_static_t *mutex) {
if(!mutex) return ((errno=EINVAL));
*mutex = 0;
return 0;
}
int usbi_cond_init(usbi_cond_t *cond,
const usbi_condattr_t *attr) {
UNUSED(attr);
if(!cond) return ((errno=EINVAL));
list_init(&cond->waiters );
list_init(&cond->not_waiting);
return 0;
}
int usbi_cond_destroy(usbi_cond_t *cond) {
// This assumes no one is using this anymore. The check MAY NOT BE safe.
struct usbi_cond_perthread *pos, *next_pos = NULL;
if(!cond) return ((errno=EINVAL));
if(!list_empty(&cond->waiters)) return ((errno=EBUSY )); // (!see above!)
list_for_each_entry_safe(pos, next_pos, &cond->not_waiting, list, struct usbi_cond_perthread) {
CloseHandle(pos->event);
list_del(&pos->list);
free(pos);
}
return 0;
}
int usbi_cond_broadcast(usbi_cond_t *cond) {
// Assumes mutex is locked; this is not in keeping with POSIX spec, but
// libusb does this anyway, so we simplify by not adding more sync
// primitives to the CV definition!
int fail = 0;
struct usbi_cond_perthread *pos;
if(!cond) return ((errno=EINVAL));
list_for_each_entry(pos, &cond->waiters, list, struct usbi_cond_perthread) {
if(!SetEvent(pos->event))
fail = 1;
}
// The wait function will remove its respective item from the list.
return fail ? ((errno=EINVAL)) : 0;
}
int usbi_cond_signal(usbi_cond_t *cond) {
// Assumes mutex is locked; this is not in keeping with POSIX spec, but
// libusb does this anyway, so we simplify by not adding more sync
// primitives to the CV definition!
struct usbi_cond_perthread *pos;
if(!cond) return ((errno=EINVAL));
if(list_empty(&cond->waiters)) return 0; // no one to wakeup.
pos = list_entry(&cond->waiters.next, struct usbi_cond_perthread, list);
// The wait function will remove its respective item from the list.
return SetEvent(pos->event) ? 0 : ((errno=EINVAL));
}
__inline static int usbi_cond_intwait(usbi_cond_t *cond,
usbi_mutex_t *mutex,
DWORD timeout_ms) {
struct usbi_cond_perthread *pos;
int found = 0, r;
DWORD r2,tid = GetCurrentThreadId();
if(!cond || !mutex) return ((errno=EINVAL));
list_for_each_entry(pos, &cond->not_waiting, list, struct usbi_cond_perthread) {
if(tid == pos->tid) {
found = 1;
break;
}
}
if(!found) {
pos = (struct usbi_cond_perthread*) calloc(1, sizeof(struct usbi_cond_perthread));
if(!pos) return ((errno=ENOMEM)); // This errno is not POSIX-allowed.
pos->tid = tid;
pos->event = CreateEvent(NULL, FALSE, FALSE, NULL); // auto-reset.
if(!pos->event) {
free(pos);
return ((errno=ENOMEM));
}
list_add(&pos->list, &cond->not_waiting);
}
list_del(&pos->list); // remove from not_waiting list.
list_add(&pos->list, &cond->waiters);
r = usbi_mutex_unlock(mutex);
if(r) return r;
r2 = WaitForSingleObject(pos->event, timeout_ms);
r = usbi_mutex_lock(mutex);
if(r) return r;
list_del(&pos->list);
list_add(&pos->list, &cond->not_waiting);
if(r2 == WAIT_TIMEOUT) return ((errno=ETIMEDOUT));
return 0;
}
// N.B.: usbi_cond_*wait() can also return ENOMEM, even though pthread_cond_*wait cannot!
int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex) {
return usbi_cond_intwait(cond, mutex, INFINITE);
}
int usbi_cond_timedwait(usbi_cond_t *cond,
usbi_mutex_t *mutex,
const struct timespec *abstime) {
FILETIME filetime;
ULARGE_INTEGER rtime;
struct timeval targ_time, cur_time, delta_time;
struct timespec cur_time_ns;
DWORD millis;
// GetSystemTimeAsFileTime() is not available on CE
SYSTEMTIME st;
GetSystemTime(&st);
SystemTimeToFileTime(&st, &filetime);
rtime.LowPart = filetime.dwLowDateTime;
rtime.HighPart = filetime.dwHighDateTime;
rtime.QuadPart -= epoch_time;
cur_time_ns.tv_sec = (long)(rtime.QuadPart / 10000000);
cur_time_ns.tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
TIMESPEC_TO_TIMEVAL(&cur_time, &cur_time_ns);
TIMESPEC_TO_TIMEVAL(&targ_time, abstime);
timersub(&targ_time, &cur_time, &delta_time);
if(delta_time.tv_sec < 0) // abstime already passed?
millis = 0;
else {
millis = delta_time.tv_usec/1000;
millis += delta_time.tv_sec *1000;
if (delta_time.tv_usec % 1000) // round up to next millisecond
millis++;
}
return usbi_cond_intwait(cond, mutex, millis);
}
int usbi_get_tid(void) {
return GetCurrentThreadId();
}

View File

@ -0,0 +1,87 @@
/*
* libusb synchronization on Microsoft Windows
*
* Copyright © 2010 Michael Plante <michael.plante@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef LIBUSB_THREADS_WINDOWS_H
#define LIBUSB_THREADS_WINDOWS_H
#define usbi_mutex_static_t volatile LONG
#define USBI_MUTEX_INITIALIZER 0
#define usbi_mutex_t HANDLE
struct usbi_cond_perthread {
struct list_head list;
DWORD tid;
HANDLE event;
};
struct usbi_cond_t_ {
// Every time a thread touches the CV, it winds up in one of these lists.
// It stays there until the CV is destroyed, even if the thread
// terminates.
struct list_head waiters;
struct list_head not_waiting;
};
typedef struct usbi_cond_t_ usbi_cond_t;
// We *were* getting timespec from pthread.h:
#if (!defined(HAVE_STRUCT_TIMESPEC) && !defined(_TIMESPEC_DEFINED))
#define HAVE_STRUCT_TIMESPEC 1
#define _TIMESPEC_DEFINED 1
struct timespec {
long tv_sec;
long tv_nsec;
};
#endif /* HAVE_STRUCT_TIMESPEC | _TIMESPEC_DEFINED */
// We *were* getting ETIMEDOUT from pthread.h:
#ifndef ETIMEDOUT
# define ETIMEDOUT 10060 /* This is the value in winsock.h. */
#endif
#define usbi_mutexattr_t void
#define usbi_condattr_t void
// all Windows mutexes are recursive
#define usbi_mutex_init_recursive(mutex, attr) usbi_mutex_init((mutex), (attr))
int usbi_mutex_static_lock(usbi_mutex_static_t *mutex);
int usbi_mutex_static_unlock(usbi_mutex_static_t *mutex);
int usbi_mutex_init(usbi_mutex_t *mutex,
const usbi_mutexattr_t *attr);
int usbi_mutex_lock(usbi_mutex_t *mutex);
int usbi_mutex_unlock(usbi_mutex_t *mutex);
int usbi_mutex_trylock(usbi_mutex_t *mutex);
int usbi_mutex_destroy(usbi_mutex_t *mutex);
int usbi_cond_init(usbi_cond_t *cond,
const usbi_condattr_t *attr);
int usbi_cond_destroy(usbi_cond_t *cond);
int usbi_cond_wait(usbi_cond_t *cond, usbi_mutex_t *mutex);
int usbi_cond_timedwait(usbi_cond_t *cond,
usbi_mutex_t *mutex,
const struct timespec *abstime);
int usbi_cond_broadcast(usbi_cond_t *cond);
int usbi_cond_signal(usbi_cond_t *cond);
int usbi_get_tid(void);
#endif /* LIBUSB_THREADS_WINDOWS_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,131 @@
/*
* Windows CE backend for libusb 1.0
* Copyright © 2011-2013 RealVNC Ltd.
* Portions taken from Windows backend, which is
* Copyright © 2009-2010 Pete Batard <pbatard@gmail.com>
* With contributions from Michael Plante, Orin Eman et al.
* Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
* Major code testing contribution by Xiaofan Chen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include "windows_common.h"
#include <windows.h>
#include "poll_windows.h"
#define MAX_DEVICE_COUNT 256
// This is a modified dump of the types in the ceusbkwrapper.h library header
// with functions transformed into extern pointers.
//
// This backend dynamically loads ceusbkwrapper.dll and doesn't include
// ceusbkwrapper.h directly to simplify the build process. The kernel
// side wrapper driver is built using the platform image build tools,
// which makes it difficult to reference directly from the libusb build
// system.
struct UKW_DEVICE_PRIV;
typedef struct UKW_DEVICE_PRIV *UKW_DEVICE;
typedef UKW_DEVICE *PUKW_DEVICE, *LPUKW_DEVICE;
typedef struct {
UINT8 bLength;
UINT8 bDescriptorType;
UINT16 bcdUSB;
UINT8 bDeviceClass;
UINT8 bDeviceSubClass;
UINT8 bDeviceProtocol;
UINT8 bMaxPacketSize0;
UINT16 idVendor;
UINT16 idProduct;
UINT16 bcdDevice;
UINT8 iManufacturer;
UINT8 iProduct;
UINT8 iSerialNumber;
UINT8 bNumConfigurations;
} UKW_DEVICE_DESCRIPTOR, *PUKW_DEVICE_DESCRIPTOR, *LPUKW_DEVICE_DESCRIPTOR;
typedef struct {
UINT8 bmRequestType;
UINT8 bRequest;
UINT16 wValue;
UINT16 wIndex;
UINT16 wLength;
} UKW_CONTROL_HEADER, *PUKW_CONTROL_HEADER, *LPUKW_CONTROL_HEADER;
// Collection of flags which can be used when issuing transfer requests
/* Indicates that the transfer direction is 'in' */
#define UKW_TF_IN_TRANSFER 0x00000001
/* Indicates that the transfer direction is 'out' */
#define UKW_TF_OUT_TRANSFER 0x00000000
/* Specifies that the transfer should complete as soon as possible,
* even if no OVERLAPPED structure has been provided. */
#define UKW_TF_NO_WAIT 0x00000100
/* Indicates that transfers shorter than the buffer are ok */
#define UKW_TF_SHORT_TRANSFER_OK 0x00000200
#define UKW_TF_SEND_TO_DEVICE 0x00010000
#define UKW_TF_SEND_TO_INTERFACE 0x00020000
#define UKW_TF_SEND_TO_ENDPOINT 0x00040000
/* Don't block when waiting for memory allocations */
#define UKW_TF_DONT_BLOCK_FOR_MEM 0x00080000
/* Value to use when dealing with configuration values, such as UkwGetConfigDescriptor,
* to specify the currently active configuration for the device. */
#define UKW_ACTIVE_CONFIGURATION -1
DLL_DECLARE(WINAPI, HANDLE, UkwOpenDriver, ());
DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceList, (HANDLE, LPUKW_DEVICE, DWORD, LPDWORD));
DLL_DECLARE(WINAPI, void, UkwReleaseDeviceList, (HANDLE, LPUKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceAddress, (UKW_DEVICE, unsigned char*, unsigned char*, unsigned long*));
DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceDescriptor, (UKW_DEVICE, LPUKW_DEVICE_DESCRIPTOR));
DLL_DECLARE(WINAPI, BOOL, UkwGetConfigDescriptor, (UKW_DEVICE, DWORD, LPVOID, DWORD, LPDWORD));
DLL_DECLARE(WINAPI, void, UkwCloseDriver, (HANDLE));
DLL_DECLARE(WINAPI, BOOL, UkwCancelTransfer, (UKW_DEVICE, LPOVERLAPPED, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwIssueControlTransfer, (UKW_DEVICE, DWORD, LPUKW_CONTROL_HEADER, LPVOID, DWORD, LPDWORD, LPOVERLAPPED));
DLL_DECLARE(WINAPI, BOOL, UkwClaimInterface, (UKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwReleaseInterface, (UKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwSetInterfaceAlternateSetting, (UKW_DEVICE, DWORD, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwClearHaltHost, (UKW_DEVICE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, UkwClearHaltDevice, (UKW_DEVICE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, UkwGetConfig, (UKW_DEVICE, PUCHAR));
DLL_DECLARE(WINAPI, BOOL, UkwSetConfig, (UKW_DEVICE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, UkwResetDevice, (UKW_DEVICE));
DLL_DECLARE(WINAPI, BOOL, UkwKernelDriverActive, (UKW_DEVICE, DWORD, PBOOL));
DLL_DECLARE(WINAPI, BOOL, UkwAttachKernelDriver, (UKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwDetachKernelDriver, (UKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwIssueBulkTransfer, (UKW_DEVICE, DWORD, UCHAR, LPVOID, DWORD, LPDWORD, LPOVERLAPPED));
DLL_DECLARE(WINAPI, BOOL, UkwIsPipeHalted, (UKW_DEVICE, UCHAR, LPBOOL));
// Used to determine if an endpoint status really is halted on a failed transfer.
#define STATUS_HALT_FLAG 0x1
struct wince_device_priv {
UKW_DEVICE dev;
UKW_DEVICE_DESCRIPTOR desc;
};
struct wince_device_handle_priv {
// This member isn't used, but only exists to avoid an empty structure
// for private data for the device handle.
int reserved;
};
struct wince_transfer_priv {
struct winfd pollable_fd;
uint8_t interface_number;
};

View File

@ -0,0 +1,108 @@
/*
* Windows backend common header for libusb 1.0
*
* This file brings together header code common between
* the desktop Windows and Windows CE backends.
* Copyright © 2012-2013 RealVNC Ltd.
* Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
* With contributions from Michael Plante, Orin Eman et al.
* Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
* Major code testing contribution by Xiaofan Chen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
// Windows API default is uppercase - ugh!
#if !defined(bool)
#define bool BOOL
#endif
#if !defined(true)
#define true TRUE
#endif
#if !defined(false)
#define false FALSE
#endif
#define safe_free(p) do {if (p != NULL) {free((void*)p); p = NULL;}} while(0)
#define safe_closehandle(h) do {if (h != INVALID_HANDLE_VALUE) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0)
#define safe_min(a, b) min((size_t)(a), (size_t)(b))
#define safe_strcp(dst, dst_max, src, count) do {memcpy(dst, src, safe_min(count, dst_max)); \
((char*)dst)[safe_min(count, dst_max)-1] = 0;} while(0)
#define safe_strcpy(dst, dst_max, src) safe_strcp(dst, dst_max, src, safe_strlen(src)+1)
#define safe_strncat(dst, dst_max, src, count) strncat(dst, src, safe_min(count, dst_max - safe_strlen(dst) - 1))
#define safe_strcat(dst, dst_max, src) safe_strncat(dst, dst_max, src, safe_strlen(src)+1)
#define safe_strcmp(str1, str2) strcmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2))
#define safe_stricmp(str1, str2) _stricmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2))
#define safe_strncmp(str1, str2, count) strncmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2), count)
#define safe_strlen(str) ((str==NULL)?0:strlen(str))
#define safe_sprintf(dst, count, ...) do {_snprintf(dst, count, __VA_ARGS__); (dst)[(count)-1] = 0; } while(0)
#define safe_stprintf _sntprintf
#define safe_tcslen(str) ((str==NULL)?0:_tcslen(str))
#define safe_unref_device(dev) do {if (dev != NULL) {libusb_unref_device(dev); dev = NULL;}} while(0)
#define wchar_to_utf8_ms(wstr, str, strlen) WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, strlen, NULL, NULL)
#ifndef ARRAYSIZE
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
#endif
#define ERR_BUFFER_SIZE 256
#define TIMER_REQUEST_RETRY_MS 100
#define MAX_TIMER_SEMAPHORES 128
/*
* API macros - from libusb-win32 1.x
*/
#define DLL_DECLARE_PREFIXNAME(api, ret, prefixname, name, args) \
typedef ret (api * __dll_##name##_t)args; \
static __dll_##name##_t prefixname = NULL
#ifndef _WIN32_WCE
#define DLL_STRINGIFY(dll) #dll
#define DLL_GET_MODULE_HANDLE(dll) GetModuleHandleA(DLL_STRINGIFY(dll))
#define DLL_LOAD_LIBRARY(dll) LoadLibraryA(DLL_STRINGIFY(dll))
#else
#define DLL_STRINGIFY(dll) L#dll
#define DLL_GET_MODULE_HANDLE(dll) GetModuleHandle(DLL_STRINGIFY(dll))
#define DLL_LOAD_LIBRARY(dll) LoadLibrary(DLL_STRINGIFY(dll))
#endif
#define DLL_LOAD_PREFIXNAME(dll, prefixname, name, ret_on_failure) \
do { \
HMODULE h = DLL_GET_MODULE_HANDLE(dll); \
if (!h) \
h = DLL_LOAD_LIBRARY(dll); \
if (!h) { \
if (ret_on_failure) { return LIBUSB_ERROR_NOT_FOUND; } \
else { break; } \
} \
prefixname = (__dll_##name##_t)GetProcAddress(h, \
DLL_STRINGIFY(name)); \
if (prefixname) break; \
prefixname = (__dll_##name##_t)GetProcAddress(h, \
DLL_STRINGIFY(name) DLL_STRINGIFY(A)); \
if (prefixname) break; \
prefixname = (__dll_##name##_t)GetProcAddress(h, \
DLL_STRINGIFY(name) DLL_STRINGIFY(W)); \
if (prefixname) break; \
if(ret_on_failure) \
return LIBUSB_ERROR_NOT_FOUND; \
} while(0)
#define DLL_DECLARE(api, ret, name, args) DLL_DECLARE_PREFIXNAME(api, ret, name, name, args)
#define DLL_LOAD(dll, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, name, name, ret_on_failure)
#define DLL_DECLARE_PREFIXED(api, ret, prefix, name, args) DLL_DECLARE_PREFIXNAME(api, ret, prefix##name, name, args)
#define DLL_LOAD_PREFIXED(dll, prefix, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, prefix##name, name, ret_on_failure)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,958 @@
/*
* Windows backend for libusb 1.0
* Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
* With contributions from Michael Plante, Orin Eman et al.
* Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
* Major code testing contribution by Xiaofan Chen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include "windows_common.h"
#if defined(_MSC_VER)
// disable /W4 MSVC warnings that are benign
#pragma warning(disable:4127) // conditional expression is constant
#pragma warning(disable:4100) // unreferenced formal parameter
#pragma warning(disable:4214) // bit field types other than int
#pragma warning(disable:4201) // nameless struct/union
#endif
// Missing from MSVC6 setupapi.h
#if !defined(SPDRP_ADDRESS)
#define SPDRP_ADDRESS 28
#endif
#if !defined(SPDRP_INSTALL_STATE)
#define SPDRP_INSTALL_STATE 34
#endif
// Missing from MinGW
#if !defined(FACILITY_SETUPAPI)
#define FACILITY_SETUPAPI 15
#endif
#if defined(__CYGWIN__ )
#define _stricmp stricmp
// cygwin produces a warning unless these prototypes are defined
extern int _snprintf(char *buffer, size_t count, const char *format, ...);
extern char *_strdup(const char *strSource);
// _beginthreadex is MSVCRT => unavailable for cygwin. Fallback to using CreateThread
#define _beginthreadex(a, b, c, d, e, f) CreateThread(a, b, (LPTHREAD_START_ROUTINE)c, d, e, f)
#endif
#define MAX_CTRL_BUFFER_LENGTH 4096
#define MAX_USB_DEVICES 256
#define MAX_USB_STRING_LENGTH 128
#define MAX_HID_REPORT_SIZE 1024
#define MAX_HID_DESCRIPTOR_SIZE 256
#define MAX_GUID_STRING_LENGTH 40
#define MAX_PATH_LENGTH 128
#define MAX_KEY_LENGTH 256
#define LIST_SEPARATOR ';'
#define HTAB_SIZE (32*1021)
// Handle code for HID interface that have been claimed ("dibs")
#define INTERFACE_CLAIMED ((HANDLE)(intptr_t)0xD1B5)
// Additional return code for HID operations that completed synchronously
#define LIBUSB_COMPLETED (LIBUSB_SUCCESS + 1)
// http://msdn.microsoft.com/en-us/library/ff545978.aspx
// http://msdn.microsoft.com/en-us/library/ff545972.aspx
// http://msdn.microsoft.com/en-us/library/ff545982.aspx
#if !defined(GUID_DEVINTERFACE_USB_HOST_CONTROLLER)
const GUID GUID_DEVINTERFACE_USB_HOST_CONTROLLER = { 0x3ABF6F2D, 0x71C4, 0x462A, {0x8A, 0x92, 0x1E, 0x68, 0x61, 0xE6, 0xAF, 0x27} };
#endif
#if !defined(GUID_DEVINTERFACE_USB_DEVICE)
const GUID GUID_DEVINTERFACE_USB_DEVICE = { 0xA5DCBF10, 0x6530, 0x11D2, {0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED} };
#endif
#if !defined(GUID_DEVINTERFACE_USB_HUB)
const GUID GUID_DEVINTERFACE_USB_HUB = { 0xF18A0E88, 0xC30C, 0x11D0, {0x88, 0x15, 0x00, 0xA0, 0xC9, 0x06, 0xBE, 0xD8} };
#endif
#if !defined(GUID_DEVINTERFACE_LIBUSB0_FILTER)
const GUID GUID_DEVINTERFACE_LIBUSB0_FILTER = { 0xF9F3FF14, 0xAE21, 0x48A0, {0x8A, 0x25, 0x80, 0x11, 0xA7, 0xA9, 0x31, 0xD9} };
#endif
/*
* Multiple USB API backend support
*/
#define USB_API_UNSUPPORTED 0
#define USB_API_HUB 1
#define USB_API_COMPOSITE 2
#define USB_API_WINUSBX 3
#define USB_API_HID 4
#define USB_API_MAX 5
// The following is used to indicate if the HID or composite extra props have already been set.
#define USB_API_SET (1<<USB_API_MAX)
// Sub-APIs for WinUSB-like driver APIs (WinUSB, libusbK, libusb-win32 through the libusbK DLL)
// Must have the same values as the KUSB_DRVID enum from libusbk.h
#define SUB_API_NOTSET -1
#define SUB_API_LIBUSBK 0
#define SUB_API_LIBUSB0 1
#define SUB_API_WINUSB 2
#define SUB_API_MAX 3
#define WINUSBX_DRV_NAMES { "libusbK", "libusb0", "WinUSB"}
struct windows_usb_api_backend {
const uint8_t id;
const char* designation;
const char **driver_name_list; // Driver name, without .sys, e.g. "usbccgp"
const uint8_t nb_driver_names;
int (*init)(int sub_api, struct libusb_context *ctx);
int (*exit)(int sub_api);
int (*open)(int sub_api, struct libusb_device_handle *dev_handle);
void (*close)(int sub_api, struct libusb_device_handle *dev_handle);
int (*configure_endpoints)(int sub_api, struct libusb_device_handle *dev_handle, int iface);
int (*claim_interface)(int sub_api, struct libusb_device_handle *dev_handle, int iface);
int (*set_interface_altsetting)(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting);
int (*release_interface)(int sub_api, struct libusb_device_handle *dev_handle, int iface);
int (*clear_halt)(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint);
int (*reset_device)(int sub_api, struct libusb_device_handle *dev_handle);
int (*submit_bulk_transfer)(int sub_api, struct usbi_transfer *itransfer);
int (*submit_iso_transfer)(int sub_api, struct usbi_transfer *itransfer);
int (*submit_control_transfer)(int sub_api, struct usbi_transfer *itransfer);
int (*abort_control)(int sub_api, struct usbi_transfer *itransfer);
int (*abort_transfers)(int sub_api, struct usbi_transfer *itransfer);
int (*copy_transfer_data)(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size);
};
extern const struct windows_usb_api_backend usb_api_backend[USB_API_MAX];
#define PRINT_UNSUPPORTED_API(fname) \
usbi_dbg("unsupported API call for '" \
#fname "' (unrecognized device driver)"); \
return LIBUSB_ERROR_NOT_SUPPORTED;
/*
* private structures definition
* with inline pseudo constructors/destructors
*/
// TODO (v2+): move hid desc to libusb.h?
struct libusb_hid_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdHID;
uint8_t bCountryCode;
uint8_t bNumDescriptors;
uint8_t bClassDescriptorType;
uint16_t wClassDescriptorLength;
};
#define LIBUSB_DT_HID_SIZE 9
#define HID_MAX_CONFIG_DESC_SIZE (LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE \
+ LIBUSB_DT_HID_SIZE + 2 * LIBUSB_DT_ENDPOINT_SIZE)
#define HID_MAX_REPORT_SIZE 1024
#define HID_IN_EP 0x81
#define HID_OUT_EP 0x02
#define LIBUSB_REQ_RECIPIENT(request_type) ((request_type) & 0x1F)
#define LIBUSB_REQ_TYPE(request_type) ((request_type) & (0x03 << 5))
#define LIBUSB_REQ_IN(request_type) ((request_type) & LIBUSB_ENDPOINT_IN)
#define LIBUSB_REQ_OUT(request_type) (!LIBUSB_REQ_IN(request_type))
// The following are used for HID reports IOCTLs
#define HID_CTL_CODE(id) \
CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_NEITHER, FILE_ANY_ACCESS)
#define HID_BUFFER_CTL_CODE(id) \
CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_BUFFERED, FILE_ANY_ACCESS)
#define HID_IN_CTL_CODE(id) \
CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_IN_DIRECT, FILE_ANY_ACCESS)
#define HID_OUT_CTL_CODE(id) \
CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100)
#define IOCTL_HID_GET_INPUT_REPORT HID_OUT_CTL_CODE(104)
#define IOCTL_HID_SET_FEATURE HID_IN_CTL_CODE(100)
#define IOCTL_HID_SET_OUTPUT_REPORT HID_IN_CTL_CODE(101)
enum libusb_hid_request_type {
HID_REQ_GET_REPORT = 0x01,
HID_REQ_GET_IDLE = 0x02,
HID_REQ_GET_PROTOCOL = 0x03,
HID_REQ_SET_REPORT = 0x09,
HID_REQ_SET_IDLE = 0x0A,
HID_REQ_SET_PROTOCOL = 0x0B
};
enum libusb_hid_report_type {
HID_REPORT_TYPE_INPUT = 0x01,
HID_REPORT_TYPE_OUTPUT = 0x02,
HID_REPORT_TYPE_FEATURE = 0x03
};
struct hid_device_priv {
uint16_t vid;
uint16_t pid;
uint8_t config;
uint8_t nb_interfaces;
bool uses_report_ids[3]; // input, ouptput, feature
uint16_t input_report_size;
uint16_t output_report_size;
uint16_t feature_report_size;
WCHAR string[3][MAX_USB_STRING_LENGTH];
uint8_t string_index[3]; // man, prod, ser
};
typedef struct libusb_device_descriptor USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
struct windows_device_priv {
uint8_t depth; // distance to HCD
uint8_t port; // port number on the hub
uint8_t active_config;
struct libusb_device *parent_dev; // access to parent is required for usermode ops
struct windows_usb_api_backend const *apib;
char *path; // device interface path
int sub_api; // for WinUSB-like APIs
struct {
char *path; // each interface needs a device interface path,
struct windows_usb_api_backend const *apib; // an API backend (multiple drivers support),
int sub_api;
int8_t nb_endpoints; // and a set of endpoint addresses (USB_MAXENDPOINTS)
uint8_t *endpoint;
bool restricted_functionality; // indicates if the interface functionality is restricted
// by Windows (eg. HID keyboards or mice cannot do R/W)
} usb_interface[USB_MAXINTERFACES];
struct hid_device_priv *hid;
USB_DEVICE_DESCRIPTOR dev_descriptor;
unsigned char **config_descriptor; // list of pointers to the cached config descriptors
};
static inline struct windows_device_priv *_device_priv(struct libusb_device *dev) {
return (struct windows_device_priv *)dev->os_priv;
}
static inline void windows_device_priv_init(libusb_device* dev) {
struct windows_device_priv* p = _device_priv(dev);
int i;
p->depth = 0;
p->port = 0;
p->parent_dev = NULL;
p->path = NULL;
p->apib = &usb_api_backend[USB_API_UNSUPPORTED];
p->sub_api = SUB_API_NOTSET;
p->hid = NULL;
p->active_config = 0;
p->config_descriptor = NULL;
memset(&(p->dev_descriptor), 0, sizeof(USB_DEVICE_DESCRIPTOR));
for (i=0; i<USB_MAXINTERFACES; i++) {
p->usb_interface[i].path = NULL;
p->usb_interface[i].apib = &usb_api_backend[USB_API_UNSUPPORTED];
p->usb_interface[i].sub_api = SUB_API_NOTSET;
p->usb_interface[i].nb_endpoints = 0;
p->usb_interface[i].endpoint = NULL;
p->usb_interface[i].restricted_functionality = false;
}
}
static inline void windows_device_priv_release(libusb_device* dev) {
struct windows_device_priv* p = _device_priv(dev);
int i;
safe_free(p->path);
if ((dev->num_configurations > 0) && (p->config_descriptor != NULL)) {
for (i=0; i < dev->num_configurations; i++)
safe_free(p->config_descriptor[i]);
}
safe_free(p->config_descriptor);
safe_free(p->hid);
for (i=0; i<USB_MAXINTERFACES; i++) {
safe_free(p->usb_interface[i].path);
safe_free(p->usb_interface[i].endpoint);
}
}
struct interface_handle_t {
HANDLE dev_handle; // WinUSB needs an extra handle for the file
HANDLE api_handle; // used by the API to communicate with the device
};
struct windows_device_handle_priv {
int active_interface;
struct interface_handle_t interface_handle[USB_MAXINTERFACES];
int autoclaim_count[USB_MAXINTERFACES]; // For auto-release
};
static inline struct windows_device_handle_priv *_device_handle_priv(
struct libusb_device_handle *handle)
{
return (struct windows_device_handle_priv *) handle->os_priv;
}
// used for async polling functions
struct windows_transfer_priv {
struct winfd pollable_fd;
uint8_t interface_number;
uint8_t *hid_buffer; // 1 byte extended data buffer, required for HID
uint8_t *hid_dest; // transfer buffer destination, required for HID
size_t hid_expected_size;
};
// used to match a device driver (including filter drivers) against a supported API
struct driver_lookup {
char list[MAX_KEY_LENGTH+1];// REG_MULTI_SZ list of services (driver) names
const DWORD reg_prop; // SPDRP registry key to use to retreive list
const char* designation; // internal designation (for debug output)
};
/* OLE32 dependency */
DLL_DECLARE_PREFIXED(WINAPI, HRESULT, p, CLSIDFromString, (LPCOLESTR, LPCLSID));
/* This call is only available from XP SP2 */
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, IsWow64Process, (HANDLE, PBOOL));
/* SetupAPI dependencies */
DLL_DECLARE_PREFIXED(WINAPI, HDEVINFO, p, SetupDiGetClassDevsA, (const GUID*, PCSTR, HWND, DWORD));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInfo, (HDEVINFO, DWORD, PSP_DEVINFO_DATA));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInterfaces, (HDEVINFO, PSP_DEVINFO_DATA,
const GUID*, DWORD, PSP_DEVICE_INTERFACE_DATA));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceInterfaceDetailA, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA,
PSP_DEVICE_INTERFACE_DETAIL_DATA_A, DWORD, PDWORD, PSP_DEVINFO_DATA));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiDestroyDeviceInfoList, (HDEVINFO));
DLL_DECLARE_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDevRegKey, (HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM));
DLL_DECLARE_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceRegistryPropertyA, (HDEVINFO,
PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD));
DLL_DECLARE_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDeviceInterfaceRegKey, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA, DWORD, DWORD));
DLL_DECLARE_PREFIXED(WINAPI, LONG, p, RegQueryValueExW, (HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD));
DLL_DECLARE_PREFIXED(WINAPI, LONG, p, RegCloseKey, (HKEY));
/*
* Windows DDK API definitions. Most of it copied from MinGW's includes
*/
typedef DWORD DEVNODE, DEVINST;
typedef DEVNODE *PDEVNODE, *PDEVINST;
typedef DWORD RETURN_TYPE;
typedef RETURN_TYPE CONFIGRET;
#define CR_SUCCESS 0x00000000
#define CR_NO_SUCH_DEVNODE 0x0000000D
#define USB_DEVICE_DESCRIPTOR_TYPE LIBUSB_DT_DEVICE
#define USB_CONFIGURATION_DESCRIPTOR_TYPE LIBUSB_DT_CONFIG
#define USB_STRING_DESCRIPTOR_TYPE LIBUSB_DT_STRING
#define USB_INTERFACE_DESCRIPTOR_TYPE LIBUSB_DT_INTERFACE
#define USB_ENDPOINT_DESCRIPTOR_TYPE LIBUSB_DT_ENDPOINT
#define USB_REQUEST_GET_STATUS LIBUSB_REQUEST_GET_STATUS
#define USB_REQUEST_CLEAR_FEATURE LIBUSB_REQUEST_CLEAR_FEATURE
#define USB_REQUEST_SET_FEATURE LIBUSB_REQUEST_SET_FEATURE
#define USB_REQUEST_SET_ADDRESS LIBUSB_REQUEST_SET_ADDRESS
#define USB_REQUEST_GET_DESCRIPTOR LIBUSB_REQUEST_GET_DESCRIPTOR
#define USB_REQUEST_SET_DESCRIPTOR LIBUSB_REQUEST_SET_DESCRIPTOR
#define USB_REQUEST_GET_CONFIGURATION LIBUSB_REQUEST_GET_CONFIGURATION
#define USB_REQUEST_SET_CONFIGURATION LIBUSB_REQUEST_SET_CONFIGURATION
#define USB_REQUEST_GET_INTERFACE LIBUSB_REQUEST_GET_INTERFACE
#define USB_REQUEST_SET_INTERFACE LIBUSB_REQUEST_SET_INTERFACE
#define USB_REQUEST_SYNC_FRAME LIBUSB_REQUEST_SYNCH_FRAME
#define USB_GET_NODE_INFORMATION 258
#define USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION 260
#define USB_GET_NODE_CONNECTION_NAME 261
#define USB_GET_HUB_CAPABILITIES 271
#if !defined(USB_GET_NODE_CONNECTION_INFORMATION_EX)
#define USB_GET_NODE_CONNECTION_INFORMATION_EX 274
#endif
#if !defined(USB_GET_HUB_CAPABILITIES_EX)
#define USB_GET_HUB_CAPABILITIES_EX 276
#endif
#if !defined(USB_GET_NODE_CONNECTION_INFORMATION_EX_V2)
#define USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 279
#endif
#ifndef METHOD_BUFFERED
#define METHOD_BUFFERED 0
#endif
#ifndef FILE_ANY_ACCESS
#define FILE_ANY_ACCESS 0x00000000
#endif
#ifndef FILE_DEVICE_UNKNOWN
#define FILE_DEVICE_UNKNOWN 0x00000022
#endif
#ifndef FILE_DEVICE_USB
#define FILE_DEVICE_USB FILE_DEVICE_UNKNOWN
#endif
#ifndef CTL_CODE
#define CTL_CODE(DeviceType, Function, Method, Access)( \
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
#endif
typedef enum USB_CONNECTION_STATUS {
NoDeviceConnected,
DeviceConnected,
DeviceFailedEnumeration,
DeviceGeneralFailure,
DeviceCausedOvercurrent,
DeviceNotEnoughPower,
DeviceNotEnoughBandwidth,
DeviceHubNestedTooDeeply,
DeviceInLegacyHub
} USB_CONNECTION_STATUS, *PUSB_CONNECTION_STATUS;
typedef enum USB_HUB_NODE {
UsbHub,
UsbMIParent
} USB_HUB_NODE;
/* Cfgmgr32.dll interface */
DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Parent, (PDEVINST, DEVINST, ULONG));
DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Child, (PDEVINST, DEVINST, ULONG));
DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Sibling, (PDEVINST, DEVINST, ULONG));
DLL_DECLARE(WINAPI, CONFIGRET, CM_Get_Device_IDA, (DEVINST, PCHAR, ULONG, ULONG));
#define IOCTL_USB_GET_HUB_CAPABILITIES_EX \
CTL_CODE( FILE_DEVICE_USB, USB_GET_HUB_CAPABILITIES_EX, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_HUB_CAPABILITIES \
CTL_CODE(FILE_DEVICE_USB, USB_GET_HUB_CAPABILITIES, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION \
CTL_CODE(FILE_DEVICE_USB, USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_ROOT_HUB_NAME \
CTL_CODE(FILE_DEVICE_USB, HCD_GET_ROOT_HUB_NAME, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_NODE_INFORMATION \
CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_INFORMATION, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX \
CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_INFORMATION_EX, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 \
CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_INFORMATION_EX_V2, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES \
CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_ATTRIBUTES, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_NODE_CONNECTION_NAME \
CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_NAME, METHOD_BUFFERED, FILE_ANY_ACCESS)
// Most of the structures below need to be packed
#pragma pack(push, 1)
typedef struct USB_INTERFACE_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;
UCHAR bInterfaceNumber;
UCHAR bAlternateSetting;
UCHAR bNumEndpoints;
UCHAR bInterfaceClass;
UCHAR bInterfaceSubClass;
UCHAR bInterfaceProtocol;
UCHAR iInterface;
} USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR;
typedef struct USB_CONFIGURATION_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;
USHORT wTotalLength;
UCHAR bNumInterfaces;
UCHAR bConfigurationValue;
UCHAR iConfiguration;
UCHAR bmAttributes;
UCHAR MaxPower;
} USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR;
typedef struct USB_CONFIGURATION_DESCRIPTOR_SHORT {
struct {
ULONG ConnectionIndex;
struct {
UCHAR bmRequest;
UCHAR bRequest;
USHORT wValue;
USHORT wIndex;
USHORT wLength;
} SetupPacket;
} req;
USB_CONFIGURATION_DESCRIPTOR data;
} USB_CONFIGURATION_DESCRIPTOR_SHORT;
typedef struct USB_ENDPOINT_DESCRIPTOR {
UCHAR bLength;
UCHAR bDescriptorType;
UCHAR bEndpointAddress;
UCHAR bmAttributes;
USHORT wMaxPacketSize;
UCHAR bInterval;
} USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR;
typedef struct USB_DESCRIPTOR_REQUEST {
ULONG ConnectionIndex;
struct {
UCHAR bmRequest;
UCHAR bRequest;
USHORT wValue;
USHORT wIndex;
USHORT wLength;
} SetupPacket;
// UCHAR Data[0];
} USB_DESCRIPTOR_REQUEST, *PUSB_DESCRIPTOR_REQUEST;
typedef struct USB_HUB_DESCRIPTOR {
UCHAR bDescriptorLength;
UCHAR bDescriptorType;
UCHAR bNumberOfPorts;
USHORT wHubCharacteristics;
UCHAR bPowerOnToPowerGood;
UCHAR bHubControlCurrent;
UCHAR bRemoveAndPowerMask[64];
} USB_HUB_DESCRIPTOR, *PUSB_HUB_DESCRIPTOR;
typedef struct USB_ROOT_HUB_NAME {
ULONG ActualLength;
WCHAR RootHubName[1];
} USB_ROOT_HUB_NAME, *PUSB_ROOT_HUB_NAME;
typedef struct USB_ROOT_HUB_NAME_FIXED {
ULONG ActualLength;
WCHAR RootHubName[MAX_PATH_LENGTH];
} USB_ROOT_HUB_NAME_FIXED;
typedef struct USB_NODE_CONNECTION_NAME {
ULONG ConnectionIndex;
ULONG ActualLength;
WCHAR NodeName[1];
} USB_NODE_CONNECTION_NAME, *PUSB_NODE_CONNECTION_NAME;
typedef struct USB_NODE_CONNECTION_NAME_FIXED {
ULONG ConnectionIndex;
ULONG ActualLength;
WCHAR NodeName[MAX_PATH_LENGTH];
} USB_NODE_CONNECTION_NAME_FIXED;
typedef struct USB_HUB_NAME_FIXED {
union {
USB_ROOT_HUB_NAME_FIXED root;
USB_NODE_CONNECTION_NAME_FIXED node;
} u;
} USB_HUB_NAME_FIXED;
typedef struct USB_HUB_INFORMATION {
USB_HUB_DESCRIPTOR HubDescriptor;
BOOLEAN HubIsBusPowered;
} USB_HUB_INFORMATION, *PUSB_HUB_INFORMATION;
typedef struct USB_MI_PARENT_INFORMATION {
ULONG NumberOfInterfaces;
} USB_MI_PARENT_INFORMATION, *PUSB_MI_PARENT_INFORMATION;
typedef struct USB_NODE_INFORMATION {
USB_HUB_NODE NodeType;
union {
USB_HUB_INFORMATION HubInformation;
USB_MI_PARENT_INFORMATION MiParentInformation;
} u;
} USB_NODE_INFORMATION, *PUSB_NODE_INFORMATION;
typedef struct USB_PIPE_INFO {
USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
ULONG ScheduleOffset;
} USB_PIPE_INFO, *PUSB_PIPE_INFO;
typedef struct USB_NODE_CONNECTION_INFORMATION_EX {
ULONG ConnectionIndex;
USB_DEVICE_DESCRIPTOR DeviceDescriptor;
UCHAR CurrentConfigurationValue;
UCHAR Speed;
BOOLEAN DeviceIsHub;
USHORT DeviceAddress;
ULONG NumberOfOpenPipes;
USB_CONNECTION_STATUS ConnectionStatus;
// USB_PIPE_INFO PipeList[0];
} USB_NODE_CONNECTION_INFORMATION_EX, *PUSB_NODE_CONNECTION_INFORMATION_EX;
typedef union _USB_PROTOCOLS {
ULONG ul;
struct {
ULONG Usb110:1;
ULONG Usb200:1;
ULONG Usb300:1;
ULONG ReservedMBZ:29;
};
} USB_PROTOCOLS, *PUSB_PROTOCOLS;
typedef union _USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS {
ULONG ul;
struct {
ULONG DeviceIsOperatingAtSuperSpeedOrHigher:1;
ULONG DeviceIsSuperSpeedCapableOrHigher:1;
ULONG ReservedMBZ:30;
};
} USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS, *PUSB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS;
typedef struct _USB_NODE_CONNECTION_INFORMATION_EX_V2 {
ULONG ConnectionIndex;
ULONG Length;
USB_PROTOCOLS SupportedUsbProtocols;
USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS Flags;
} USB_NODE_CONNECTION_INFORMATION_EX_V2, *PUSB_NODE_CONNECTION_INFORMATION_EX_V2;
typedef struct USB_HUB_CAP_FLAGS {
ULONG HubIsHighSpeedCapable:1;
ULONG HubIsHighSpeed:1;
ULONG HubIsMultiTtCapable:1;
ULONG HubIsMultiTt:1;
ULONG HubIsRoot:1;
ULONG HubIsArmedWakeOnConnect:1;
ULONG ReservedMBZ:26;
} USB_HUB_CAP_FLAGS, *PUSB_HUB_CAP_FLAGS;
typedef struct USB_HUB_CAPABILITIES {
ULONG HubIs2xCapable : 1;
} USB_HUB_CAPABILITIES, *PUSB_HUB_CAPABILITIES;
typedef struct USB_HUB_CAPABILITIES_EX {
USB_HUB_CAP_FLAGS CapabilityFlags;
} USB_HUB_CAPABILITIES_EX, *PUSB_HUB_CAPABILITIES_EX;
#pragma pack(pop)
/* winusb.dll interface */
#define SHORT_PACKET_TERMINATE 0x01
#define AUTO_CLEAR_STALL 0x02
#define PIPE_TRANSFER_TIMEOUT 0x03
#define IGNORE_SHORT_PACKETS 0x04
#define ALLOW_PARTIAL_READS 0x05
#define AUTO_FLUSH 0x06
#define RAW_IO 0x07
#define MAXIMUM_TRANSFER_SIZE 0x08
#define AUTO_SUSPEND 0x81
#define SUSPEND_DELAY 0x83
#define DEVICE_SPEED 0x01
#define LowSpeed 0x01
#define FullSpeed 0x02
#define HighSpeed 0x03
typedef enum USBD_PIPE_TYPE {
UsbdPipeTypeControl,
UsbdPipeTypeIsochronous,
UsbdPipeTypeBulk,
UsbdPipeTypeInterrupt
} USBD_PIPE_TYPE;
typedef struct {
USBD_PIPE_TYPE PipeType;
UCHAR PipeId;
USHORT MaximumPacketSize;
UCHAR Interval;
} WINUSB_PIPE_INFORMATION, *PWINUSB_PIPE_INFORMATION;
#pragma pack(1)
typedef struct {
UCHAR request_type;
UCHAR request;
USHORT value;
USHORT index;
USHORT length;
} WINUSB_SETUP_PACKET, *PWINUSB_SETUP_PACKET;
#pragma pack()
typedef void *WINUSB_INTERFACE_HANDLE, *PWINUSB_INTERFACE_HANDLE;
typedef BOOL (WINAPI *WinUsb_AbortPipe_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID
);
typedef BOOL (WINAPI *WinUsb_ControlTransfer_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
WINUSB_SETUP_PACKET SetupPacket,
PUCHAR Buffer,
ULONG BufferLength,
PULONG LengthTransferred,
LPOVERLAPPED Overlapped
);
typedef BOOL (WINAPI *WinUsb_FlushPipe_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID
);
typedef BOOL (WINAPI *WinUsb_Free_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle
);
typedef BOOL (WINAPI *WinUsb_GetAssociatedInterface_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR AssociatedInterfaceIndex,
PWINUSB_INTERFACE_HANDLE AssociatedInterfaceHandle
);
typedef BOOL (WINAPI *WinUsb_GetCurrentAlternateSetting_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
PUCHAR AlternateSetting
);
typedef BOOL (WINAPI *WinUsb_GetDescriptor_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR DescriptorType,
UCHAR Index,
USHORT LanguageID,
PUCHAR Buffer,
ULONG BufferLength,
PULONG LengthTransferred
);
typedef BOOL (WINAPI *WinUsb_GetOverlappedResult_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
LPOVERLAPPED lpOverlapped,
LPDWORD lpNumberOfBytesTransferred,
BOOL bWait
);
typedef BOOL (WINAPI *WinUsb_GetPipePolicy_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID,
ULONG PolicyType,
PULONG ValueLength,
PVOID Value
);
typedef BOOL (WINAPI *WinUsb_GetPowerPolicy_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
ULONG PolicyType,
PULONG ValueLength,
PVOID Value
);
typedef BOOL (WINAPI *WinUsb_Initialize_t)(
HANDLE DeviceHandle,
PWINUSB_INTERFACE_HANDLE InterfaceHandle
);
typedef BOOL (WINAPI *WinUsb_QueryDeviceInformation_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
ULONG InformationType,
PULONG BufferLength,
PVOID Buffer
);
typedef BOOL (WINAPI *WinUsb_QueryInterfaceSettings_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR AlternateSettingNumber,
PUSB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor
);
typedef BOOL (WINAPI *WinUsb_QueryPipe_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR AlternateInterfaceNumber,
UCHAR PipeIndex,
PWINUSB_PIPE_INFORMATION PipeInformation
);
typedef BOOL (WINAPI *WinUsb_ReadPipe_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID,
PUCHAR Buffer,
ULONG BufferLength,
PULONG LengthTransferred,
LPOVERLAPPED Overlapped
);
typedef BOOL (WINAPI *WinUsb_ResetPipe_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID
);
typedef BOOL (WINAPI *WinUsb_SetCurrentAlternateSetting_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR AlternateSetting
);
typedef BOOL (WINAPI *WinUsb_SetPipePolicy_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID,
ULONG PolicyType,
ULONG ValueLength,
PVOID Value
);
typedef BOOL (WINAPI *WinUsb_SetPowerPolicy_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
ULONG PolicyType,
ULONG ValueLength,
PVOID Value
);
typedef BOOL (WINAPI *WinUsb_WritePipe_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle,
UCHAR PipeID,
PUCHAR Buffer,
ULONG BufferLength,
PULONG LengthTransferred,
LPOVERLAPPED Overlapped
);
typedef BOOL (WINAPI *WinUsb_ResetDevice_t)(
WINUSB_INTERFACE_HANDLE InterfaceHandle
);
/* /!\ These must match the ones from the official libusbk.h */
typedef enum _KUSB_FNID
{
KUSB_FNID_Init,
KUSB_FNID_Free,
KUSB_FNID_ClaimInterface,
KUSB_FNID_ReleaseInterface,
KUSB_FNID_SetAltInterface,
KUSB_FNID_GetAltInterface,
KUSB_FNID_GetDescriptor,
KUSB_FNID_ControlTransfer,
KUSB_FNID_SetPowerPolicy,
KUSB_FNID_GetPowerPolicy,
KUSB_FNID_SetConfiguration,
KUSB_FNID_GetConfiguration,
KUSB_FNID_ResetDevice,
KUSB_FNID_Initialize,
KUSB_FNID_SelectInterface,
KUSB_FNID_GetAssociatedInterface,
KUSB_FNID_Clone,
KUSB_FNID_QueryInterfaceSettings,
KUSB_FNID_QueryDeviceInformation,
KUSB_FNID_SetCurrentAlternateSetting,
KUSB_FNID_GetCurrentAlternateSetting,
KUSB_FNID_QueryPipe,
KUSB_FNID_SetPipePolicy,
KUSB_FNID_GetPipePolicy,
KUSB_FNID_ReadPipe,
KUSB_FNID_WritePipe,
KUSB_FNID_ResetPipe,
KUSB_FNID_AbortPipe,
KUSB_FNID_FlushPipe,
KUSB_FNID_IsoReadPipe,
KUSB_FNID_IsoWritePipe,
KUSB_FNID_GetCurrentFrameNumber,
KUSB_FNID_GetOverlappedResult,
KUSB_FNID_GetProperty,
KUSB_FNID_COUNT,
} KUSB_FNID;
typedef struct _KLIB_VERSION {
INT Major;
INT Minor;
INT Micro;
INT Nano;
} KLIB_VERSION;
typedef KLIB_VERSION* PKLIB_VERSION;
typedef BOOL (WINAPI *LibK_GetProcAddress_t)(
PVOID* ProcAddress,
ULONG DriverID,
ULONG FunctionID
);
typedef VOID (WINAPI *LibK_GetVersion_t)(
PKLIB_VERSION Version
);
struct winusb_interface {
bool initialized;
WinUsb_AbortPipe_t AbortPipe;
WinUsb_ControlTransfer_t ControlTransfer;
WinUsb_FlushPipe_t FlushPipe;
WinUsb_Free_t Free;
WinUsb_GetAssociatedInterface_t GetAssociatedInterface;
WinUsb_GetCurrentAlternateSetting_t GetCurrentAlternateSetting;
WinUsb_GetDescriptor_t GetDescriptor;
WinUsb_GetOverlappedResult_t GetOverlappedResult;
WinUsb_GetPipePolicy_t GetPipePolicy;
WinUsb_GetPowerPolicy_t GetPowerPolicy;
WinUsb_Initialize_t Initialize;
WinUsb_QueryDeviceInformation_t QueryDeviceInformation;
WinUsb_QueryInterfaceSettings_t QueryInterfaceSettings;
WinUsb_QueryPipe_t QueryPipe;
WinUsb_ReadPipe_t ReadPipe;
WinUsb_ResetPipe_t ResetPipe;
WinUsb_SetCurrentAlternateSetting_t SetCurrentAlternateSetting;
WinUsb_SetPipePolicy_t SetPipePolicy;
WinUsb_SetPowerPolicy_t SetPowerPolicy;
WinUsb_WritePipe_t WritePipe;
WinUsb_ResetDevice_t ResetDevice;
};
/* hid.dll interface */
#define HIDP_STATUS_SUCCESS 0x110000
typedef void* PHIDP_PREPARSED_DATA;
#pragma pack(1)
typedef struct {
ULONG Size;
USHORT VendorID;
USHORT ProductID;
USHORT VersionNumber;
} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
#pragma pack()
typedef USHORT USAGE;
typedef struct {
USAGE Usage;
USAGE UsagePage;
USHORT InputReportByteLength;
USHORT OutputReportByteLength;
USHORT FeatureReportByteLength;
USHORT Reserved[17];
USHORT NumberLinkCollectionNodes;
USHORT NumberInputButtonCaps;
USHORT NumberInputValueCaps;
USHORT NumberInputDataIndices;
USHORT NumberOutputButtonCaps;
USHORT NumberOutputValueCaps;
USHORT NumberOutputDataIndices;
USHORT NumberFeatureButtonCaps;
USHORT NumberFeatureValueCaps;
USHORT NumberFeatureDataIndices;
} HIDP_CAPS, *PHIDP_CAPS;
typedef enum _HIDP_REPORT_TYPE {
HidP_Input,
HidP_Output,
HidP_Feature
} HIDP_REPORT_TYPE;
typedef struct _HIDP_VALUE_CAPS {
USAGE UsagePage;
UCHAR ReportID;
BOOLEAN IsAlias;
USHORT BitField;
USHORT LinkCollection;
USAGE LinkUsage;
USAGE LinkUsagePage;
BOOLEAN IsRange;
BOOLEAN IsStringRange;
BOOLEAN IsDesignatorRange;
BOOLEAN IsAbsolute;
BOOLEAN HasNull;
UCHAR Reserved;
USHORT BitSize;
USHORT ReportCount;
USHORT Reserved2[5];
ULONG UnitsExp;
ULONG Units;
LONG LogicalMin, LogicalMax;
LONG PhysicalMin, PhysicalMax;
union {
struct {
USAGE UsageMin, UsageMax;
USHORT StringMin, StringMax;
USHORT DesignatorMin, DesignatorMax;
USHORT DataIndexMin, DataIndexMax;
} Range;
struct {
USAGE Usage, Reserved1;
USHORT StringIndex, Reserved2;
USHORT DesignatorIndex, Reserved3;
USHORT DataIndex, Reserved4;
} NotRange;
} u;
} HIDP_VALUE_CAPS, *PHIDP_VALUE_CAPS;
DLL_DECLARE(WINAPI, BOOL, HidD_GetAttributes, (HANDLE, PHIDD_ATTRIBUTES));
DLL_DECLARE(WINAPI, VOID, HidD_GetHidGuid, (LPGUID));
DLL_DECLARE(WINAPI, BOOL, HidD_GetPreparsedData, (HANDLE, PHIDP_PREPARSED_DATA *));
DLL_DECLARE(WINAPI, BOOL, HidD_FreePreparsedData, (PHIDP_PREPARSED_DATA));
DLL_DECLARE(WINAPI, BOOL, HidD_GetManufacturerString, (HANDLE, PVOID, ULONG));
DLL_DECLARE(WINAPI, BOOL, HidD_GetProductString, (HANDLE, PVOID, ULONG));
DLL_DECLARE(WINAPI, BOOL, HidD_GetSerialNumberString, (HANDLE, PVOID, ULONG));
DLL_DECLARE(WINAPI, LONG, HidP_GetCaps, (PHIDP_PREPARSED_DATA, PHIDP_CAPS));
DLL_DECLARE(WINAPI, BOOL, HidD_SetNumInputBuffers, (HANDLE, ULONG));
DLL_DECLARE(WINAPI, BOOL, HidD_SetFeature, (HANDLE, PVOID, ULONG));
DLL_DECLARE(WINAPI, BOOL, HidD_GetFeature, (HANDLE, PVOID, ULONG));
DLL_DECLARE(WINAPI, BOOL, HidD_GetPhysicalDescriptor, (HANDLE, PVOID, ULONG));
DLL_DECLARE(WINAPI, BOOL, HidD_GetInputReport, (HANDLE, PVOID, ULONG));
DLL_DECLARE(WINAPI, BOOL, HidD_SetOutputReport, (HANDLE, PVOID, ULONG));
DLL_DECLARE(WINAPI, BOOL, HidD_FlushQueue, (HANDLE));
DLL_DECLARE(WINAPI, BOOL, HidP_GetValueCaps, (HIDP_REPORT_TYPE, PHIDP_VALUE_CAPS, PULONG, PHIDP_PREPARSED_DATA));

View File

@ -0,0 +1,169 @@
/*
* libusb strerror code
* Copyright © 2013 Hans de Goede <hdegoede@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include "libusb.h"
#include "libusbi.h"
#if defined(_MSC_VER)
#define strncasecmp _strnicmp
#endif
static size_t usbi_locale = 0;
/** \ingroup misc
* How to add a new \ref libusb_strerror() translation:
* <ol>
* <li> Download the latest \c strerror.c from:<br>
* https://raw.github.com/libusb/libusb/master/libusb/sterror.c </li>
* <li> Open the file in an UTF-8 capable editor </li>
* <li> Add the 2 letter <a href="http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes">ISO 639-1</a>
* code for your locale at the end of \c usbi_locale_supported[]<br>
* Eg. for Chinese, you would add "zh" so that:
* \code... usbi_locale_supported[] = { "en", "nl", "fr" };\endcode
* becomes:
* \code... usbi_locale_supported[] = { "en", "nl", "fr", "zh" };\endcode </li>
* <li> Copy the <tt>{ / * English (en) * / ... }</tt> section and add it at the end of \c usbi_localized_errors<br>
* Eg. for Chinese, the last section of \c usbi_localized_errors could look like:
* \code
* }, { / * Chinese (zh) * /
* "Success",
* ...
* "Other error",
* }
* };\endcode </li>
* <li> Translate each of the English messages from the section you copied into your language </li>
* <li> Save the file (in UTF-8 format) and send it to \c libusb-devel\@lists.sourceforge.net </li>
* </ol>
*/
static const char* usbi_locale_supported[] = { "en", "ru" };
static const char* usbi_localized_errors[ARRAYSIZE(usbi_locale_supported)][LIBUSB_ERROR_COUNT] = {
{ /* English (en) */
"Success",
"Input/Output Error",
"Invalid parameter",
"Access denied (insufficient permissions)",
"No such device (it may have been disconnected)",
"Entity not found",
"Resource busy",
"Operation timed out",
"Overflow",
"Pipe error",
"System call interrupted (perhaps due to signal)",
"Insufficient memory",
"Operation not supported or unimplemented on this platform",
"Other error",
}, { /* Russian (ru) */
"Успех",
"Ошибка ввода/вывода",
"Неверный параметр",
"Доступ запрещён (не хватает прав)",
"Устройство отсутствует (возможно, оно было отсоединено)",
"Элемент не найден",
"Ресурс занят",
"Истекло время ожидания операции",
"Переполнение",
"Ошибка канала",
"Системный вызов прерван (возможно, сигналом)",
"Память исчерпана",
"Операция не поддерживается данной платформой",
"Неизвестная ошибка"
}
};
/** \ingroup misc
* Set the language, and only the language, not the encoding! used for
* translatable libusb messages.
*
* This takes a locale string in the default setlocale format: lang[-region]
* or lang[_country_region][.codeset]. Only the lang part of the string is
* used, and only 2 letter ISO 639-1 codes are accepted for it, such as "de".
* The optional region, country_region or codeset parts are ignored. This
* means that functions which return translatable strings will NOT honor the
* specified encoding.
* All strings returned are encoded as UTF-8 strings.
*
* If libusb_setlocale() is not called, all messages will be in English.
*
* The following functions return translatable strings: libusb_strerror().
* Note that the libusb log messages controlled through libusb_set_debug()
* are not translated, they are always in English.
*
* For POSIX UTF-8 environments if you want libusb to follow the standard
* locale settings, call libusb_setlocale(setlocale(LC_MESSAGES, NULL)),
* after your app has done its locale setup.
*
* \param locale locale-string in the form of lang[_country_region][.codeset]
* or lang[-region], where lang is a 2 letter ISO 639-1 code
* \returns LIBUSB_SUCCESS on success
* \returns LIBUSB_ERROR_INVALID_PARAM if the locale doesn't meet the requirements
* \returns LIBUSB_ERROR_NOT_FOUND if the requested language is not supported
* \returns a LIBUSB_ERROR code on other errors
*/
int API_EXPORTED libusb_setlocale(const char *locale)
{
size_t i;
if ( (locale == NULL) || (strlen(locale) < 2)
|| ((strlen(locale) > 2) && (locale[2] != '-') && (locale[2] != '_') && (locale[2] != '.')) )
return LIBUSB_ERROR_INVALID_PARAM;
for (i=0; i<ARRAYSIZE(usbi_locale_supported); i++) {
if (strncasecmp(usbi_locale_supported[i], locale, 2) == 0)
break;
}
if (i >= ARRAYSIZE(usbi_locale_supported)) {
return LIBUSB_ERROR_NOT_FOUND;
}
usbi_locale = i;
return LIBUSB_SUCCESS;
}
/** \ingroup misc
* Returns a constant string with a short description of the given error code,
* this description is intended for displaying to the end user and will be in
* the language set by libusb_setlocale().
*
* The returned string is encoded in UTF-8.
*
* The messages always start with a capital letter and end without any dot.
* The caller must not free() the returned string.
*
* \param errcode the error code whose description is desired
* \returns a short description of the error code in UTF-8 encoding
*/
DEFAULT_VISIBILITY const char* LIBUSB_CALL libusb_strerror(enum libusb_error errcode)
{
int errcode_index = -errcode;
if ((errcode_index < 0) || (errcode_index >= LIBUSB_ERROR_COUNT)) {
/* "Other Error", which should always be our last message, is returned */
errcode_index = LIBUSB_ERROR_COUNT - 1;
}
return usbi_localized_errors[usbi_locale][errcode_index];
}

View File

@ -0,0 +1,307 @@
/*
* Synchronous I/O functions for libusb
* Copyright © 2007-2008 Daniel Drake <dsd@gentoo.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "libusbi.h"
/**
* @defgroup syncio Synchronous device I/O
*
* This page documents libusb's synchronous (blocking) API for USB device I/O.
* This interface is easy to use but has some limitations. More advanced users
* may wish to consider using the \ref asyncio "asynchronous I/O API" instead.
*/
static void LIBUSB_CALL sync_transfer_cb(struct libusb_transfer *transfer)
{
int *completed = transfer->user_data;
*completed = 1;
usbi_dbg("actual_length=%d", transfer->actual_length);
/* caller interprets result and frees transfer */
}
static void sync_transfer_wait_for_completion(struct libusb_transfer *transfer)
{
int r, *completed = transfer->user_data;
struct libusb_context *ctx = HANDLE_CTX(transfer->dev_handle);
while (!*completed) {
r = libusb_handle_events_completed(ctx, completed);
if (r < 0) {
if (r == LIBUSB_ERROR_INTERRUPTED)
continue;
usbi_err(ctx, "libusb_handle_events failed: %s, cancelling transfer and retrying",
libusb_error_name(r));
libusb_cancel_transfer(transfer);
continue;
}
}
}
/** \ingroup syncio
* Perform a USB control transfer.
*
* The direction of the transfer is inferred from the bmRequestType field of
* the setup packet.
*
* The wValue, wIndex and wLength fields values should be given in host-endian
* byte order.
*
* \param dev_handle a handle for the device to communicate with
* \param bmRequestType the request type field for the setup packet
* \param bRequest the request field for the setup packet
* \param wValue the value field for the setup packet
* \param wIndex the index field for the setup packet
* \param data a suitably-sized data buffer for either input or output
* (depending on direction bits within bmRequestType)
* \param wLength the length field for the setup packet. The data buffer should
* be at least this size.
* \param timeout timeout (in millseconds) that this function should wait
* before giving up due to no response being received. For an unlimited
* timeout, use value 0.
* \returns on success, the number of bytes actually transferred
* \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out
* \returns LIBUSB_ERROR_PIPE if the control request was not supported by the
* device
* \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
* \returns another LIBUSB_ERROR code on other failures
*/
int API_EXPORTED libusb_control_transfer(libusb_device_handle *dev_handle,
uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
unsigned char *data, uint16_t wLength, unsigned int timeout)
{
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
unsigned char *buffer;
int completed = 0;
int r;
if (!transfer)
return LIBUSB_ERROR_NO_MEM;
buffer = (unsigned char*) malloc(LIBUSB_CONTROL_SETUP_SIZE + wLength);
if (!buffer) {
libusb_free_transfer(transfer);
return LIBUSB_ERROR_NO_MEM;
}
libusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue, wIndex,
wLength);
if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT)
memcpy(buffer + LIBUSB_CONTROL_SETUP_SIZE, data, wLength);
libusb_fill_control_transfer(transfer, dev_handle, buffer,
sync_transfer_cb, &completed, timeout);
transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER;
r = libusb_submit_transfer(transfer);
if (r < 0) {
libusb_free_transfer(transfer);
return r;
}
sync_transfer_wait_for_completion(transfer);
if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN)
memcpy(data, libusb_control_transfer_get_data(transfer),
transfer->actual_length);
switch (transfer->status) {
case LIBUSB_TRANSFER_COMPLETED:
r = transfer->actual_length;
break;
case LIBUSB_TRANSFER_TIMED_OUT:
r = LIBUSB_ERROR_TIMEOUT;
break;
case LIBUSB_TRANSFER_STALL:
r = LIBUSB_ERROR_PIPE;
break;
case LIBUSB_TRANSFER_NO_DEVICE:
r = LIBUSB_ERROR_NO_DEVICE;
break;
case LIBUSB_TRANSFER_OVERFLOW:
r = LIBUSB_ERROR_OVERFLOW;
break;
case LIBUSB_TRANSFER_ERROR:
case LIBUSB_TRANSFER_CANCELLED:
r = LIBUSB_ERROR_IO;
break;
default:
usbi_warn(HANDLE_CTX(dev_handle),
"unrecognised status code %d", transfer->status);
r = LIBUSB_ERROR_OTHER;
}
libusb_free_transfer(transfer);
return r;
}
static int do_sync_bulk_transfer(struct libusb_device_handle *dev_handle,
unsigned char endpoint, unsigned char *buffer, int length,
int *transferred, unsigned int timeout, unsigned char type)
{
struct libusb_transfer *transfer = libusb_alloc_transfer(0);
int completed = 0;
int r;
if (!transfer)
return LIBUSB_ERROR_NO_MEM;
libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, length,
sync_transfer_cb, &completed, timeout);
transfer->type = type;
r = libusb_submit_transfer(transfer);
if (r < 0) {
libusb_free_transfer(transfer);
return r;
}
sync_transfer_wait_for_completion(transfer);
*transferred = transfer->actual_length;
switch (transfer->status) {
case LIBUSB_TRANSFER_COMPLETED:
r = 0;
break;
case LIBUSB_TRANSFER_TIMED_OUT:
r = LIBUSB_ERROR_TIMEOUT;
break;
case LIBUSB_TRANSFER_STALL:
r = LIBUSB_ERROR_PIPE;
break;
case LIBUSB_TRANSFER_OVERFLOW:
r = LIBUSB_ERROR_OVERFLOW;
break;
case LIBUSB_TRANSFER_NO_DEVICE:
r = LIBUSB_ERROR_NO_DEVICE;
break;
case LIBUSB_TRANSFER_ERROR:
case LIBUSB_TRANSFER_CANCELLED:
r = LIBUSB_ERROR_IO;
break;
default:
usbi_warn(HANDLE_CTX(dev_handle),
"unrecognised status code %d", transfer->status);
r = LIBUSB_ERROR_OTHER;
}
libusb_free_transfer(transfer);
return r;
}
/** \ingroup syncio
* Perform a USB bulk transfer. The direction of the transfer is inferred from
* the direction bits of the endpoint address.
*
* For bulk reads, the <tt>length</tt> field indicates the maximum length of
* data you are expecting to receive. If less data arrives than expected,
* this function will return that data, so be sure to check the
* <tt>transferred</tt> output parameter.
*
* You should also check the <tt>transferred</tt> parameter for bulk writes.
* Not all of the data may have been written.
*
* Also check <tt>transferred</tt> when dealing with a timeout error code.
* libusb may have to split your transfer into a number of chunks to satisfy
* underlying O/S requirements, meaning that the timeout may expire after
* the first few chunks have completed. libusb is careful not to lose any data
* that may have been transferred; do not assume that timeout conditions
* indicate a complete lack of I/O.
*
* \param dev_handle a handle for the device to communicate with
* \param endpoint the address of a valid endpoint to communicate with
* \param data a suitably-sized data buffer for either input or output
* (depending on endpoint)
* \param length for bulk writes, the number of bytes from data to be sent. for
* bulk reads, the maximum number of bytes to receive into the data buffer.
* \param transferred output location for the number of bytes actually
* transferred.
* \param timeout timeout (in millseconds) that this function should wait
* before giving up due to no response being received. For an unlimited
* timeout, use value 0.
*
* \returns 0 on success (and populates <tt>transferred</tt>)
* \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out (and populates
* <tt>transferred</tt>)
* \returns LIBUSB_ERROR_PIPE if the endpoint halted
* \returns LIBUSB_ERROR_OVERFLOW if the device offered more data, see
* \ref packetoverflow
* \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
* \returns another LIBUSB_ERROR code on other failures
*/
int API_EXPORTED libusb_bulk_transfer(struct libusb_device_handle *dev_handle,
unsigned char endpoint, unsigned char *data, int length, int *transferred,
unsigned int timeout)
{
return do_sync_bulk_transfer(dev_handle, endpoint, data, length,
transferred, timeout, LIBUSB_TRANSFER_TYPE_BULK);
}
/** \ingroup syncio
* Perform a USB interrupt transfer. The direction of the transfer is inferred
* from the direction bits of the endpoint address.
*
* For interrupt reads, the <tt>length</tt> field indicates the maximum length
* of data you are expecting to receive. If less data arrives than expected,
* this function will return that data, so be sure to check the
* <tt>transferred</tt> output parameter.
*
* You should also check the <tt>transferred</tt> parameter for interrupt
* writes. Not all of the data may have been written.
*
* Also check <tt>transferred</tt> when dealing with a timeout error code.
* libusb may have to split your transfer into a number of chunks to satisfy
* underlying O/S requirements, meaning that the timeout may expire after
* the first few chunks have completed. libusb is careful not to lose any data
* that may have been transferred; do not assume that timeout conditions
* indicate a complete lack of I/O.
*
* The default endpoint bInterval value is used as the polling interval.
*
* \param dev_handle a handle for the device to communicate with
* \param endpoint the address of a valid endpoint to communicate with
* \param data a suitably-sized data buffer for either input or output
* (depending on endpoint)
* \param length for bulk writes, the number of bytes from data to be sent. for
* bulk reads, the maximum number of bytes to receive into the data buffer.
* \param transferred output location for the number of bytes actually
* transferred.
* \param timeout timeout (in millseconds) that this function should wait
* before giving up due to no response being received. For an unlimited
* timeout, use value 0.
*
* \returns 0 on success (and populates <tt>transferred</tt>)
* \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out
* \returns LIBUSB_ERROR_PIPE if the endpoint halted
* \returns LIBUSB_ERROR_OVERFLOW if the device offered more data, see
* \ref packetoverflow
* \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
* \returns another LIBUSB_ERROR code on other error
*/
int API_EXPORTED libusb_interrupt_transfer(
struct libusb_device_handle *dev_handle, unsigned char endpoint,
unsigned char *data, int length, int *transferred, unsigned int timeout)
{
return do_sync_bulk_transfer(dev_handle, endpoint, data, length,
transferred, timeout, LIBUSB_TRANSFER_TYPE_INTERRUPT);
}

View File

@ -0,0 +1,18 @@
/* This file is parsed by m4 and windres and RC.EXE so please keep it simple. */
#include "version_nano.h"
#ifndef LIBUSB_MAJOR
#define LIBUSB_MAJOR 1
#endif
#ifndef LIBUSB_MINOR
#define LIBUSB_MINOR 0
#endif
#ifndef LIBUSB_MICRO
#define LIBUSB_MICRO 19
#endif
#ifndef LIBUSB_NANO
#define LIBUSB_NANO 0
#endif
/* LIBUSB_RC is the release candidate suffix. Should normally be empty. */
#ifndef LIBUSB_RC
#define LIBUSB_RC ""
#endif

View File

@ -0,0 +1 @@
#define LIBUSB_NANO 10903

View File

@ -0,0 +1,95 @@
# Файл для включения в проект на CMAKE.
# После включения будут установлены следующие перменные:
# LIBUSB_HEADERS - используемые заголовочные файлы
# LIBUSB_SOURCES - используемые файлы исходных кодов
# LIBUSB_INCLUDE_DIRS - директории включения заголовков
# LIBUSB_LIBS - используемые библиотеки
cmake_policy(PUSH)
cmake_minimum_required(VERSION 2.8.12)
set(LIBUSB_DIR ${CMAKE_CURRENT_LIST_DIR})
set(LIBUSB_DIR_SRC ${LIBUSB_DIR}/libusb-1.0)
set(LIBUSB_INCLUDE_DIRS ${LIBUSB_DIR})
set(LIBUSB_SOURCES
${LIBUSB_DIR_SRC}/core.c
${LIBUSB_DIR_SRC}/descriptor.c
${LIBUSB_DIR_SRC}/hotplug.c
${LIBUSB_DIR_SRC}/io.c
${LIBUSB_DIR_SRC}/strerror.c
${LIBUSB_DIR_SRC}/sync.c
)
set(LIBUSB_HEADERS
${LIBUSB_DIR_SRC}/libusb.h
${LIBUSB_DIR_SRC}/libusbi.h
${LIBUSB_DIR_SRC}/hotplug.h
${LIBUSB_DIR_SRC}/version.h
${LIBUSB_DIR_SRC}/version_nano.h
)
if(WIN32)
include(CheckStructHasMember)
check_struct_has_member("struct timespec" tv_sec time.h HAVE_STRUCT_TIMESPEC LANGUAGE C)
if(HAVE_STRUCT_TIMESPEC)
add_definitions(-DHAVE_STRUCT_TIMESPEC)
endif(HAVE_STRUCT_TIMESPEC)
set(SOURCES ${SOURCES}
${LIBUSB_DIR_SRC}/os/poll_windows.c
${LIBUSB_DIR_SRC}/os/threads_windows.c
${LIBUSB_DIR_SRC}/os/windows_usb.c
)
set(HEADERS ${HEADERS}
${LIBUSB_DIR_SRC}/os/poll_windows.h
${LIBUSB_DIR_SRC}/os/threads_windows.h
${LIBUSB_DIR_SRC}/os/windows_common.h
)
else(WIN32)
message(FATAL_ERROR "unsupported os")
endif(WIN32)
if(MSVC)
set(LIBUSB_INCLUDE_DIRS ${LIBUSB_INCLUDE_DIRS} ${LIBUSB_DIR_SRC}/msvc)
#В зависимости от версии msvc файлы errno.h,stdint.h,inttypes.h могут присутсвовать
#или отсутствовать. При этом файлы из libusb могут конфликтовать с файлами из msvc.
#Поэтому проверяем каждый из этих файлов, и прописываем до него путь в поиске include,
#только в случае, если он не найден
include(CheckIncludeFile)
check_include_file(errno.h HAVE_ERRNO)
if (NOT ${HAVE_ERRNO})
set(LIBUSB_INCLUDE_DIRS ${LIBUSB_INCLUDE_DIRS} ${LIBUSB_DIR_SRC}/errno)
endif (NOT ${HAVE_ERRNO})
check_include_file(stdint.h HAVE_STDINT)
if (NOT ${HAVE_STDINT})
set(LIBUSB_INCLUDE_DIRS ${LIBUSB_INCLUDE_DIRS} ${LIBUSB_DIR_SRC}/stdint)
endif (NOT ${HAVE_STDINT})
check_include_file(inttypes.h HAVE_INTTYPES)
if (NOT ${HAVE_INTTYPES})
set(LIBUSB_INCLUDE_DIRS ${LIBUSB_INCLUDE_DIRS} ${LIBUSB_DIR_SRC}/inttypes)
endif (NOT ${HAVE_INTTYPES})
set(LIBUSB_HEADERS ${LIBUSB_HEADERS}
${LIBUSB_DIR_SRC}/msvc/config.h
${LIBUSB_DIR_SRC}/msvc/missing.h
${LIBUSB_DIR_SRC}/msvc/errno/errno.h
${LIBUSB_DIR_SRC}/msvc/inttypes/inttypes.h
${LIBUSB_DIR_SRC}/msvc/stdint/stdint.h
)
else(MSVC)
message(FATAL_ERROR "unsupported compiler")
endif(MSVC)
cmake_policy(POP)

View File

@ -0,0 +1,294 @@
unit e502api;
interface
uses Windows, SysUtils, x502api;
const
{ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> }
E502_ETH_SVC_EVENT_NONE = 0; // <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
E502_ETH_SVC_EVENT_ADD = 1; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
E502_ETH_SVC_EVENT_REMOVE = 2; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
E502_ETH_SVC_EVENT_CHANGED = 3; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
type st_e502_eth_config_state = record
end;
type t_e502_eth_config_hnd = ^st_e502_eth_config_state;
type t_e502_mac_addr = array[0..X502_MAC_ADDR_SIZE-1] of byte;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD>
type st_e502_eth_svc_browse_context = record
end;
type t_e502_eth_svc_browse_hnd = ^st_e502_eth_svc_browse_context;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
type st_e502_eth_svc_record = record
end;
type t_e502_eth_svc_record_hnd = ^st_e502_eth_svc_record;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> E502, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> USB
function E502_UsbGetSerialList(out serials: array of string; flags: LongWord; out devcnt: LongWord) : LongInt; overload;
function E502_UsbGetSerialList(out serials: array of string; flags: LongWord) : LongInt; overload;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> E502, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> USB, <20><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function E502_OpenUsb(hnd: t_x502_hnd; serial: string): LongInt; stdcall;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> E502 <20><> IP-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_OpenByIpAddr(hnd : t_x502_hnd; ip_addr: LongWord; flags : LongWord; tout: LongWord) : LongInt; stdcall;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> E502
function E502_UsbGetDevRecordsList(out list: array of t_x502_devrec; flags : LongWord; out devcnt: LongWord) : LongInt; overload;
function E502_UsbGetDevRecordsList(out list: array of t_x502_devrec; flags : LongWord) : LongInt; overload;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> IP-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_MakeDevRecordByIpAddr(var devrec: t_x502_devrec; ip_addr: LongWord; flags : LongWord; tout: LongWord) : LongInt; stdcall;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> TCP-<2D><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_EthDevRecordSetCmdPort(var devrec: t_x502_devrec; cmd_port: Word) : LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> TCP-<2D><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_EthDevRecordSetDataPort(var devrec: t_x502_devrec; data_port: Word) : LongInt; stdcall;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_MakeDevRecordByEthSvc(var devrec: t_x502_devrec; svc : t_e502_eth_svc_record_hnd; flags : LongWord; tout: LongWord) : LongInt; stdcall;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> IP-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_GetIpAddr(hnd: t_x502_hnd; out ip_addr : LongWord) : LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function E502_EthConfigCreate() : t_e502_eth_config_hnd; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function E502_EthConfigFree(cfg: t_e502_eth_config_hnd): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_EthConfigRead(hnd: t_x502_hnd; cfg: t_e502_eth_config_hnd): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_EthConfigWrite(hnd: t_x502_hnd; cfg: t_e502_eth_config_hnd; passwd : string): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_EthConfigCopy(src_cfg: t_e502_eth_config_hnd; dst_cfg: t_e502_eth_config_hnd): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ethernet
function E502_EthConfigGetEnabled(cfg: t_e502_eth_config_hnd; out en : LongBool): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ethernet
function E502_EthConfigSetEnabled(cfg: t_e502_eth_config_hnd; en : LongBool): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> IP
function E502_EthConfigGetAutoIPEnabled(cfg: t_e502_eth_config_hnd; out en: LongBool): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> IP
function E502_EthConfigSetAutoIPEnabled(cfg: t_e502_eth_config_hnd; en: LongBool): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MAC-<2D><><EFBFBD><EFBFBD><EFBFBD>
function E502_EthConfigGetUserMACEnabled(cfg: t_e502_eth_config_hnd; out en: LongBool): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MAC-<2D><><EFBFBD><EFBFBD><EFBFBD>
function E502_EthConfigSetUserMACEnabled(cfg: t_e502_eth_config_hnd; en : LongBool): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> IP-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_EthConfigGetIPv4Addr(cfg: t_e502_eth_config_hnd; out ip_addr : LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> IP-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_EthConfigSetIPv4Addr(cfg: t_e502_eth_config_hnd; ip_addr: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_EthConfigGetIPv4Mask(cfg: t_e502_eth_config_hnd; out mask : LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_EthConfigSetIPv4Mask(cfg: t_e502_eth_config_hnd; mask : LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
function E502_EthConfigGetIPv4Gate(cfg: t_e502_eth_config_hnd; out gate: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
function E502_EthConfigSetIPv4Gate(cfg: t_e502_eth_config_hnd; gate: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MAC-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_EthConfigGetUserMac(cfg: t_e502_eth_config_hnd; mac : t_e502_mac_addr): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MAC-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_EthConfigSetUserMac(cfg: t_e502_eth_config_hnd; mac: t_e502_mac_addr): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MAC-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_EthConfigGetFactoryMac(cfg: t_e502_eth_config_hnd; mac : t_e502_mac_addr): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_EthConfigGetInstanceName(cfg: t_e502_eth_config_hnd; out name: string): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_EthConfigSetInstanceName(cfg: t_e502_eth_config_hnd; const name: string): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_EthConfigSetNewPassword(cfg: t_e502_eth_config_hnd; const new_passwd: string): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> E502 <20> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_SwitchToBootloader(hnd: t_x502_hnd): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
function E502_ReloadFPGA(hnd: t_x502_hnd): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Cortex-M4.
function E502_CortexExecCmd(hnd: t_x502_hnd; cmd_code: LongWord; par: LongWord;
const snd_data : array of byte; snd_size : LongWord;
rcv_data : array of byte; rcv_size : LongWord;
tout: LongWord; out recvd_size: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
function E502_EthSvcBrowseStart(out context : t_e502_eth_svc_browse_hnd; flags : LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
function E502_EthSvcBrowseGetEvent(context : t_e502_eth_svc_browse_hnd; out svc: t_e502_eth_svc_record_hnd; out event: LongWord; out flags : LongWord; tout : LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
function E502_EthSvcBrowseStop(context : t_e502_eth_svc_browse_hnd): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_EthSvcRecordFree(svc : t_e502_eth_svc_record_hnd): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_EthSvcRecordGetInstanceName(svc : t_e502_eth_svc_record_hnd; out name: string): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_EthSvcRecordGetDevSerial(svc : t_e502_eth_svc_record_hnd; out serial : string): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> IP <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_EthSvcRecordResolveIPv4Addr(svc : t_e502_eth_svc_record_hnd; out addr :LongWord; tout : LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function E502_EthSvcRecordIsSameInstance(svc1 : t_e502_eth_svc_record_hnd; svc2 : t_e502_eth_svc_record_hnd): LongInt; stdcall;
implementation
function _get_serials( ser_arr: p_x502_serial_array; size:LongWord;
flags:LongWord; out devcnt: LongWord) : LongInt;
stdcall; external 'e502api.dll' name 'E502_UsbGetSerialList';
function _get_dev_records_list(out list; size:LongWord;
flags : LongWord; out devcnt: LongWord) : LongInt;
stdcall; external 'e502api.dll' name 'E502_UsbGetDevRecordsList';
function _open_usb(hnd: t_x502_hnd; serial: PAnsiChar) : LongInt; stdcall; external 'e502api.dll' name 'E502_OpenUsb';
function E502_OpenByIpAddr(hnd : t_x502_hnd; ip_addr: LongWord; flags : LongWord; tout: LongWord) : LongInt; stdcall; external 'e502api.dll';
function E502_MakeDevRecordByIpAddr(var devrec: t_x502_devrec; ip_addr: LongWord; flags : LongWord; tout: LongWord) : LongInt; stdcall; external 'e502api.dll';
function E502_EthDevRecordSetCmdPort(var devrec: t_x502_devrec; cmd_port: Word) : LongInt; stdcall; external 'e502api.dll';
function E502_EthDevRecordSetDataPort(var devrec: t_x502_devrec; data_port: Word) : LongInt; stdcall; external 'e502api.dll';
function E502_MakeDevRecordByEthSvc(var devrec: t_x502_devrec; svc : t_e502_eth_svc_record_hnd; flags : LongWord; tout: LongWord) : LongInt; stdcall; external 'e502api.dll';
function E502_GetIpAddr(hnd: t_x502_hnd; out ip_addr : LongWord) : LongInt; stdcall; external 'e502api.dll';
function E502_EthConfigCreate() : t_e502_eth_config_hnd; stdcall; external 'e502api.dll';
function E502_EthConfigFree(cfg: t_e502_eth_config_hnd): LongInt; stdcall; external 'e502api.dll';
function E502_EthConfigRead(hnd: t_x502_hnd; cfg: t_e502_eth_config_hnd): LongInt; stdcall; external 'e502api.dll';
function E502_EthConfigWrite(hnd: t_x502_hnd; cfg: t_e502_eth_config_hnd; passwd : string): LongInt; stdcall; external 'e502api.dll';
function E502_EthConfigCopy(src_cfg: t_e502_eth_config_hnd; dst_cfg: t_e502_eth_config_hnd): LongInt; stdcall; external 'e502api.dll';
function E502_EthConfigGetEnabled(cfg: t_e502_eth_config_hnd; out en : LongBool): LongInt; stdcall; external 'e502api.dll';
function E502_EthConfigSetEnabled(cfg: t_e502_eth_config_hnd; en : LongBool): LongInt; stdcall; external 'e502api.dll';
function E502_EthConfigGetAutoIPEnabled(cfg: t_e502_eth_config_hnd; out en: LongBool): LongInt; stdcall; external 'e502api.dll';
function E502_EthConfigSetAutoIPEnabled(cfg: t_e502_eth_config_hnd; en: LongBool): LongInt; stdcall; external 'e502api.dll';
function E502_EthConfigGetUserMACEnabled(cfg: t_e502_eth_config_hnd; out en: LongBool): LongInt; stdcall; external 'e502api.dll';
function E502_EthConfigSetUserMACEnabled(cfg: t_e502_eth_config_hnd; en : LongBool): LongInt; stdcall; external 'e502api.dll';
function E502_EthConfigGetIPv4Addr(cfg: t_e502_eth_config_hnd; out ip_addr : LongWord): LongInt; stdcall; external 'e502api.dll';
function E502_EthConfigSetIPv4Addr(cfg: t_e502_eth_config_hnd; ip_addr: LongWord): LongInt; stdcall; external 'e502api.dll';
function E502_EthConfigGetIPv4Mask(cfg: t_e502_eth_config_hnd; out mask : LongWord): LongInt; stdcall; external 'e502api.dll';
function E502_EthConfigSetIPv4Mask(cfg: t_e502_eth_config_hnd; mask : LongWord): LongInt; stdcall; external 'e502api.dll';
function E502_EthConfigGetIPv4Gate(cfg: t_e502_eth_config_hnd; out gate: LongWord): LongInt; stdcall; external 'e502api.dll';
function E502_EthConfigSetIPv4Gate(cfg: t_e502_eth_config_hnd; gate: LongWord): LongInt; stdcall; external 'e502api.dll';
function E502_EthConfigGetUserMac(cfg: t_e502_eth_config_hnd; mac : t_e502_mac_addr): LongInt; stdcall; external 'e502api.dll';
function E502_EthConfigSetUserMac(cfg: t_e502_eth_config_hnd; mac: t_e502_mac_addr): LongInt; stdcall; external 'e502api.dll';
function E502_EthConfigGetFactoryMac(cfg: t_e502_eth_config_hnd; mac : t_e502_mac_addr): LongInt; stdcall; external 'e502api.dll';
function _eth_config_get_instance_name(cfg: t_e502_eth_config_hnd; name: PAnsiChar): LongInt; stdcall; external 'e502api.dll' name 'E502_EthConfigGetInstanceName';
function _eth_config_set_instance_name(cfg: t_e502_eth_config_hnd; name: PAnsiChar): LongInt; stdcall; external 'e502api.dll' name 'E502_EthConfigSetInstanceName';
function _eth_config_set_new_password(cfg: t_e502_eth_config_hnd; new_passwd: PAnsiChar): LongInt; stdcall; external 'e502api.dll' name 'E502_EthConfigSetNewPassword';
function E502_SwitchToBootloader(hnd: t_x502_hnd): LongInt; stdcall; external 'e502api.dll';
function E502_ReloadFPGA(hnd: t_x502_hnd): LongInt; stdcall; external 'e502api.dll';
function _cortex_exec_cmd(hnd: t_x502_hnd; cmd_code: LongWord; par: LongWord;
const snd_data; snd_size : LongWord;
out rcv_data; rcv_size : LongWord;
tout: LongWord; out recvd_size: LongWord): LongInt; stdcall; external 'e502api.dll' name 'E502_CortexExecCmd';
function E502_EthSvcBrowseStart(out context : t_e502_eth_svc_browse_hnd; flags : LongWord): LongInt; stdcall; external 'e502api.dll';
function E502_EthSvcBrowseGetEvent(context : t_e502_eth_svc_browse_hnd; out svc: t_e502_eth_svc_record_hnd; out event: LongWord; out flags : LongWord; tout : LongWord): LongInt; stdcall; external 'e502api.dll';
function E502_EthSvcBrowseStop(context : t_e502_eth_svc_browse_hnd): LongInt; stdcall; external 'e502api.dll';
function E502_EthSvcRecordFree(svc : t_e502_eth_svc_record_hnd): LongInt; stdcall; external 'e502api.dll';
function _eth_svc_record_get_instance_name(svc : t_e502_eth_svc_record_hnd; name: PAnsiChar): LongInt; stdcall; external 'e502api.dll' name 'E502_EthSvcRecordGetInstanceName';
function _eth_svc_record_get_dev_serial(svc : t_e502_eth_svc_record_hnd; serial : PAnsiChar): LongInt; stdcall; external 'e502api.dll' name 'E502_EthSvcRecordGetDevSerial';
function E502_EthSvcRecordResolveIPv4Addr(svc : t_e502_eth_svc_record_hnd; out addr :LongWord; tout : LongWord): LongInt; stdcall; external 'e502api.dll';
function E502_EthSvcRecordIsSameInstance(svc1 : t_e502_eth_svc_record_hnd; svc2 : t_e502_eth_svc_record_hnd): LongInt; stdcall; external 'e502api.dll';
function E502_UsbGetSerialList(out serials: array of string; flags: LongWord; out devcnt: LongWord) : LongInt; overload;
var
ser_arr : p_x502_serial_array;
res, i : LongInt;
begin
if (Length(serials) > 0) then
begin
ser_arr:=GetMemory(Length(serials)*X502_SERIAL_SIZE);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
res := _get_serials(ser_arr, Length(serials), flags, devcnt);
if res >= 0 then
begin
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
for i:=0 to res-1 do
serials[i] := string(ser_arr[i]);
end;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
FreeMemory(ser_arr);
end
else
begin
res:= _get_serials(nil, 0, flags, devcnt);
end;
E502_UsbGetSerialList:=res;
end;
function E502_UsbGetSerialList(out serials: array of string; flags: LongWord) : LongInt; overload;
begin
E502_UsbGetSerialList:= E502_UsbGetSerialList(serials, flags, PCardinal(nil)^);
end;
function E502_UsbGetDevRecordsList(out list: array of t_x502_devrec; flags : LongWord; out devcnt: LongWord) : LongInt; overload;
begin
E502_UsbGetDevRecordsList := _get_dev_records_list(list, Length(list), flags, devcnt);
end;
function E502_UsbGetDevRecordsList(out list: array of t_x502_devrec; flags : LongWord) : LongInt; overload;
begin
E502_UsbGetDevRecordsList:= E502_UsbGetDevRecordsList(list, flags, PCardinal(nil)^);
end;
function E502_OpenUsb(hnd: t_x502_hnd; serial: string) : LongInt;
begin
E502_OpenUsb:=_open_usb(hnd, PAnsiChar(AnsiString(serial)));
end;
function E502_EthConfigGetInstanceName(cfg: t_e502_eth_config_hnd; out name: string): LongInt; stdcall;
var
strptr: PAnsiChar;
res: LongInt;
begin
strptr:=GetMemory(X502_INSTANCE_NAME_SIZE);
res:=_eth_config_get_instance_name(cfg, strptr);
if res = X502_ERR_OK then
name:=string(Utf8Decode(strptr));
FreeMemory(strptr);
E502_EthConfigGetInstanceName:= res;
end;
function E502_EthConfigSetInstanceName(cfg: t_e502_eth_config_hnd; const name: string): LongInt; stdcall;
begin
E502_EthConfigSetInstanceName:=_eth_config_set_instance_name(cfg, PAnsiChar(Utf8Encode(AnsiString(name))));
end;
function E502_EthConfigSetNewPassword(cfg: t_e502_eth_config_hnd; const new_passwd: string): LongInt; stdcall;
begin
E502_EthConfigSetNewPassword:=_eth_config_set_new_password(cfg, PAnsiChar(AnsiString(new_passwd)));
end;
function E502_CortexExecCmd(hnd: t_x502_hnd; cmd_code: LongWord; par: LongWord;
const snd_data : array of byte; snd_size : LongWord;
rcv_data : array of byte; rcv_size : LongWord;
tout: LongWord; out recvd_size: LongWord): LongInt; stdcall;
begin
if (LongWord(Length(snd_data)) < snd_size) or
(LongWord(Length(rcv_data)) < rcv_size) then
E502_CortexExecCmd := X502_ERR_INSUFFICIENT_ARRAY_SIZE
else
E502_CortexExecCmd:=_cortex_exec_cmd(hnd, cmd_code, par, snd_data, snd_size, rcv_data, rcv_size, tout, recvd_size);
end;
function E502_EthSvcRecordGetInstanceName(svc : t_e502_eth_svc_record_hnd; out name: string): LongInt; stdcall;
var
strptr: PAnsiChar;
res: LongInt;
begin
strptr:=GetMemory(X502_INSTANCE_NAME_SIZE);
res:=_eth_svc_record_get_instance_name(svc, strptr);
if res = X502_ERR_OK then
name:=string(Utf8Decode(strptr));
FreeMemory(strptr);
E502_EthSvcRecordGetInstanceName:= res;
end;
function E502_EthSvcRecordGetDevSerial(svc : t_e502_eth_svc_record_hnd; out serial : string): LongInt; stdcall;
var
strptr: PAnsiChar;
res: LongInt;
begin
strptr:=GetMemory(X502_SERIAL_SIZE);
res:=_eth_svc_record_get_dev_serial(svc, strptr);
if res = X502_ERR_OK then
serial:=string(strptr);
FreeMemory(strptr);
E502_EthSvcRecordGetDevSerial:= res;
end;
end.

View File

@ -0,0 +1,48 @@
cmake_minimum_required(VERSION 2.8.12)
project(l502api C)
set(PROJECT_VARNAME_PREFIX L502API)
include(${LTIMER_DIR}/ltimer.cmake)
set(SOURCES
l502api.c
l502api_compat.c
l502api_eeprom.c
l502api_bf.c
${LTIMER_SOURCES}
)
set(SETUP_HEADERS
l502api.h
l502api_compat.h)
set(HEADERS
l502api_private.h
lpcie_ioctls.h
${LTIMER_HEADERS})
set(LIBS
x502api
${LTIMER_LIBS})
set(L502API_COMPILE_DEFINITIONS ${L502API_COMPILE_DEFINITIONS} ${LTIMER_DEFINITIONS})
if(WIN32)
#В Windows используем setupapi для нахождения устройства
set(LIBS ${LIBS} setupapi)
set(SOURCES ${SOURCES} win/l502_spec.c)
elseif(UNIX)
set(SOURCES ${SOURCES} linux/l502_spec.c)
endif(WIN32)
include(${X502_LIBS_CMAKE_FILE})

View File

@ -0,0 +1,212 @@
#ifndef L5XX_REGS_H
#define L5XX_REGS_H
#define L583_BF_ADDR_ENDPROG (0xFFFFFFFCUL)
#define L502_MAX_PAGES_CNT 252
#define L502_BF_SDRAM_SIZE (32UL*1024*1024)
#define L502_BF_MEMADDR_CMD 0xFF800800
#define L502_BF_CMD_READ 0x0001
#define L502_BF_CMD_WRITE 0x0002
#define L502_BF_CMD_HIRQ 0x0004
#define L502_BF_CMD_HDMA_RST 0x0008
/********************* Адреса регистров блока EEPROM *************************/
#define L502_REGS_EEPROM_BLOCK 0x0100
#define L502_REGS_EEPROM_SET_RD_ADDR (L502_REGS_EEPROM_BLOCK + 0)
#define L502_REGS_EEPROM_RD_DWORD (L502_REGS_EEPROM_BLOCK + 1)
#define L502_REGS_EEPROM_RD_STATUS (L502_REGS_EEPROM_BLOCK + 2)
#define L502_REGS_EEPROM_WR_STATUS_EN (L502_REGS_EEPROM_BLOCK + 3)
#define L502_REGS_EEPROM_WR_EN (L502_REGS_EEPROM_BLOCK + 4)
#define L502_REGS_EEPROM_WR_DIS (L502_REGS_EEPROM_BLOCK + 5)
#define L502_REGS_EEPROM_WR_STATUS (L502_REGS_EEPROM_BLOCK + 6)
#define L502_REGS_EEPROM_ERASE_4K (L502_REGS_EEPROM_BLOCK + 7)
#define L502_REGS_EEPROM_ERASE_64K (L502_REGS_EEPROM_BLOCK + 8)
#define L502_REGS_EEPROM_WR_BYTE (L502_REGS_EEPROM_BLOCK + 9)
#define L502_REGS_EEPROM_HARD_WR_STATUS_EN (L502_REGS_EEPROM_BLOCK + 0xF)
#define L502_REGS_HARD_ID (L502_REGS_EEPROM_BLOCK + 0xA)
#define L502_REGS_JEDEC_RD_ID (L502_REGS_EEPROM_BLOCK + 0xB)
/********************* Адреса регистров с отладочной информацией **************/
#define L502_REGS_DBG_BLOCK 0x0140
#define L502_REGS_DBG_EVENTS (L502_REGS_DBG_BLOCK + 0)
#define L502_REGS_DBG_LAST_ABORT_ADDR (L502_REGS_DBG_BLOCK + 8)
#define L502_REGS_DBG_LAST_NACK_ADDR (L502_REGS_DBG_BLOCK + 9)
#define L502_REGS_DBG_LINK_REPLAY_CNT (L502_REGS_DBG_BLOCK + 10)
/********************* Адреса регистров блока IOHARD **************************/
#define L502_REGS_IOHARD_BLOCK 0x0200
//Адрес Control Table
#define L502_REGS_IOHARD_LTABLE (L502_REGS_IOHARD_BLOCK+0)
#define L502_REGS_IOHARD_LTABLE_MAX_SIZE 0x100 // Максимальный размер Control Table
#define L502_REGS_IOHARD_LCH_CNT (L502_REGS_IOHARD_BLOCK+0x100)
#define L502_REGS_IOHARD_ADC_FREQ_DIV (L502_REGS_IOHARD_BLOCK+0x102)
#define L502_REGS_IOHARD_ADC_FRAME_DELAY (L502_REGS_IOHARD_BLOCK+0x104)
#define L502_REGS_IOHARD_DIGIN_FREQ_DIV (L502_REGS_IOHARD_BLOCK+0x106)
#define L502_REGS_IOHARD_IO_MODE (L502_REGS_IOHARD_BLOCK+0x108)
#define L502_REGS_IOHARD_GO_SYNC_IO (L502_REGS_IOHARD_BLOCK+0x10A)
#define L502_REGS_IOHARD_PRELOAD_ADC (L502_REGS_IOHARD_BLOCK+0x10C)
#define L502_REGS_IOHARD_ASYNC_OUT (L502_REGS_IOHARD_BLOCK+0x112)
#define L502_REGS_IOHARD_LED (L502_REGS_IOHARD_BLOCK+0x114)
#define L502_REGS_IOHARD_DIGIN_PULLUP (L502_REGS_IOHARD_BLOCK+0x116)
#define L502_REGS_IOHARD_OUTSWAP_BFCTL (L502_REGS_IOHARD_BLOCK+0x118)
#define L502_REGS_IOHARD_OUTSWAP_ERROR (L502_REGS_IOHARD_BLOCK+0x120)
/********************* Адреса регистров блока IOARITH **************************/
#define L502_REGS_IOARITH_BLOCK 0x0400
#define L502_REGS_IOARITH_B10 L502_REGS_IOARITH_BLOCK
#define L502_REGS_IOARITH_B5 (L502_REGS_IOARITH_BLOCK+0x01)
#define L502_REGS_IOARITH_B2 (L502_REGS_IOARITH_BLOCK+0x02)
#define L502_REGS_IOARITH_B1 (L502_REGS_IOARITH_BLOCK+0x03)
#define L502_REGS_IOARITH_B05 (L502_REGS_IOARITH_BLOCK+0x04)
#define L502_REGS_IOARITH_B02 (L502_REGS_IOARITH_BLOCK+0x05)
#define L502_REGS_IOARITH_K10 (L502_REGS_IOARITH_BLOCK+0x08)
#define L502_REGS_IOARITH_K5 (L502_REGS_IOARITH_BLOCK+0x09)
#define L502_REGS_IOARITH_K2 (L502_REGS_IOARITH_BLOCK+0x0A)
#define L502_REGS_IOARITH_K1 (L502_REGS_IOARITH_BLOCK+0x0B)
#define L502_REGS_IOARITH_K05 (L502_REGS_IOARITH_BLOCK+0x0C)
#define L502_REGS_IOARITH_K02 (L502_REGS_IOARITH_BLOCK+0x0D)
#define L502_REGS_IOARITH_ADC_FREQ_DIV (L502_REGS_IOARITH_BLOCK+0x12)
#define L502_REGS_IOARITH_IN_STREAM_ENABLE (L502_REGS_IOARITH_BLOCK+0x19)
#define L502_REGS_IOARITH_DIN_ASYNC (L502_REGS_IOARITH_BLOCK+0x1A)
/********************* Адреса регистров блока управления BlackFin'ом **********/
#define L502_REGS_BF_CTL_BLOCK 0
#define L502_REGS_BF_CTL (L502_REGS_BF_CTL_BLOCK+0)
#define L502_REGS_BF_CMD (L502_REGS_BF_CTL_BLOCK+1)
#define L502_REGS_BF_STATUS (L502_REGS_BF_CTL_BLOCK+2)
#define L502_REGS_BF_IRQ (L502_REGS_BF_CTL_BLOCK+3)
#define L502_REGS_BF_IRQ_EN (L502_REGS_BF_CTL_BLOCK+4)
#define L502_REGS_BF_REQ_ADDR (L502_REGS_BF_CTL_BLOCK+5)
#define L502_REGS_BF_REQ_SIZE (L502_REGS_BF_CTL_BLOCK+6)
#define L502_REGS_BF_REQ_DATA (L502_REGS_BF_CTL_BLOCK+128)
#define L502_BF_REQ_DATA_SIZE_MAX 128
#define L502_BF_REQ_DATA_SIZE_MIN 8
/********************* Адреса регистров блока DMA *****************************/
#define L502_REGS_DMA_CTL_BLOCK 0x700
#define L502_REGS_DMA_CAP (L502_REGS_DMA_CTL_BLOCK)
#define L502_REGS_DMA_EN (L502_REGS_DMA_CTL_BLOCK+1)
#define L502_REGS_DMA_DIS (L502_REGS_DMA_CTL_BLOCK+2)
#define L502_REGS_DMA_RST (L502_REGS_DMA_CTL_BLOCK+3)
#define L502_REGS_DMA_IRQ (L502_REGS_DMA_CTL_BLOCK+4)
#define L502_REGS_DMA_IRQ_EN (L502_REGS_DMA_CTL_BLOCK+5)
#define L502_REGS_DMA_IRQ_DIS (L502_REGS_DMA_CTL_BLOCK+6)
#define L502_REGS_DMA_CH_PARAMS_SIZE (16 + L502_MAX_PAGES_CNT*4)
#define L502_DMA_CHNUM_IN 0
#define L502_DMA_CHNUM_OUT 1
/* номер регистра, с которого начинаются параметры канала DMA */
#define L502_REGS_DMA_CH_PARAMS(ch) (0x800 + L502_REGS_DMA_CH_PARAMS_SIZE*ch)
#define L502_REGS_DMA_CH_CTL(ch) (L502_REGS_DMA_CH_PARAMS(ch) + 0)
#define L502_REGS_DMA_CH_CMP_CNTR(ch) (L502_REGS_DMA_CH_PARAMS(ch) + 1)
#define L502_REGS_DMA_CH_CUR_CNTR(ch) (L502_REGS_DMA_CH_PARAMS(ch) + 2)
#define L502_REGS_DMA_CH_CUR_POS(ch) (L502_REGS_DMA_CH_PARAMS(ch) + 3)
#define L502_REGS_DMA_CH_PC_POS(ch) (L502_REGS_DMA_CH_PARAMS(ch) + 4)
/* адреса для регистров страниц DMA АЦП */
#define L502_REGS_DMA_CH_PAGES(ch) (L502_REGS_DMA_CH_PARAMS(ch) + 16)
#define L502_REGS_DMA_CH_PAGE_ADDRL(ch,n) (L502_REGS_DMA_CH_PAGES(ch) + 4*(n))
#define L502_REGS_DMA_CH_PAGE_ADDRH(ch,n) (L502_REGS_DMA_CH_PAGES(ch) + 4*(n)+1)
#define L502_REGS_DMA_CH_PAGE_LEN(ch,n) (L502_REGS_DMA_CH_PAGES(ch) + 4*(n)+2)
#define L502_REGBIT_BF_STATUS_HWAIT_Pos 0
#define L502_REGBIT_BF_STATUS_HWAIT_Msk (1UL << L502_REGBIT_BF_STATUS_HWAIT_Pos)
#define L502_REGBIT_BF_STATUS_BUSY_Pos 1
#define L502_REGBIT_BF_STATUS_BUSY_Msk (1UL << L502_REGBIT_BF_STATUS_BUSY_Pos)
/* описание отдельных битов регистров */
#define L502_REGBIT_DMA_CTL_PACK_SIZE_Pos 0
#define L502_REGBIT_DMA_CTL_PACK_SIZE_Msk (0xFFUL << L502_REGBIT_DMA_CTL_PACK_SIZE_Pos)
#define L502_REGBIT_DMA_CTL_PAGE_CNT_Pos 16
#define L502_REGBIT_DMA_CTL_PAGE_CNT_Msk (0xFFUL << L502_REGBIT_DMA_CTL_PAGE_CNT_Pos)
#define L502_REGBIT_DMA_CTL_AUTOSTOP_Pos 31
#define L502_REGBIT_DMA_CTL_AUTOSTOP_Msk (0x1UL << L502_REGBIT_DMA_CTL_AUTOSTOP_Pos)
#define L502_REGBIT_DMA_CTL_PC_WAIT_Pos 30
#define L502_REGBIT_DMA_CTL_PC_WAIT_Msk (0x1UL << L502_REGBIT_DMA_CTL_PC_WAIT_Pos)
#define L502_REGBIT_DMA_CH_ADC_Pos 0
#define L502_REGBIT_DMA_CH_ADC_Msk (0x1UL << L502_REGBIT_DMA_CH_ADC_Pos)
#define L502_REGBIT_DMA_CH_DAC_Pos 1
#define L502_REGBIT_DMA_CH_DAC_Msk (0x1UL << L502_REGBIT_DMA_CH_DAC_Pos)
#define L502_REGBIT_BF_CTL_BF_RESET_Pos 1
#define L502_REGBIT_BF_CTL_BF_RESET_Msk (0x1UL << L502_REGBIT_BF_CTL_BF_RESET_Pos)
#define L502_REGBIT_BF_CTL_HOST_WAIT_Pos 3
#define L502_REGBIT_BF_CTL_HOST_WAIT_Msk (0x1UL << L502_REGBIT_BF_CTL_HOST_WAIT_Pos)
#define L502_REGBIT_BF_CTL_DSP_MODE_Pos 4
#define L502_REGBIT_BF_CTL_DSP_MODE_Msk (0x1UL << L502_REGBIT_BF_CTL_DSP_MODE_Pos)
#define L502_REGBIT_BF_CTL_DBG_MODE_Pos 5
#define L502_REGBIT_BF_CTL_DBG_MODE_Msk (0x1UL << L502_REGBIT_BF_CTL_DBG_MODE_Pos)
#define L502_REGBIT_BF_CTL_CLK_DIV_Pos 8
#define L502_REGBIT_BF_CTL_CLK_DIV_Msk (0xFUL << L502_REGBIT_BF_CTL_CLK_DIV_Pos)
#define L502_REGBIT_DMA_CURPOS_PAGE_Pos 24
#define L502_REGBIT_DMA_CURPOS_PAGE_Msk (0xFFUL << L502_REGBIT_DMA_CURPOS_PAGE_Pos)
#define L502_REGBIT_DMA_CURPOS_OFFSET_Pos 0
#define L502_REGBIT_DMA_CURPOS_OFFSET_Msk (0xFFFFFFUL << L502_REGBIT_DMA_CURPOS_OFFSET_Pos)
#define L502_REGBIT_ADC_SLV_CLK_LOCK_Pos 31
#define L502_REGBIT_ADC_SLV_CLK_LOCK_Msk (0x1UL << L502_REGBIT_ADC_SLV_CLK_LOCK_Pos)
#define L502_REGBIT_IOHARD_OUT_SWAP_Pos 0
#define L502_REGBIT_IOHARD_OUT_SWAP_Msk (0x1UL << L502_REGBIT_IOHARD_OUT_SWAP_Pos)
#define L502_REGBIT_IOHARD_OUT_TFS_EN_Pos 1
#define L502_REGBIT_IOHARD_OUT_TFS_EN_Msk (0x1UL << L502_REGBIT_IOHARD_OUT_TFS_EN_Pos)
#define L502_REGBIT_IOHARD_OUT_RING_Pos 2
#define L502_REGBIT_IOHARD_OUT_RING_Msk (0x1UL << L502_REGBIT_IOHARD_OUT_RING_Pos)
#define L502_REGBIT_IOHARD_OUT_RFS_EN_Pos 3
#define L502_REGBIT_IOHARD_OUT_RFS_EN_Msk (0x1UL << L502_REGBIT_IOHARD_OUT_RFS_EN_Pos)
#define L502_REGBIT_DMA_IRQ_STEP_Msk(ch) (1UL << ch)
#define L502_REGBIT_DMA_IRQ_PAGE_Msk(ch) (1UL << (ch+8))
#define L502_REGBIT_DMA_IRQ_FLUSH_Msk(ch) (1UL << (ch+16))
#endif // L5XX_REGS_H

View File

@ -0,0 +1,164 @@
#include "l502api.h"
#include "l502api_private.h"
#include "l502_fpga_regs.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* минимальный размер внутреннего буфера */
#define L502_DMA_IN_BUF_SIZE_MIN 16*1024
#ifdef _WIN32
BOOL WINAPI DllMain(HINSTANCE hmod, DWORD reason, LPVOID resvd) {
switch (reason) {
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
#endif
static int32_t f_iface_free_devinfo_ptr(t_x502_devrec_inptr *devinfo_ptr);
static int32_t f_iface_stream_cfg(t_x502_hnd hnd, uint32_t ch, t_x502_stream_ch_params *params);
static int32_t f_iface_cycle_load_start(t_x502_hnd hnd, uint32_t size);
static int32_t f_iface_cycle_setup(t_x502_hnd hnd, uint32_t flags);
static int32_t f_iface_cycle_stop(t_x502_hnd hnd, uint32_t flags);
static int32_t f_iface_cycle_check_setup(t_x502_hnd hnd, uint32_t *done);
static int32_t f_iface_check_feature(t_x502_hnd hnd, uint32_t feature);
static const t_x502_dev_iface f_pcie_iface = {
L502_REGS_HARD_ID,
L502_DMA_IN_BUF_SIZE_MIN,
0,
L502_BF_REQ_DATA_SIZE_MAX,
4, //flash rd size
1, //flash wr size
f_iface_free_devinfo_ptr,
l502_port_open,
l502_port_close,
l502_port_fpga_reg_read,
l502_port_fpga_reg_write,
f_iface_stream_cfg,
l502_port_stream_start,
l502_port_stream_stop,
l502_port_stream_free,
NULL,
l502_port_stream_read,
l502_port_stream_write,
l502_port_stream_rdy_size,
l502_iface_bf_mem_block_rd,
l502_iface_bf_mem_block_wr,
l502_iface_bf_firm_load,
l502_iface_flash_rd,
l502_iface_flash_wr,
l502_iface_flash_erase,
l502_iface_flash_set_prot,
l502_port_renew_info,
f_iface_cycle_load_start,
f_iface_cycle_setup,
f_iface_cycle_stop,
f_iface_cycle_check_setup,
NULL,
NULL,
f_iface_check_feature
};
X502_EXPORT(int32_t) L502_GetDriverVersion(t_x502_hnd hnd, uint32_t* ver) {
int32_t err = X502_CHECK_HND(hnd);
if (err == X502_ERR_OK)
err = l502_port_get_drv_ver(hnd, ver);
return err;
}
int32_t l502_devlist_gen(t_x502_devrec *info, void *iface_data) {
int32_t err = X502_ERR_OK;
t_x502_devrec_inptr *devinfo_ptr = calloc(1, sizeof(t_x502_devrec_inptr));
if (devinfo_ptr == NULL) {
err = X502_ERR_MEMORY_ALLOC;
} else {
devinfo_ptr->iface_data = iface_data;
devinfo_ptr->iface = &f_pcie_iface;
info->iface = X502_IFACE_PCI;
info->flags |= X502_DEVFLAGS_IFACE_SUPPORT_PCI | X502_DEVFLAGS_FPGA_LOADED;
info->internal = devinfo_ptr;
}
return err;
}
X502_EXPORT(int32_t) L502_GetSerialList(char serials[][X502_SERIAL_SIZE], uint32_t size,
uint32_t flags, uint32_t *devcnt) {
return X502_GetSerialList(serials, size, flags, devcnt, L502_DEVICE_NAME, L502_GetDevRecordsList);
}
X502_EXPORT(int32_t) L502_Open(t_x502_hnd hnd, const char *serial) {
return X502_Open(hnd, serial, L502_DEVICE_NAME, L502_GetDevRecordsList);
}
static int32_t f_iface_free_devinfo_ptr(t_x502_devrec_inptr *devinfo_ptr) {
l502_port_free_iface_data(devinfo_ptr->iface_data);
free(devinfo_ptr);
return X502_ERR_OK;
}
static int32_t f_iface_stream_cfg(t_x502_hnd hnd, uint32_t ch, t_x502_stream_ch_params *params) {
t_lpcie_stream_ch_params lpcie_ch_params;
memset(&lpcie_ch_params, 0, sizeof(lpcie_ch_params));
lpcie_ch_params.ch = ch;
lpcie_ch_params.irq_step = params->step;
lpcie_ch_params.buf_size = params->buf_size;
return l502_port_stream_set_params(hnd, &lpcie_ch_params);
}
static int32_t f_iface_cycle_load_start(t_x502_hnd hnd, uint32_t size) {
uint32_t irq_step = STREAM_OUT_IRQ_STEP(hnd);
return l502_port_cycle_load_start(hnd, L502_DMA_CHNUM_OUT, size, irq_step);
}
static int32_t f_iface_cycle_setup(t_x502_hnd hnd, uint32_t flags) {
return l502_port_cycle_setup(hnd, L502_DMA_CHNUM_OUT, (flags & X502_OUT_CYCLE_FLAGS_FORCE) ?
LPCIE_CYCLE_SW_EVT_IMMIDIATLY : LPCIE_CYCLE_SW_EVT_END_OF_CYCLE);
}
static int32_t f_iface_cycle_stop(t_x502_hnd hnd, uint32_t flags) {
return l502_port_cycle_stop(hnd, L502_DMA_CHNUM_OUT, (flags & X502_OUT_CYCLE_FLAGS_FORCE) ?
LPCIE_CYCLE_SW_EVT_IMMIDIATLY : LPCIE_CYCLE_SW_EVT_END_OF_CYCLE);
}
static int32_t f_iface_cycle_check_setup(t_x502_hnd hnd, uint32_t *done) {
uint32_t ver;
int32_t err = L502_GetDriverVersion(hnd, &ver);
if ((err == X502_ERR_OK) && !LPCIE_IOCTL_SUPPORT_CYCLE_CHECK_SETUP(ver))
err = X502_ERR_NOT_SUP_BY_DRIVER;
if (err == X502_ERR_OK)
err = l502_port_cycle_check_setup(hnd, L502_DMA_CHNUM_OUT, done);
if (err == X502_ERR_OK) {
/* за счет буфера в плате на вывод может пройти несколько мс после
* передачи в модуль данных до того как реально эти данные появятся
* на выходе. т.к. это отследить явно нельзя, то приходится ставить задержку */
SLEEP_MS(3);
}
return err;
}
static int32_t f_iface_check_feature(t_x502_hnd hnd, uint32_t feature) {
int32_t err = X502_ERR_NOT_SUP_BY_FIRMWARE;
switch (feature) {
case X502_FEATURE_OUT_FREQ_DIV:
case X502_FEATURE_OUT_STATUS_FLAGS:
if (hnd->info.fpga_ver >= 0x5)
err = X502_ERR_OK;
break;
default:
err = X502_ERR_UNKNOWN_FEATURE_CODE;
break;
}
return err;
}

View File

@ -0,0 +1,72 @@
LIBRARY l502api.dll
EXPORTS
L502_Create
L502_Free
L502_Open
L502_Close
L502_GetSerialList
L502_GetDevInfo
L502_Configure
L502_StreamsEnable
L502_StreamsDisable
L502_StreamsStart
L502_StreamsStop
L502_IsRunning
L502_Recv
L502_Send
L502_GetRecvReadyCount
L502_GetSendReadyCount
L502_SetDmaBufSize
L502_SetDmaIrqStep
L502_GetNextExpectedLchNum
L502_PreloadStart
L502_ProcessAdcData
L502_ProcessData
L502_ProcessDataWithUserExt
L502_PrepareData
L502_SetLChannel
L502_SetLChannelCount
L502_GetLChannelCount
L502_SetAdcFreqDivider
L502_SetAdcInterframeDelay
L502_SetDinFreqDivider
L502_SetAdcFreq
L502_SetDinFreq
L502_GetAdcFreq
L502_SetRefFreq
L502_SetSyncMode
L502_SetSyncStartMode
L502_SetMode
L502_GetMode
L502_SetAdcCoef
L502_GetAdcCoef
L502_SetDacCoef
L502_GetDacCoef
L502_AsyncOutDac
L502_AsyncOutDig
L502_AsyncInDig
L502_AsyncGetAdcFrame
L502_BfCheckFirmwareIsLoaded
L502_BfLoadFirmware
L502_BfMemRead
L502_BfMemWrite
L502_BfExecCmd
L502_FlashRead
L502_FlashWrite
L502_FlashErase
L502_FlashWriteEnable
L502_FlashWriteDisable
L502_FpgaRegWrite
L502_FpgaRegRead
L502_GetDllVersion
L502_GetDriverVersion
L502_GetErrorString
L502_LedBlink
L502_SetDigInPullup
L502_ReloadDevInfo
L502_OutCycleLoadStart
L502_OutCycleSetup
L502_OutCycleStop
L502_GetDevRecordsList

View File

@ -0,0 +1,162 @@
/***************************************************************************//**
@file l502api.h
Файл содержит все необходимые описания типов, констант и функций для работы
с модулем L-502 из пользовательской программы.
@date 11.03.2012
@author Borisov Alexey <borisov@lcard.ru>
******************************************************************************/
#ifndef L502_API_H
#define L502_API_H
#include "l502api_compat.h"
#include "x502api.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
@addtogroup func_open
@{
*******************************************************************************/
/***************************************************************************//**
@brief Получение списка серийных номеров модулей L-502
Функция возвращает список номеров всех найденных модулей L-502, независимо от
того, открыты они сейчас или нет.
Если нужен список только тех модулей, которые не открыты (то есть
только тех, с которыми можно установить соединение), то для этого можно
передать в функцию флаг #X502_GETDEVS_FLAGS_ONLY_NOT_OPENED.
@param[in] serials Массив размером size*#X502_SERIAL_SIZE байт, в который
будут сохранены серийные номера найденных модулей.
Может быть NULL, если size=0, а devcnt!=NULL, в случае,
если нужно только получить количество модулей в системе.
@param[in] size Определяет, сколько максимально серийных номеров может
быть сохранено в массив serial. Будут сохранены только
первые size серийных номеров.
Может быть 0, если serials=NULL
@param[in] flags Флаги из #t_x502_getdevs_flags, определяющие поведение
функции.
@param[out] devcnt Если devcnt!=NULL, то в данную переменную сохраняется
общее число найденных модулей L502
(может быть больше size).
@return Если <0 - код ошибки, иначе количество сохраненных
серийных номеров в массиве serials (всегда <= size)
*******************************************************************************/
X502_EXPORT(int32_t) L502_GetSerialList(char serials[][X502_SERIAL_SIZE], uint32_t size,
uint32_t flags, uint32_t *devcnt);
/***************************************************************************//**
@brief Открытие модуля L-502 по его серийному номеру
Функция устанавливает связь с модулем L-502 по его серийному номеру.
После успешного выполнения этой функции, пользователь получает эксклюзивный
доступ к модулю через описатель модуля. До закрытия связи с помощью
X502_Close() никто другой установить связь с модулем не сможет
(будет возвращена ошибка #X502_ERR_DEVICE_ACCESS_DENIED).
Если в качестве серийного номера передан NULL или пустая строка, то будет
установлена связь с первым найденным модулем, с которым получится успешно
ее установить.
Если в системе нет ни одного модуля, то будет возвращена ошибка
#X502_ERR_DEVICE_NOT_FOUND. Если в системе присутствуют модули L-502, но
соединение ни с одним из них установить не удалось, то будет возвращена
ошибка, полученная при попытке установить соединение с последним
найденным модулем.
После завершения работы с устройством соединение должно быть закрыто с
помощью X502_Close().
@param[in] hnd Описатель устройства.
@param[in] serial Указатель на строку с серийным номером открываемого
модуля или NULL.
@return Код ошибки.
*******************************************************************************/
X502_EXPORT(int32_t) L502_Open(t_x502_hnd hnd, const char *serial);
/** @} */
/***************************************************************************//**
@addtogroup func_devrec
@{
*******************************************************************************/
/***************************************************************************//**
@brief Получить список записей, соответствующих подключенным модулям L502
Функция находит все подключенные модули L-502 и инициализирует
записи о каждом найденном устройстве и сохраняет их в переданный список
(если не нулевой).
Возвращенные в списке записи должны быть очищены после использования
с помощью X502_FreeDevRecordList() (также в случае повторного
вызов L502_GetDevRecordsList() с тем же массивом записей, записи, полученные
при предыдущем вызове, должны быть сперва очищены).
@param[in] list Массив для сохранения записей о найденных устройствах.
Должен содержать место для сохранения не менее size записей.
Может быть NULL, если size=0, а devcnt!=NULL, в случае,
если нужно только получить количество модулей в системе.
@param[in] size Определяет, сколько максимально записей может
быть сохранено в массив list. Будут сохранены только
первые size записей, если устройств найденно больше.
@param[in] flags Флаги из #t_x502_getdevs_flags, определяющие поведение
функции.
@param[out] devcnt Если не нулевой указатель, то в данную переменную сохраняется
общее число найденных модулей L-502 (может быть больше size).
@return Если <0 --- код ошибки, иначе количество сохраненных
записей о найденных устройствах (всегда <= size).
Именно на этот размер нужно сделать в дальнейшем
X502_FreeDevRecordList() для освобождения памяти,
выделенной под информацию, на которую ссылается запись.
******************************************************************************/
X502_EXPORT(int32_t) L502_GetDevRecordsList(t_x502_devrec *list, uint32_t size,
uint32_t flags, uint32_t *devcnt) ;
/** @} */
/***************************************************************************//**
@addtogroup func_misc
@{
*******************************************************************************/
/**************************************************************************//**
@brief Получить версию драйвера модуля L-502
Функция возвращает версию драйвера, установленного для
указанного открытого устройства.
Версия возвращается в виде 32-битного числа.
Строковое представление возвращенной версии - четыре числа,
старшее соответствует старшему байту, младшее - младшему.
Старший байт - мажорная версия, второй по старшинству байт - минорная,
третий - ревизия, четвертый - номер сборки (не используется - всегда 0).
Это та версия, которая отображается в диспетчере устройств в Windows или
с помощью modinfo в Linux.
Данная функция доступна только для устройств с интерфейсом PCI/PCI-Express (L502)
@param[in] hnd Описатель модуля.
@param[out] ver 32-битное число, представляющее собой версию драйвера
@return Код ошибки.
*****************************************************************************/
X502_EXPORT(int32_t) L502_GetDriverVersion(t_x502_hnd hnd, uint32_t* ver);
/** @} */
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,48 @@
#include <winresrc.h>
#define LIB_VERSION @X502API_VER_MAJOR@,@X502API_VER_MINOR@,@X502API_VER_PATCH@,0
#define VER_DEBUG VS_FF_DEBUG
1 VERSIONINFO
FILEVERSION LIB_VERSION
PRODUCTVERSION LIB_VERSION
#ifndef NDEBUG
FILEFLAGS 0
#else
FILEFLAGS VER_DEBUG
#endif
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "04090000"
BEGIN
VALUE "CompanyName", "L-Card"
VALUE "FileDescription", "Library for L502"
VALUE "FileVersion", "@X502API_VERSION@"
VALUE "OriginalFilename", "l502api.dll"
VALUE "ProductName", "l502api"
VALUE "ProductVersion", "@X502API_VERSION@"
VALUE "LegalCopyright", "© 2015 L-Card Ltd."
END
BLOCK "04190000"
BEGIN
VALUE "CompanyName", "Л Кард"
VALUE "FileDescription", "Библиотека для работы с платой L502"
VALUE "FileVersion", "@X502API_VERSION@"
VALUE "OriginalFilename", "l502api.dll"
VALUE "ProductName", "l502api"
VALUE "ProductVersion", "@X502API_VERSION@"
VALUE "LegalCopyright", "© 2015 ООО 'Л Кард'"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
VALUE "Translation", 0x419, 1251
END
END

View File

@ -0,0 +1,272 @@
#include "l502api_private.h"
#include "ltimer.h"
#include "l502_fpga_regs.h"
#include <stdlib.h>
#include <string.h>
#define BF_LDR_HDR_SIZE (16)
#define BF_LDR_HDRSGN (0xAD)
#define BF_LDR_HDRPOS_SGN (3)
#define BF_LDR_FLAG_SAVE (0x0010) //не используется
#define BF_LDR_FLAG_AUX (0x0020) //не используется
#define BF_LDR_FLAG_FILL (0x0100)
#define BF_LDR_FLAG_QUICKBOOT (0x0200) //не используется
#define BF_LDR_FLAG_CALLBACK (0x0400) //не используется
#define BF_LDR_FLAG_INIT (0x0800) //не используется
#define BF_LDR_FLAG_IGNORE (0x1000)
#define BF_LDR_FLAG_INDIRECT (0x2000) //не используется
#define BF_LDR_FLAG_FIRST (0x4000)
#define BF_LDR_FLAG_FINAL (0x8000)
#define L502_BF_WAIT_LOAD_RDY_TOUT 500
#define LDR_BUFF_SIZE 4096
#define BF_CHECK_ADDR(addr) (((addr) < 0xFFA0C000) && ((addr)>= 0xFFA0000)) || \
(((addr) < 0xFF908000) && ((addr) >=0xFF900000)) || \
(((addr) < 0xFF808000) && ((addr) >=0xFF800000)) || \
(((addr) < 0x2000000)) ? 0 : X502_ERR_BF_INVALID_ADDR
#define BF_CHECK_ADDR_SIZE(addr, size) BF_CHECK_ADDR(addr) ? X502_ERR_BF_INVALID_ADDR : \
BF_CHECK_ADDR(addr+size*4-1) ? X502_ERR_BF_INVALID_ADDR : 0
typedef struct st_bf_ldr_pkt {
uint8_t res;
uint8_t dma_mode;
uint16_t flags;
uint32_t addr;
uint32_t size;
uint32_t arg;
} t_bf_ldr_pkt;
/* Разбираем заголовок блока LDR-формата из буфера размером BF_LDR_HDR_SIZE
и сохраняем параметры в структуре pkt */
static int32_t f_parse_ldr_hdr(const uint8_t *hdr, t_bf_ldr_pkt *pkt) {
int32_t err = X502_ERR_OK;
uint32_t* pdw_buff = (uint32_t*)hdr;
uint8_t xor_ch = 0;
int i;
for (i=0; i < BF_LDR_HDR_SIZE; i++) {
xor_ch ^= hdr[i];
}
if ((xor_ch!=0) || (hdr[BF_LDR_HDRPOS_SGN] != BF_LDR_HDRSGN)) {
err = X502_ERR_LDR_FILE_FORMAT;
} else {
pkt->res = 0;
pkt->dma_mode = pdw_buff[0]&0xF;
pkt->flags = pdw_buff[0]&0xFFF0;
pkt->addr = pdw_buff[1];
pkt->size = pdw_buff[2];
pkt->arg = pdw_buff[3];
if ((pkt->flags & BF_LDR_FLAG_INIT) && (pkt->flags & BF_LDR_FLAG_FILL)) {
err = X502_ERR_LDR_FILE_FORMAT;
} else if (pkt->flags & (BF_LDR_FLAG_CALLBACK | BF_LDR_FLAG_INDIRECT | BF_LDR_FLAG_INIT)) {
err = X502_ERR_LDR_FILE_UNSUP_FEATURE;
} else if ((pkt->flags & BF_LDR_FLAG_INIT) && (pkt->addr != 0xFFA00000)) {
err = X502_ERR_LDR_FILE_UNSUP_STARTUP_ADDR;
}
}
return err;
}
static int32_t f_bf_wait_cmd_done(t_x502_hnd hnd) {
int32_t err = X502_ERR_OK;
t_ltimer tmr;
uint32_t status;
ltimer_set(&tmr, LTIMER_MS_TO_CLOCK_TICKS(X502_BF_REQ_TOUT));
do {
err = l502_port_fpga_reg_read(hnd, L502_REGS_BF_STATUS, &status);
} while ((status & L502_REGBIT_BF_STATUS_BUSY_Msk) &&
(err == X502_ERR_OK) && !ltimer_expired(&tmr));
if (!err && (status & L502_REGBIT_BF_STATUS_BUSY_Msk))
err = X502_ERR_BF_REQ_TIMEOUT;
return err;
}
int32_t l502_iface_bf_mem_block_rd(t_x502_hnd hnd, uint32_t addr, uint32_t *block, uint32_t size){
uint32_t i;
int32_t err = f_bf_wait_cmd_done(hnd);
/* записываем переметры передачи - размер и адрес в памяти BlackFin */
if (err == X502_ERR_OK)
err = l502_port_fpga_reg_write(hnd, L502_REGS_BF_REQ_SIZE, size);
if (err == X502_ERR_OK)
err = l502_port_fpga_reg_write(hnd, L502_REGS_BF_REQ_ADDR, addr);
/* даем команду на запис */
if (err == X502_ERR_OK)
err = l502_port_fpga_reg_write(hnd, L502_REGS_BF_CMD, L502_BF_CMD_READ);
/* ждем, пока операция не будет завершена */
if (err == X502_ERR_OK)
err = f_bf_wait_cmd_done(hnd);
/* записываем блок данных в буфер ПЛИС */
for (i=0; (i < size) && (err == X502_ERR_OK); i++) {
err = l502_port_fpga_reg_read(hnd, L502_REGS_BF_REQ_DATA+i, &block[i]);
}
return err;
}
int32_t l502_iface_bf_mem_block_wr(t_x502_hnd hnd, uint32_t addr, const uint32_t *block, uint32_t size) {
uint32_t i;
int32_t err = f_bf_wait_cmd_done(hnd);
if (err == X502_ERR_OK) {
/* записываем блок данных в буфер ПЛИС */
for (i=0; (i < size) && (err == X502_ERR_OK); i++) {
err = l502_port_fpga_reg_write(hnd, L502_REGS_BF_REQ_DATA+i, block[i]);
}
/* записываем переметры передачи - размер и адрес в памяти BlackFin */
if (err == X502_ERR_OK)
err = l502_port_fpga_reg_write(hnd, L502_REGS_BF_REQ_SIZE, size);
if (err == X502_ERR_OK)
err = l502_port_fpga_reg_write(hnd, L502_REGS_BF_REQ_ADDR, addr);
/* даем команду на запис */
if (err == X502_ERR_OK)
err = l502_port_fpga_reg_write(hnd, L502_REGS_BF_CMD, L502_BF_CMD_WRITE);
/* ждем, пока операция не будет завершена */
if (err == X502_ERR_OK)
err = f_bf_wait_cmd_done(hnd);
}
return err;
}
static int32_t f_bf_mem_wr(t_x502_hnd hnd, uint32_t addr, const uint32_t* regs, uint32_t size) {
int32_t err = X502_ERR_OK;
/* данные записываем блоками по L502_BF_REQ_DATA_SIZE */
while ((err == X502_ERR_OK) && size) {
int put_size = (size < hnd->iface_hnd->bf_mem_block_size) ? size :
hnd->iface_hnd->bf_mem_block_size;
err = hnd->iface_hnd->bf_mem_block_wr(hnd, addr, regs, put_size);
if (!err) {
size -= put_size;
regs += put_size;
addr += put_size*4;
}
}
return err;
}
int32_t l502_iface_bf_firm_load(t_x502_hnd hnd, const char *filename) {
int32_t err = X502_ERR_OK;
FILE* ldr_file=fopen(filename, "rb");
if (ldr_file==NULL) {
err = X502_ERR_LDR_FILE_OPEN;
} else {
int32_t next_err = X502_ERR_OK;
uint32_t *ldr_buff = NULL;
ldr_buff = malloc(LDR_BUFF_SIZE);
if (ldr_buff == NULL)
err = X502_ERR_MEMORY_ALLOC;
if (err == X502_ERR_OK) {
int rd_size = 0;
int stop = 0;
uint32_t reg;
uint8_t hdr[BF_LDR_HDR_SIZE];
t_ltimer tmr;
//uint32_t* pdw = (uint32_t*)ldr_buff;
t_bf_ldr_pkt pkt, pkt_next;
uint32_t bf_val = 0;
memset(&pkt_next, 0, sizeof(pkt_next));
l502_port_fpga_reg_read(hnd, L502_REGS_BF_CTL, &bf_val);
l502_port_fpga_reg_write(hnd, L502_REGS_BF_CTL, L502_REGBIT_BF_CTL_DSP_MODE_Msk
| (bf_val & 0xF00)); //set rst
SLEEP_MS(1);
l502_port_fpga_reg_write(hnd, L502_REGS_BF_CTL, L502_REGBIT_BF_CTL_DSP_MODE_Msk |
L502_REGBIT_BF_CTL_BF_RESET_Msk | (bf_val & 0xF00)); //release rst
ltimer_set(&tmr, LTIMER_MS_TO_CLOCK_TICKS(L502_BF_WAIT_LOAD_RDY_TOUT));
do {
l502_port_fpga_reg_read(hnd, L502_REGS_BF_CTL, &reg);
if ((reg & L502_REGBIT_BF_CTL_HOST_WAIT_Msk) && ltimer_expired(&tmr))
err = X502_ERR_BF_LOAD_RDY_TOUT;
} while ((err == X502_ERR_OK) && (reg & L502_REGBIT_BF_CTL_HOST_WAIT_Msk));
if (err == X502_ERR_OK) {
err = fread(hdr, 1, BF_LDR_HDR_SIZE, ldr_file) == BF_LDR_HDR_SIZE ?
f_parse_ldr_hdr(hdr, &pkt) : X502_ERR_LDR_FILE_READ;
}
while ((err == X502_ERR_OK) && !stop) {
if (next_err != X502_ERR_OK) {
err = next_err;
} else if (((pkt.flags & BF_LDR_FLAG_FILL) == 0) && (pkt.size != 0)) {
int r_size = (pkt.size > LDR_BUFF_SIZE) ? LDR_BUFF_SIZE : pkt.size;
rd_size = (int)fread(ldr_buff, 1, r_size, ldr_file);
if (rd_size!=r_size)
err = X502_ERR_LDR_FILE_READ;
}
if (err == X502_ERR_OK) {
if (pkt.size > LDR_BUFF_SIZE) {
pkt_next = pkt;
pkt_next.addr += LDR_BUFF_SIZE;
pkt_next.size -= LDR_BUFF_SIZE;
pkt.size = LDR_BUFF_SIZE;
} else {
next_err = fread(hdr, 1, BF_LDR_HDR_SIZE, ldr_file) == BF_LDR_HDR_SIZE ?
f_parse_ldr_hdr(hdr, &pkt_next) : X502_ERR_LDR_FILE_READ;
if (next_err != X502_ERR_OK) {
pkt_next.size = 0;
}
}
if (pkt.size!=0) {
uint32_t size = ((pkt.size+31)/(32))*8;
if (pkt.flags & BF_LDR_FLAG_FILL) {
uint32_t i;
for (i=0; i < size; i++)
ldr_buff[i] = pkt.arg;
}
if ((pkt.flags & BF_LDR_FLAG_FINAL)
|| ((pkt_next.flags & BF_LDR_FLAG_FINAL) && (pkt_next.size==0))) {
uint32_t buf_pos = 0;
err = BF_CHECK_ADDR_SIZE(pkt.addr, size);
if ((err == X502_ERR_OK) && (size > 8)) {
err = f_bf_mem_wr(hnd, pkt.addr, ldr_buff, size-8);
pkt.addr+=4*(size-8);
buf_pos = size-8;
size = 8;
}
if (err == X502_ERR_OK)
err = l502_port_fpga_reg_write(hnd, L502_REGS_BF_CMD, L502_BF_CMD_HIRQ);
if (err == X502_ERR_OK)
err = f_bf_mem_wr(hnd, pkt.addr, &ldr_buff[buf_pos], size);
stop=1;
if (err == X502_ERR_OK) {
err = l502_port_fpga_reg_write(hnd, L502_REGS_BF_CTL, L502_REGBIT_BF_CTL_DSP_MODE_Msk |
L502_REGBIT_BF_CTL_BF_RESET_Msk);
}
} else if (!(pkt.flags & BF_LDR_FLAG_IGNORE)) {
err = BF_CHECK_ADDR_SIZE(pkt.addr, size);
if (!err)
err = f_bf_mem_wr(hnd, pkt.addr, ldr_buff, size);
}
}
pkt = pkt_next;
}
}
}
free(ldr_buff);
fclose(ldr_file);
}
return err;
}

View File

@ -0,0 +1,285 @@
#include "l502api_compat.h"
#include "x502api_private.h"
LPCIE_EXPORT(t_l502_hnd) L502_Create(void) {
return X502_Create();
}
LPCIE_EXPORT(int32_t) L502_Free(t_l502_hnd hnd) {
return X502_Free(hnd);
}
LPCIE_EXPORT(int32_t) L502_Close(t_l502_hnd hnd) {
return X502_Close(hnd);
}
LPCIE_EXPORT(int32_t) L502_GetDevInfo(t_l502_hnd hnd, t_l502_info* info) {
return X502_GetDevInfo(hnd, (t_x502_info*)info);
}
LPCIE_EXPORT(int32_t) L502_Configure(t_l502_hnd hnd, uint32_t flags) {
return X502_Configure(hnd, flags);
}
LPCIE_EXPORT(int32_t) L502_SetLChannel(t_l502_hnd hnd, uint32_t lch, uint32_t phy_ch,
uint32_t mode, uint32_t range, uint32_t avg) {
return X502_SetLChannel(hnd, lch, phy_ch, mode, range, avg);
}
LPCIE_EXPORT(int32_t) L502_SetLChannelCount(t_l502_hnd hnd, uint32_t lch_cnt) {
return X502_SetLChannelCount(hnd, lch_cnt);
}
LPCIE_EXPORT(int32_t) L502_GetLChannelCount(t_l502_hnd hnd, uint32_t* lch_cnt) {
return X502_GetLChannelCount(hnd, lch_cnt);
}
LPCIE_EXPORT(int32_t) L502_SetAdcFreqDivider(t_l502_hnd hnd, uint32_t adc_freq_div) {
return X502_SetAdcFreqDivider(hnd, adc_freq_div);
}
LPCIE_EXPORT(int32_t) L502_SetAdcInterframeDelay(t_l502_hnd hnd, uint32_t delay) {
return X502_SetAdcInterframeDelay(hnd, delay);
}
LPCIE_EXPORT(int32_t) L502_SetDinFreqDivider(t_l502_hnd hnd, uint32_t din_freq_div) {
return X502_SetDinFreqDivider(hnd, din_freq_div);
}
LPCIE_EXPORT(int32_t) L502_SetAdcFreq(t_l502_hnd hnd, double *f_acq, double *f_frame) {
return X502_SetAdcFreq(hnd, f_acq, f_frame);
}
LPCIE_EXPORT(int32_t) L502_SetDinFreq(t_l502_hnd hnd, double *f_din) {
return X502_SetDinFreq(hnd, f_din);
}
LPCIE_EXPORT(int32_t) L502_GetAdcFreq(t_l502_hnd hnd, double *f_acq, double *f_frame) {
return X502_GetAdcFreq(hnd, f_acq, f_frame);
}
LPCIE_EXPORT(int32_t) L502_SetRefFreq(t_l502_hnd hnd, uint32_t freq) {
return X502_SetRefFreq(hnd, freq);
}
LPCIE_EXPORT(int32_t) L502_SetSyncMode(t_l502_hnd hnd, uint32_t sync_mode) {
return X502_SetSyncMode(hnd, sync_mode);
}
LPCIE_EXPORT(int32_t) L502_SetSyncStartMode(t_l502_hnd hnd, uint32_t sync_start_mode) {
return X502_SetSyncStartMode(hnd, sync_start_mode);
}
LPCIE_EXPORT(int32_t) L502_SetMode(t_l502_hnd hnd, uint32_t mode) {
return X502_SetMode(hnd, mode);
}
LPCIE_EXPORT(int32_t) L502_GetMode(t_l502_hnd hnd, uint32_t* mode) {
return X502_GetMode(hnd, mode);
}
LPCIE_EXPORT(int32_t) L502_SetAdcCoef(t_l502_hnd hnd, uint32_t range, double k, double offs) {
return X502_SetAdcCoef(hnd, range, k, offs);
}
LPCIE_EXPORT(int32_t) L502_GetAdcCoef(t_l502_hnd hnd, uint32_t range, double* k, double* offs) {
return X502_GetAdcCoef(hnd, range, k, offs);
}
LPCIE_EXPORT(int32_t) L502_SetDacCoef(t_l502_hnd hnd, uint32_t ch, double k, double offs) {
return X502_SetDacCoef(hnd, ch, k, offs);
}
LPCIE_EXPORT(int32_t) L502_GetDacCoef(t_l502_hnd hnd, uint32_t ch, double* k, double* offs) {
return X502_GetDacCoef(hnd, ch, k, offs);
}
LPCIE_EXPORT(int32_t) L502_AsyncOutDac(t_l502_hnd hnd, uint32_t ch, double data, uint32_t flags) {
return X502_AsyncOutDac(hnd, ch, data, flags);
}
LPCIE_EXPORT(int32_t) L502_AsyncOutDig(t_l502_hnd hnd, uint32_t val, uint32_t msk) {
return X502_AsyncOutDig(hnd, val, msk);
}
LPCIE_EXPORT(int32_t) L502_AsyncInDig(t_l502_hnd hnd, uint32_t* din) {
return X502_AsyncInDig(hnd, din);
}
LPCIE_EXPORT(int32_t) L502_AsyncGetAdcFrame(t_l502_hnd hnd, uint32_t flags,
uint32_t tout, double* data) {
return X502_AsyncGetAdcFrame(hnd, flags, tout, data);
}
LPCIE_EXPORT(int32_t) L502_StreamsEnable(t_l502_hnd hnd, uint32_t streams) {
return X502_StreamsEnable(hnd, streams);
}
LPCIE_EXPORT(int32_t) L502_StreamsDisable(t_l502_hnd hnd, uint32_t streams) {
return X502_StreamsDisable(hnd, streams);
}
LPCIE_EXPORT(int32_t) L502_StreamsStart(t_l502_hnd hnd) {
return X502_StreamsStart(hnd);
}
LPCIE_EXPORT(int32_t) L502_StreamsStop(t_l502_hnd hnd) {
return X502_StreamsStop(hnd);
}
LPCIE_EXPORT(int32_t) L502_IsRunning(t_l502_hnd hnd) {
return X502_IsRunning(hnd);
}
LPCIE_EXPORT(int32_t) L502_Recv(t_l502_hnd hnd, uint32_t* buf, uint32_t size, uint32_t tout) {
return X502_Recv(hnd, buf, size, tout);
}
LPCIE_EXPORT(int32_t) L502_Send(t_l502_hnd hnd, const uint32_t* buf, uint32_t size, uint32_t tout) {
return X502_Send(hnd, buf, size, tout);
}
LPCIE_EXPORT(int32_t) L502_ProcessAdcData(t_l502_hnd hnd, const uint32_t* src, double *dest,
uint32_t *size, uint32_t flags) {
return X502_ProcessAdcData(hnd, src, dest, size, flags);
}
LPCIE_EXPORT(int32_t) L502_ProcessData(t_l502_hnd hnd, const uint32_t* src, uint32_t size,
uint32_t flags, double *adc_data, uint32_t *adc_data_size,
uint32_t *din_data, uint32_t *din_data_size) {
return X502_ProcessData(hnd, src, size, flags, adc_data, adc_data_size,
din_data, din_data_size);
}
LPCIE_EXPORT(int32_t) L502_ProcessDataWithUserExt(t_l502_hnd hnd, const uint32_t* src, uint32_t size,
uint32_t flags, double *adc_data,
uint32_t *adc_data_size, uint32_t *din_data,
uint32_t *din_data_size,
uint32_t *usr_data, uint32_t *usr_data_size) {
return X502_ProcessDataWithUserExt(hnd, src, size, flags, adc_data, adc_data_size,
din_data, din_data_size, usr_data, usr_data_size);
}
LPCIE_EXPORT(int32_t) L502_PrepareData(t_l502_hnd hnd, const double* dac1, const double* dac2,
const uint32_t* digout, uint32_t size, int32_t flags,
uint32_t* out_buf) {
return X502_PrepareData(hnd, dac1, dac2, digout, size, flags, out_buf);
}
LPCIE_EXPORT(int32_t) L502_GetRecvReadyCount(t_l502_hnd hnd, uint32_t *rdy_cnt) {
return X502_GetRecvReadyCount(hnd, rdy_cnt);
}
LPCIE_EXPORT(int32_t) L502_GetSendReadyCount(t_l502_hnd hnd, uint32_t *rdy_cnt) {
return X502_GetSendReadyCount(hnd, rdy_cnt);
}
LPCIE_EXPORT(int32_t) L502_GetNextExpectedLchNum(t_l502_hnd hnd, uint32_t *lch) {
return X502_GetNextExpectedLchNum(hnd, lch);
}
LPCIE_EXPORT(int32_t) L502_PreloadStart(t_l502_hnd hnd) {
return X502_PreloadStart(hnd);
}
LPCIE_EXPORT(int32_t) L502_OutCycleLoadStart(t_l502_hnd hnd, uint32_t size) {
return X502_OutCycleLoadStart(hnd, size);
}
LPCIE_EXPORT(int32_t) L502_OutCycleSetup(t_l502_hnd hnd, uint32_t flags) {
return X502_OutCycleSetup(hnd, flags);
}
LPCIE_EXPORT(int32_t) L502_OutCycleStop(t_l502_hnd hnd, uint32_t flags) {
return X502_OutCycleStop(hnd, flags);
}
LPCIE_EXPORT(int32_t) L502_SetDmaBufSize(t_l502_hnd hnd, uint32_t dma_ch, uint32_t size) {
return X502_SetStreamBufSize(hnd, dma_ch, size);
}
LPCIE_EXPORT(int32_t) L502_SetDmaIrqStep(t_l502_hnd hnd, uint32_t dma_ch, uint32_t step) {
return X502_SetStreamStep(hnd, dma_ch, step);
}
LPCIE_EXPORT(int32_t) L502_BfLoadFirmware(t_l502_hnd hnd, const char* filename) {
return X502_BfLoadFirmware(hnd, filename);
}
LPCIE_EXPORT(int32_t) L502_BfCheckFirmwareIsLoaded(t_l502_hnd hnd, uint32_t *version) {
return X502_BfCheckFirmwareIsLoaded(hnd, version);
}
LPCIE_EXPORT(int32_t) L502_BfMemRead(t_l502_hnd hnd, uint32_t addr, uint32_t* regs,
uint32_t size) {
return X502_BfMemRead(hnd, addr, regs, size);
}
LPCIE_EXPORT(int32_t) L502_BfMemWrite(t_l502_hnd hnd, uint32_t addr,
const uint32_t* regs, uint32_t size) {
return X502_BfMemWrite(hnd, addr, regs, size);
}
LPCIE_EXPORT(int32_t) L502_BfExecCmd(t_l502_hnd hnd, uint16_t cmd_code, uint32_t par,
const uint32_t* snd_data, uint32_t snd_size,
uint32_t* rcv_data, uint32_t rcv_size, uint32_t tout, uint32_t* recvd_size) {
return X502_BfExecCmd(hnd, cmd_code, par, snd_data, snd_size, rcv_data, rcv_size,
tout, recvd_size);
}
LPCIE_EXPORT(int32_t) L502_FlashRead(t_l502_hnd hnd, uint32_t addr, uint8_t* data,
uint32_t size) {
return X502_FlashRead(hnd, addr, data, size);
}
LPCIE_EXPORT(int32_t) L502_FlashWrite(t_l502_hnd hnd, uint32_t addr,
const uint8_t* data, uint32_t size) {
return X502_FlashWrite(hnd, addr, data, size);
}
LPCIE_EXPORT(int32_t) L502_FlashErase(t_l502_hnd hnd, uint32_t addr, uint32_t size) {
return X502_FlashErase(hnd, addr, size);
}
LPCIE_EXPORT(int32_t) L502_FlashWriteEnable(t_l502_hnd hnd) {
return X502_FlashWriteEnable(hnd);
}
LPCIE_EXPORT(int32_t) L502_FlashWriteDisable(t_l502_hnd hnd) {
return X502_FlashWriteDisable(hnd);
}
LPCIE_EXPORT(uint32_t) L502_GetDllVersion(void) {
return X502_GetLibraryVersion();
}
LPCIE_EXPORT(const char*) L502_GetErrorString(int32_t err) {
return X502_GetErrorString(err);
}
LPCIE_EXPORT(int32_t) L502_LedBlink(t_l502_hnd hnd) {
return X502_LedBlink(hnd);
}
LPCIE_EXPORT(int32_t) L502_SetDigInPullup(t_l502_hnd hnd, uint32_t pullups) {
return X502_SetDigInPullup(hnd, pullups);
}
LPCIE_EXPORT(int32_t) L502_FpgaRegWrite(t_l502_hnd hnd, uint32_t reg, uint32_t val) {
return X502_FpgaRegWrite(hnd, reg, val);
}
LPCIE_EXPORT(int32_t) L502_FpgaRegRead(t_l502_hnd hnd, uint32_t reg, uint32_t *val) {
return X502_FpgaRegRead(hnd, reg, val);
}
LPCIE_EXPORT(int32_t) L502_ReloadDevInfo(t_l502_hnd hnd) {
return X502_ReloadDevInfo(hnd, 0);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,171 @@
#include "l502api_private.h"
#include "ltimer.h"
#include "l502_fpga_regs.h"
#define L502_EEPROM_BIG_SECTOR_SIZE (64*1024)
#define L502_EEPROM_SMALL_SECTOR_SIZE (4*1024)
#define L502_FLASH_WRITE_TOUT 500
#define L502_FLASH_ERASE_TOUT 500
/** биты регистра статуса */
typedef enum {
SST25_STATUS_BUSY = 0x01,
SST25_STATUS_WEL = 0x02,
SST25_STATUS_BP0 = 0x04,
SST25_STATUS_BP1 = 0x08,
SST25_STATUS_BP2 = 0x10,
SST25_STATUS_BP3 = 0x20,
SST25_STATUS_AAI = 0x40,
SST25_STATUS_BPL = 0x80
} t_sst25_status_bits;
static uint8_t f_prot_bits[] = {
SST25_STATUS_BP2 | SST25_STATUS_BP1 | SST25_STATUS_BP0,
SST25_STATUS_BP2 | SST25_STATUS_BP0,
SST25_STATUS_BP2,
SST25_STATUS_BP0,
0
};
static LINLINE int32_t f_eeprom_rd_status(t_x502_hnd hnd, uint8_t* stat) {
uint32_t val;
int32_t err = l502_port_fpga_reg_read(hnd, L502_REGS_EEPROM_RD_STATUS, &val);
if (err == X502_ERR_OK)
*stat = (val>>24)&0xFF;
return err;
}
static LINLINE int32_t f_eeprom_wr_status(t_x502_hnd hnd, uint8_t stat) {
int32_t err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_WR_STATUS_EN, 1);
if (err == X502_ERR_OK) {
err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_WR_STATUS, stat);
}
return err;
}
static int32_t f_eeprom_wr_byte(t_x502_hnd hnd, uint32_t addr, uint8_t val) {
int32_t err = X502_ERR_OK;
t_ltimer tmr;
uint8_t stat = SST25_STATUS_BUSY;
/* разрешаем запись в EEPROM */
err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_WR_EN, 1);
if (err == X502_ERR_OK) {
err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_WR_BYTE, ((addr & 0xFFFFFF) << 8) | val);
if (err != X502_ERR_OK)
l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_WR_DIS, 1);
}
if (err == X502_ERR_OK)
ltimer_set(&tmr, LTIMER_MS_TO_CLOCK_TICKS(L502_FLASH_WRITE_TOUT));
/* Ожидаем завершения записи */
while ((err == X502_ERR_OK) && (stat & SST25_STATUS_BUSY) && !ltimer_expired(&tmr)) {
err = f_eeprom_rd_status(hnd, &stat);
}
if ((err == X502_ERR_OK) && (stat & SST25_STATUS_BUSY)) {
err = X502_ERR_FLASH_WRITE_TOUT;
}
return err;
}
int32_t l502_iface_flash_rd(t_x502_hnd hnd, uint32_t addr, uint8_t* data, uint32_t size) {
int32_t err = X502_ERR_OK;
uint32_t val;
err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_SET_RD_ADDR, (addr & 0xFFFFFF) << 8);
if (err == X502_ERR_OK)
err = l502_port_fpga_reg_read(hnd, L502_REGS_EEPROM_RD_DWORD, &val);
if (err == X502_ERR_OK) {
unsigned int i;
for (i=0; (i < sizeof(val)) && size; i++, size--) {
*data++ = val & 0xFF;
val >>= 8;
}
}
return err;
}
int32_t l502_iface_flash_wr(t_x502_hnd hnd, uint32_t addr, const uint8_t* data, uint32_t size) {
uint32_t i;
int32_t err = X502_ERR_OK;
for (i=0; (i < size) && (err == X502_ERR_OK); i++) {
err = f_eeprom_wr_byte(hnd, addr+i, data[i]);
}
return err;
}
int32_t l502_iface_flash_erase(t_x502_hnd hnd, uint32_t addr, uint32_t size) {
int32_t err = X502_ERR_OK;
if (((addr & (L502_EEPROM_SMALL_SECTOR_SIZE-1)) ||
(size & (L502_EEPROM_SMALL_SECTOR_SIZE-1)))) {
err = X502_ERR_FLASH_SECTOR_BOUNDARY;
}
while((size != 0) && (err == X502_ERR_OK)) {
uint32_t er_size;
/* разрешаем запись в EEPROM */
err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_WR_EN, 1);
if (err == X502_ERR_OK) {
uint8_t stat = SST25_STATUS_BUSY;
t_ltimer tmr;
/* проверяем - можем ли стереть целиком большой сектор или
придется писать в мелкий */
if ((size >= L502_EEPROM_BIG_SECTOR_SIZE) &&
!(size & (L502_EEPROM_BIG_SECTOR_SIZE-1))) {
er_size = L502_EEPROM_BIG_SECTOR_SIZE;
err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_ERASE_64K, addr<<8);
} else {
er_size = L502_EEPROM_SMALL_SECTOR_SIZE;
err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_ERASE_4K, addr<<8);
}
if (err == X502_ERR_OK)
ltimer_set(&tmr, LTIMER_MS_TO_CLOCK_TICKS(L502_FLASH_ERASE_TOUT));
/* ожидаем завершения стирания */
while ((err == X502_ERR_OK) && (stat & SST25_STATUS_BUSY) && !ltimer_expired(&tmr)) {
err = f_eeprom_rd_status(hnd, &stat);
}
if ((err == X502_ERR_OK) && (stat & SST25_STATUS_BUSY)) {
err = X502_ERR_FLASH_ERASE_TOUT;
}
/* запрещаем запись, если произошла ошибка. при успешном стирании
запись будут запрещена атоматически */
if (err != X502_ERR_OK)
l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_WR_EN, 0);
if (err == X502_ERR_OK) {
addr += er_size;
size -= er_size;
}
}
}
return err;
}
int32_t l502_iface_flash_set_prot(t_x502_hnd hnd, uint32_t prot, const uint8_t* prot_data, uint32_t size) {
int32_t err = X502_ERR_OK;
uint16_t prot_code = 0;
if (size == 2) {
prot_code = ((uint16_t)prot_data[1] << 8) | prot_data[0];
}
err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_WR_STATUS_EN, 1);
if ((err == X502_ERR_OK) && (prot_code != 0))
err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_HARD_WR_STATUS_EN, prot_code);
if (err == X502_ERR_OK)
err = l502_port_fpga_reg_write(hnd, L502_REGS_EEPROM_WR_STATUS, f_prot_bits[prot]);
return err;
}

View File

@ -0,0 +1,54 @@
#ifndef L502API_PRIVATE_H
#define L502API_PRIVATE_H
#include "x502api_private.h"
#include "lpcie_ioctls.h"
#define L502_DEVICE_NAME "L502"
typedef struct {
#ifdef _WIN32
HANDLE file;
#else
int file;
#endif
} t_pci_iface_data;
#define L502_PCI_IFACE_FILE(hnd) (((t_pci_iface_data*)hnd->iface_data)->file)
int32_t l502_port_fpga_reg_write(t_x502_hnd hnd, uint32_t reg, uint32_t val);
int32_t l502_port_fpga_reg_read(t_x502_hnd hnd, uint32_t reg, uint32_t *val);
int32_t l502_port_open(t_x502_hnd hnd, const t_x502_devrec *devrec);
int32_t l502_port_free_iface_data(void *intptr);
int32_t l502_port_close(t_x502_hnd hnd);
int32_t l502_port_stream_start(t_x502_hnd hnd, uint32_t ch, uint32_t single);
int32_t l502_port_stream_stop(t_x502_hnd hnd, uint32_t ch, uint32_t flags);
int32_t l502_port_stream_free(t_x502_hnd hnd, uint32_t ch, uint32_t flags);
int32_t l502_port_stream_read(t_x502_hnd hnd, uint32_t *buff, uint32_t size, uint32_t timeout);
int32_t l502_port_stream_write(t_x502_hnd hnd, const uint32_t *buff, uint32_t size,
uint32_t timeout);
int32_t l502_port_stream_set_params(t_x502_hnd hnd, t_lpcie_stream_ch_params *par);
int32_t l502_port_stream_rdy_size(t_x502_hnd hnd, uint32_t ch, uint32_t *rdy_size);
int32_t l502_port_renew_info(t_x502_hnd hnd);
int32_t l502_port_get_drv_ver(t_x502_hnd hnd, uint32_t *ver);
int32_t l502_port_cycle_load_start(t_x502_hnd hnd, uint32_t ch, uint32_t size, uint32_t min_irq_step);
int32_t l502_port_cycle_setup(t_x502_hnd hnd, uint32_t ch, uint32_t evt);
int32_t l502_port_cycle_stop(t_x502_hnd hnd, uint32_t ch, uint32_t evt);
int32_t l502_port_cycle_check_setup(t_x502_hnd hnd, uint32_t ch, uint32_t *done);
int32_t l502_iface_flash_rd(t_x502_hnd hnd, uint32_t addr, uint8_t* data, uint32_t size);
int32_t l502_iface_flash_wr(t_x502_hnd hnd, uint32_t addr, const uint8_t* data, uint32_t size);
int32_t l502_iface_flash_erase(t_x502_hnd hnd, uint32_t addr, uint32_t size);
int32_t l502_iface_flash_set_prot(t_x502_hnd hnd, uint32_t prot, const uint8_t* prot_data, uint32_t size);
int32_t l502_iface_bf_mem_block_rd(t_x502_hnd hnd, uint32_t addr, uint32_t *block, uint32_t size);
int32_t l502_iface_bf_mem_block_wr(t_x502_hnd hnd, uint32_t addr, const uint32_t *block, uint32_t size);
int32_t l502_iface_bf_firm_load(t_x502_hnd hnd, const char *filename);
int32_t l502_devlist_gen(t_x502_devrec *info, void *iface_data);
#endif // L502API_PRIVATE_H

View File

@ -0,0 +1,78 @@
#ifndef LPCIE_IOCTLS_H
#define LPCIE_IOCTLS_H
#include "linux/ioctl.h"
#include "linux/types.h"
#define L502_BF_IO_SIZE 8
#define LPCIE_DEVNAME_SIZE 32
#define LPCIE_SERIAL_SIZE 32
#define LPCIE_SOFTVER_SIZE 32
#define LPCIE_REVISION_SIZE 16
#define LPCIE_MODIFICATION_SIZE 16
#define LPCIE_SPECINFO_SIZE 64
/** Информация о модуле */
typedef struct
{
char Name[LPCIE_DEVNAME_SIZE]; /**< название модуля ("L-502") */
char Serial[LPCIE_SERIAL_SIZE]; /**< серийный номер изделия */
char SoftVer[LPCIE_SOFTVER_SIZE]; /**< версия ПО контроллера */
char Revision[LPCIE_REVISION_SIZE]; /**< ревизия платы */
char Modification[LPCIE_MODIFICATION_SIZE]; /**< опции */
char SpecInfo[LPCIE_SPECINFO_SIZE]; /**< резервная информация */
} t_lpcie_devinfo;
typedef struct
{
__u32 addr;
__u32 val;
} t_lpcie_mem_rw;
typedef struct
{
__u32 page_size; /** размер каждой страницы */
__u32 irq_step; /** количество отсчетов, после которого генерится прерывание */
__u16 pages_cnt; /** количество страниц */
__u16 packet_size; /** размер пакета по PCI-Express */
} t_lpcie_dma_params;
typedef struct
{
uint32_t addr;
uint32_t reserv;
uint32_t buf[L502_BF_IO_SIZE];
} t_l502_bf_rw;
#define LPCIE_IO_MAGIC 'L'
#define LPCIE_IOCTL_GET_DEVINFO _IOR(LPCIE_IO_MAGIC, 0x80, t_lpcie_devinfo)
#define LPCIE_IOCTL_TIMER_START _IOW(LPCIE_IO_MAGIC, 0x81, __u32)
#define LPCIE_IOCTL_TIMER_STOP _IO(LPCIE_IO_MAGIC, 0x82)
#define LPCIE_IOCTL_READ_CFG _IOWR(LPCIE_IO_MAGIC, 0x83, __u32)
#define LPCIE_IOCTL_MEM_FPGA_RD _IOWR(LPCIE_IO_MAGIC, 0x86, t_lpcie_mem_rw)
#define LPCIE_IOCTL_MEM_FPGA_WR _IOW(LPCIE_IO_MAGIC, 0x87, t_lpcie_mem_rw)
#define LPCIE_IOCTL_MEM_BLOCK_RD _IOWR(LPCIE_IO_MAGIC, 0x86, t_lpcie_mem_rw)
#define LPCIE_IOCTL_ADC_START _IO(LPCIE_IO_MAGIC, 0x90)
#define LPCIE_IOCTL_ADC_STOP _IO(LPCIE_IO_MAGIC, 0x91)
#define LPCIE_IOCTL_DAC_START _IO(LPCIE_IO_MAGIC, 0x92)
#define LPCIE_IOCTL_DAC_STOP _IO(LPCIE_IO_MAGIC, 0x93)
#define LPCIE_IOCTL_SET_ADC_DMA_PAR _IOW(LPCIE_IO_MAGIC, 0x94, t_lpcie_dma_params)
#define LPCIE_IOCTL_SET_DAC_DMA_PAR _IOW(LPCIE_IO_MAGIC, 0x95, t_lpcie_dma_params)
#define LPCIE_IOCTL_DAC_RST_BUFS _IO(LPCIE_IO_MAGIC, 0x96)
#define LPCIE_IOCTL_ADC_GET_RDY _IOR(LPCIE_IO_MAGIC, 0x97, __u32)
#define LPCIE_IOCTL_DAC_GET_FREE _IOR(LPCIE_IO_MAGIC, 0x98, __u32)
#define LPCIE_IOCTL_DAC_SET_CYCLE_BUF _IOW(LPCIE_IO_MAGIC, 0x99, __u32)
#define LPCIE_IOCTL_DAC_SET_CYCLE_DATA _IOW(LPCIE_IO_MAGIC, 0x9A, __u32)
#define LPCIE_IOCTL_BF_RD _IOR(LPCIE_IO_MAGIC, 0xA0, t_l502_bf_rw)
#define LPCIE_IOCTL_BF_WR _IOW(LPCIE_IO_MAGIC, 0xA0, t_l502_bf_rw)
#define LPCIE_IOCTL_BF_HOST_IRQ _IO(LPCIE_IO_MAGIC, 0xA1)
#endif // LPCIE_IOCTLS_H

View File

@ -0,0 +1,369 @@
#include "../l502api_private.h"
#include "../lpcie_ioctls.h"
#include <sys/ioctl.h>
#include <linux/ioctl.h>
#include <linux/types.h>
#include <stdlib.h>
#include <dirent.h>
#include <libgen.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#define LPCIE_CLASS_DIR "/sys/class/lpcie"
static int32_t f_ioctl(int fd, unsigned long int req, void* val) {
return ioctl(fd, req, val) ? X502_ERR_IOCTL_FAILD : X502_ERR_OK;
}
int32_t l502_port_fpga_reg_write(t_x502_hnd hnd, uint32_t reg, uint32_t val) {
t_lpcie_mem_rw mem_wr = {reg,val};
return f_ioctl(L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_MEMFPGA_WR, &mem_wr);
}
int32_t l502_port_fpga_reg_read(t_x502_hnd hnd, uint32_t reg, uint32_t *val) {
t_lpcie_mem_rw mem_wr = {reg,0};
int32_t err = f_ioctl (L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_MEMFPGA_RD, &mem_wr);
if ((err == X502_ERR_OK) && (val != NULL))
*val = mem_wr.val;
return err;
}
int32_t l502_port_stream_set_params(t_x502_hnd hnd, t_lpcie_stream_ch_params *par) {
return f_ioctl(L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_STREAM_SET_PARAMS, par);
}
int32_t l502_port_stream_start(t_x502_hnd hnd, uint32_t ch, uint32_t single) {
return f_ioctl(L502_PCI_IFACE_FILE(hnd), single ? LPCIE_IOCTL_STREAM_START_SINGLE :
LPCIE_IOCTL_STREAM_START, &ch);
}
int32_t l502_port_stream_stop(t_x502_hnd hnd, uint32_t ch, uint32_t flags) {
return f_ioctl(L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_STREAM_STOP, &ch);
}
int32_t l502_port_stream_free(t_x502_hnd hnd, uint32_t ch, uint32_t flags) {
return f_ioctl(L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_STREAM_FREE, &ch);
}
int32_t l502_port_stream_rdy_size(t_x502_hnd hnd, uint32_t ch, uint32_t *rdy_size) {
t_lpcie_get_rdy_par rdy_par = {ch,0};
int32_t err = f_ioctl (L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_STREAM_GET_RDY_SIZE, &rdy_par);
if ((err == X502_ERR_OK) && (rdy_size != NULL))
*rdy_size = rdy_par.rdy_size;
return err;
}
int32_t l502_port_cycle_load_start(t_x502_hnd hnd, uint32_t ch, uint32_t size, uint32_t min_irq_step) {
t_lpcie_cycle_set_par par;
memset(&par, 0, sizeof(par));
par.ch = ch;
par.size = size;
par.irq_step = min_irq_step;
return f_ioctl (L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_CYCLE_LOAD, &par);
}
int32_t l502_port_cycle_setup(t_x502_hnd hnd, uint32_t ch, uint32_t evt) {
t_lpcie_cycle_evt_par par;
memset(&par, 0, sizeof(par));
par.ch = ch;
par.evt = evt;
return f_ioctl (L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_CYCLE_SWITCH, &par);
}
int32_t l502_port_cycle_stop(t_x502_hnd hnd, uint32_t ch, uint32_t evt) {
t_lpcie_cycle_evt_par par;
memset(&par, 0, sizeof(par));
par.ch = ch;
par.evt = evt;
return f_ioctl (L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_CYCLE_STOP, &par);
}
int32_t l502_port_cycle_check_setup(t_x502_hnd hnd, uint32_t ch, uint32_t *done) {
t_lpcie_cycle_check_setup_par par;
int32_t err;
memset(&par, 0, sizeof(par));
par.ch = ch;
err = f_ioctl(L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_CYCLE_CHECK_SETUP, &par);
if (err == X502_ERR_OK)
*done = par.done;
return err;
}
int32_t l502_port_renew_info(t_x502_hnd hnd) {
return f_ioctl(L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_RELOAD_DEVINFO, NULL);
}
int32_t l502_port_get_drv_ver(t_x502_hnd hnd, uint32_t *ver) {
return f_ioctl(L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_GET_DRV_VERSION, ver);
}
int32_t l502_port_stream_read(t_x502_hnd hnd, uint32_t *buff, uint32_t size, uint32_t timeout) {
struct timeval tmval = {timeout/1000, (timeout%1000)*1000};
uint32_t rcv_size = 0;
int out = 0;
int32_t err = X502_ERR_OK;
while (!out && (err == X502_ERR_OK) && (rcv_size < size)) {
fd_set rd_set;
int sel = 0;
FD_ZERO(&rd_set);
FD_SET(L502_PCI_IFACE_FILE(hnd), &rd_set);
sel = select(L502_PCI_IFACE_FILE(hnd)+1, &rd_set, NULL, NULL, &tmval);
if ((sel > 0) && (FD_ISSET(L502_PCI_IFACE_FILE(hnd), &rd_set))) {
ssize_t rd = read(L502_PCI_IFACE_FILE(hnd), &buff[rcv_size], (size-rcv_size)*4);
if (rd>0) {
rcv_size += rd/4;
} else if (rd == 0) {
out = 1;
} else {
err = X502_ERR_RECV;
}
} else if (sel==0) {
out = 1;
} else {
err = X502_ERR_RECV;
}
}
return err != X502_ERR_OK ? err : (int32_t)rcv_size;
}
int32_t l502_port_stream_write(t_x502_hnd hnd, const uint32_t *buff, uint32_t size,
uint32_t timeout) {
struct timeval tmval = {timeout/1000, (timeout%1000)*1000};
uint32_t snd_size = 0;
int32_t err = X502_ERR_OK;
int out = 0;
while (!out && (err == X502_ERR_OK) && (snd_size < size)) {
fd_set wr_set;
int sel = 0;
FD_ZERO(&wr_set);
FD_SET(L502_PCI_IFACE_FILE(hnd), &wr_set);
sel = select(L502_PCI_IFACE_FILE(hnd)+1, NULL, &wr_set, NULL, &tmval);
if ((sel > 0) && (FD_ISSET(L502_PCI_IFACE_FILE(hnd), &wr_set))) {
ssize_t wr = write(L502_PCI_IFACE_FILE(hnd), &buff[snd_size], (size-snd_size)*4);
if (wr > 0) {
snd_size += wr/4;
} else if (wr==0) {
out = 1;
} else {
err = X502_ERR_SEND;
}
} else if (sel==0) {
out = 1;
} else {
err = X502_ERR_SEND;
}
}
return err != X502_ERR_OK ? err : (int32_t)snd_size;
}
static int32_t f_get_file_par(const char *path, char *filebuf,
const char *file, char *res, uint32_t req_size,
uint32_t *read_size) {
int f;
int32_t err = X502_ERR_OK;
strcpy(filebuf, path);
strcat(filebuf, file);
f = open (filebuf, O_RDONLY);
if (f == -1) {
err = X502_ERR_GET_INFO;
} else {
ssize_t rd = read(f, res, req_size);
if (rd < 0) {
err = X502_ERR_GET_INFO;
} else {
if (read_size!=NULL)
*read_size = rd;
}
close(f);
}
return err;
}
static void f_del_eol(char *str) {
for ( ; *str; str++) {
if ((*str=='\n') || (*str=='\r'))
*str = '\0';
}
}
static int32_t f_fill_devlist(const char *devname, t_x502_devrec *info) {
int32_t err = 0;
int path_len = strlen(devname) + strlen(LPCIE_CLASS_DIR) + 2;
char *filename = malloc(path_len + 21);
char *path = malloc(path_len);
if ((filename != NULL) && (path != NULL)) {
sprintf(path, LPCIE_CLASS_DIR "/%s", devname);
err = f_get_file_par(path, filename, "/name", info->devname,
sizeof(info->devname), NULL);
if (err == X502_ERR_OK)
f_del_eol(info->devname);
if (err == X502_ERR_OK) {
/* получаем серийный номер устройства */
err = f_get_file_par(path, filename, "/sn", info->serial,
sizeof(info->serial), NULL);
if (err == X502_ERR_OK)
f_del_eol(info->serial);
}
/* получаем информацию, открыто ли устройство */
if (err == X502_ERR_OK) {
char val = '0';
err = f_get_file_par(path, filename, "/opened", &val, 1, NULL);
if ((err == X502_ERR_OK) && (val!='0'))
info->flags |= X502_DEVFLAGS_DEVREC_OPENED;
}
/* получаем информацию, присутствует ли BlackFin */
if (err == X502_ERR_OK) {
char val = '0';
if ((f_get_file_par(path, filename, "/bf", &val, 1, NULL) == X502_ERR_OK)
&& (val != '0')) {
info->flags |= X502_DEVFLAGS_BF_PRESENT;
}
if ((f_get_file_par(path, filename, "/dac", &val, 1, NULL) == X502_ERR_OK)
&& (val != '0')) {
info->flags |= X502_DEVFLAGS_DAC_PRESENT;
}
if ((f_get_file_par(path, filename, "/gal", &val, 1, NULL) == X502_ERR_OK)
&& (val != '0')) {
info->flags |= X502_DEVFLAGS_GAL_PRESENT;
}
}
if (err == X502_ERR_OK) {
char *devname_cpy = malloc(strlen(devname)+1);
if (devname_cpy!=NULL) {
strcpy(devname_cpy, devname);
err = l502_devlist_gen(info, devname_cpy);
if (err != X502_ERR_OK) {
free(devname_cpy);
}
} else {
err = X502_ERR_MEMORY_ALLOC;
}
}
} else {
err = X502_ERR_MEMORY_ALLOC;
}
free(filename);
free(path);
return err;
}
int32_t l502_port_free_iface_data(void *intptr) {
free(intptr);
return X502_ERR_OK;
}
int32_t l502_port_open(t_x502_hnd hnd, const t_x502_devrec *devinfo) {
const char *devname = (const char *)devinfo->internal->iface_data;
int32_t err = X502_ERR_OK;
int path_len = strlen(devname)+6;
char *path = malloc(path_len);
if (path != NULL) {
int file;
snprintf(path, path_len, "/dev/%s", devname);
file = open(path, O_RDWR);
if (file != -1) {
hnd->iface_data = malloc(sizeof(t_pci_iface_data));
if (hnd->iface_data == NULL) {
err = X502_ERR_MEMORY_ALLOC;
close(file);
} else {
L502_PCI_IFACE_FILE(hnd) = file;
}
} else {
/** @todo Разобрать коды ошибок */
err = X502_ERR_DEVICE_OPEN;
}
free(path);
} else {
err = X502_ERR_MEMORY_ALLOC;
}
return err;
}
int32_t l502_port_close(t_x502_hnd hnd) {
if (hnd->iface_data !=NULL) {
close(L502_PCI_IFACE_FILE(hnd));
free(hnd->iface_data);
hnd->iface_data = NULL;
}
return X502_ERR_OK;
}
X502_EXPORT(int32_t) L502_GetDevRecordsList(t_x502_devrec *list, uint32_t size,
uint32_t flags, uint32_t *devcnt) {
uint32_t curcnt = 0;
int32_t err = X502_ERR_OK;
/* все устройства, поддерживаемые драйвером LPCIE, создают папку
в директории класса устройств lpcie*/
DIR *class_dir = opendir(LPCIE_CLASS_DIR);
if (class_dir!=NULL) {
struct dirent *dev_ent;
/* читаем все записи в директории класса */
while ((dev_ent=readdir(class_dir))!=NULL) {
/* проверяем, что имя начинается с lpcie */
if (!memcmp(dev_ent->d_name, "lpcie", sizeof("lpcie")-1)) {
t_x502_devrec info;
int info_used = 0;
X502_DevRecordInit(&info);
/* получаем информацию о устройстве из служебных файлов,
* предоставляемых драйвером */
if (f_fill_devlist(dev_ent->d_name, &info) == X502_ERR_OK) {
/* если нужны только не открытые, то уже открытое
* устройство пропускаем */
if (!(flags & X502_GETDEVS_FLAGS_ONLY_NOT_OPENED) ||
!(info.flags & X502_DEVFLAGS_DEVREC_OPENED)) {
/* если есть место в списке - то сохраняем
* полученную информацию */
if ((list!=NULL) && (curcnt < size)) {
list[curcnt] = info;
info_used = 1;
}
curcnt++;
}
}
if (!info_used)
X502_FreeDevRecordList(&info,1);
}
}
closedir(class_dir);
}
if (devcnt != NULL)
*devcnt = curcnt;
return err != X502_ERR_OK ? err : curcnt > size ? (int32_t)size : (int32_t)curcnt ;
}

View File

@ -0,0 +1,144 @@
/***************************************************************************//**
* @file lpcie_ioctls.h
* Файл содержит определения управляющих запросов драйвера lpcie и типов данных,
* используемых для передачи параметров управляющих запросов
* @author Borisov Alexey <borisov@lcard.ru>
* @date 23.05.2012
* ****************************************************************************/
#ifndef LPCIE_IOCTLS_H
#define LPCIE_IOCTLS_H
/** Проверка по версии дарайвера, поддерживается ли запрос LPCIE_IOCTL_CYCLE_CHECK_SETUP */
#define LPCIE_IOCTL_SUPPORT_CYCLE_CHECK_SETUP(ver) (ver >= 0x01000900)
/** Варианты событий, по которым должно произойти переключение
циклического сигнала */
typedef enum {
LPCIE_CYCLE_SW_EVT_IMMIDIATLY = 1, /**< сразу по получению команды */
LPCIE_CYCLE_SW_EVT_END_OF_CYCLE = 2 /**< по завершению текущего цикла */
} t_lpcie_cycle_sw_evt;
/** параметры для записи значения регистра */
typedef struct {
uint32_t addr; /** Адрес регистра */
uint32_t val; /** Значение регистра */
} t_lpcie_mem_rw;
/** настройки канала DMA, передаваемые вместе с LPCIE_IOCTL_STREAM_SET_PARAMS */
typedef struct {
uint32_t ch; /** канал DMA (ввод/вывод) */
uint32_t res[2]; /** резерв */
uint32_t buf_size; /** размер каждой страницы памяти в PC */
uint32_t irq_step; /** через сколько переданных отсчетов будет
генерироваться прерывание */
uint32_t res2[3];
} t_lpcie_stream_ch_params;
/** параметры для установки циклического сигнала */
typedef struct {
uint32_t ch; /** канал DMA (доступно только на вывод) */
uint32_t size; /** количество отсчетов в циклическом сигнале */
uint32_t irq_step; /** шаг генерации прерываний */
uint32_t res; /** резерв */
} t_lpcie_cycle_set_par;
/** параметры для остановки/смены циклического сигнала */
typedef struct {
uint32_t ch; /** канал DMA (доступно только на вывод) */
uint32_t evt; /** событие для смены сигнала из #t_lpcie_cycle_sw_evt */
uint32_t res[2]; /** резерв */
} t_lpcie_cycle_evt_par;
/** параметры для запроса LPCIE_IOCTL_CYCLE_CHECK_SETUP */
typedef struct {
uint32_t ch; /** канал DMA (доступно только на вывод) */
uint32_t done; /** признак, завершена ли установка циклического сигнала */
} t_lpcie_cycle_check_setup_par;
/** параметры запроса для получения количества готовых для ввода или вывода
отсчетов */
typedef struct {
uint32_t ch; /** канал DMA (ввод/вывод) */
uint32_t rdy_size; /** Количество отсчетов доступных на ввод или вывод */
} t_lpcie_get_rdy_par;
#ifdef _WIN32
#define LPCIE_IOCTL_GET_DRV_VERSION \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED , FILE_ANY_ACCESS)
#define LPCIE_IOCTL_MEMFPGA_RD \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x810, METHOD_BUFFERED , FILE_ANY_ACCESS)
#define LPCIE_IOCTL_MEMFPGA_WR \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x811, METHOD_BUFFERED , FILE_ANY_ACCESS)
#define LPCIE_IOCTL_POWER_DONW \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x820, METHOD_BUFFERED , FILE_ANY_ACCESS)
#define LPCIE_IOCTL_RELOAD_DEVINFO \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x821, METHOD_BUFFERED , FILE_ANY_ACCESS)
#define LPCIE_IOCTL_STREAM_SET_PARAMS \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x840, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define LPCIE_IOCTL_STREAM_GET_PARAMS \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x841, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define LPCIE_IOCTL_STREAM_GET_RDY_SIZE \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x842, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define LPCIE_IOCTL_STREAM_START \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x844, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define LPCIE_IOCTL_STREAM_STOP \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x845, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define LPCIE_IOCTL_STREAM_FREE \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x846, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define LPCIE_IOCTL_STREAM_START_SINGLE \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x847, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define LPCIE_IOCTL_CYCLE_LOAD \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x850, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define LPCIE_IOCTL_CYCLE_SWITCH \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x851, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define LPCIE_IOCTL_CYCLE_STOP \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x852, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define LPCIE_IOCTL_CYCLE_CHECK_SETUP \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x853, METHOD_BUFFERED, FILE_ANY_ACCESS)
#else
#define LPCIE_IO_MAGIC 'L'
#define LPCIE_IOCTL_GET_DRV_VERSION _IOR(LPCIE_IO_MAGIC, 0x800, uint32_t)
#define LPCIE_IOCTL_MEMFPGA_RD _IOWR(LPCIE_IO_MAGIC, 0x810, t_lpcie_mem_rw)
#define LPCIE_IOCTL_MEMFPGA_WR _IOW(LPCIE_IO_MAGIC, 0x811, t_lpcie_mem_rw)
#define LPCIE_IOCTL_POWER_DONW _IO(LPCIE_IO_MAGIC, 0x820)
#define LPCIE_IOCTL_RELOAD_DEVINFO _IO(LPCIE_IO_MAGIC, 0x821)
#define LPCIE_IOCTL_STREAM_SET_PARAMS _IOW(LPCIE_IO_MAGIC, 0x840, t_lpcie_stream_ch_params)
#define LPCIE_IOCTL_STREAM_GET_PARAMS _IOWR(LPCIE_IO_MAGIC, 0x841, t_lpcie_stream_ch_params)
#define LPCIE_IOCTL_STREAM_GET_RDY_SIZE _IOWR(LPCIE_IO_MAGIC, 0x842, t_lpcie_get_rdy_par)
#define LPCIE_IOCTL_STREAM_START _IOW(LPCIE_IO_MAGIC, 0x844, uint32_t)
#define LPCIE_IOCTL_STREAM_STOP _IOW(LPCIE_IO_MAGIC, 0x845, uint32_t)
#define LPCIE_IOCTL_STREAM_FREE _IOW(LPCIE_IO_MAGIC, 0x846, uint32_t)
#define LPCIE_IOCTL_STREAM_START_SINGLE _IOW(LPCIE_IO_MAGIC, 0x847, uint32_t)
#define LPCIE_IOCTL_CYCLE_LOAD _IOW(LPCIE_IO_MAGIC, 0x850, t_lpcie_cycle_set_par)
#define LPCIE_IOCTL_CYCLE_SWITCH _IOW(LPCIE_IO_MAGIC, 0x851, t_lpcie_cycle_evt_par)
#define LPCIE_IOCTL_CYCLE_STOP _IOW(LPCIE_IO_MAGIC, 0x852, t_lpcie_cycle_evt_par)
#define LPCIE_IOCTL_CYCLE_CHECK_SETUP _IOWR(LPCIE_IO_MAGIC, 0x853, t_lpcie_cycle_check_setup_par)
#endif
#endif // LPCIE_IOCTLS_H

View File

@ -0,0 +1,805 @@
unit l502api;
interface
uses Windows, SysUtils, x502api;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function L502_GetSerialList(out serials: array of string; flags: LongWord; out devcnt: LongWord) : LongInt; overload;
function L502_GetSerialList(out serials: array of string; flags: LongWord) : LongInt; overload;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function L502_Open(hnd: t_x502_hnd; serial: string): LongInt; stdcall;
function L502_GetDevRecordsList(out list: array of t_x502_devrec; flags : LongWord; out devcnt: LongWord) : LongInt; overload;
function L502_GetDevRecordsList(out list: array of t_x502_devrec; flags : LongWord) : LongInt; overload;
{ ----------- <20><><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ----------}
const
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_LTABLE_MAX_CH_CNT = 256;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ADC_RANGE_CNT = 6;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_LCH_AVG_SIZE_MAX = 128;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
L502_ADC_FREQ_DIV_MAX = (1024*1024);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
L502_DIN_FREQ_DIV_MAX = (1024*1024);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD>
L502_ADC_INTERFRAME_DELAY_MAX = $1FFFFF;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> BlackFin
L502_BF_CMD_DEFAULT_TOUT = 500;
// <20><><EFBFBD> <20><><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
L502_ADC_SCALE_CODE_MAX = 6000000;
// <20><><EFBFBD> <20><><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
L502_DAC_SCALE_CODE_MAX = 30000;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_DEVNAME_SIZE = X502_DEVNAME_SIZE;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_SERIAL_SIZE = X502_SERIAL_SIZE;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Flash-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_FLASH_USER_SIZE = $100000;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> BlackFin <20> <20><>
L502_BF_REQ_TOUT = 500;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_DAC_RANGE = 5;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
L502_DAC_CH_CNT = 2;
// <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_STREAM_IN_MSG_OVERFLOW = $01010000;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_EXT_REF_FREQ_MAX = 2000000;
{ ----------------- <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ---------------------------}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_OK = 0;
// <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_INVALID_HANDLE = -1;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_MEMORY_ALLOC = -2;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_ALREADY_OPENED = -3;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_DEVICE_NOT_FOUND = -4;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>-<2D><> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
L502_ERR_DEVICE_ACCESS_DENIED = -5;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_DEVICE_OPEN = -6;
// <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_INVALID_POINTER = -7;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_STREAM_IS_RUNNING = -8;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_RECV = -9;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_SEND = -10;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_STREAM_OVERFLOW = -11;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_UNSUP_STREAM_MSG = -12;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_MUTEX_CREATE = -13;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_MUTEX_INVALID_HANDLE = -14;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_MUTEX_LOCK_TOUT = -15;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_MUTEX_RELEASE = -16;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_INSUFFICIENT_SYSTEM_RESOURCES= -17;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_NOT_IMPLEMENTED = -18;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_INSUFFICIENT_ARRAY_SIZE = -19;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> FPGA
L502_ERR_FPGA_REG_READ = -20;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> FPGA
L502_ERR_FPGA_REG_WRITE = -21;
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_STREAM_IS_NOT_RUNNING = -22;
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_INVALID_LTABLE_SIZE = -102;
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_INVALID_LCH_NUMBER = -103;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
L502_ERR_INVALID_LCH_RANGE = -104;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_INVALID_LCH_MODE = -105;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_INVALID_LCH_PHY_NUMBER = -106;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_INVALID_LCH_AVG_SIZE = -107;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
L502_ERR_INVALID_ADC_FREQ_DIV = -108;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_INVALID_DIN_FREQ_DIV = -108;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> L502
L502_ERR_INVALID_MODE = -109;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
L502_ERR_INVALID_DAC_CHANNEL = -110;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_INVALID_REF_FREQ = -111;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_INVALID_INTERFRAME_DELAY = -112;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_INVALID_SYNC_MODE = -113;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DMA
L502_ERR_INVALID_DMA_CH = -114;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_REF_FREQ_NOT_LOCKED = -131;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_IOCTL_FAILD = -132;
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_IOCTL_TIMEOUT = -133;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_GET_INFO = -134;
// <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_DIG_IN_NOT_RDY = -135;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_RECV_INSUFFICIENT_WORDS = -136;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>, <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_DAC_NOT_PRESENT = -137;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_PROC_INVALID_CH_NUM = -140;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_PROC_INVALID_CH_RANGE = -141;
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><> Flash-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_FLASH_INVALID_ADDR = -142;
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> Flash-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_FLASH_INVALID_SIZE = -143;
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> Flash-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_FLASH_WRITE_TOUT = -144;
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> Flash-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_FLASH_ERASE_TOUT = -145;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Flash-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20> 4 <20><><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_FLASH_SECTOR_BOUNDARY = -146;
// <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BlackFin
L502_ERR_LDR_FILE_OPEN = -180;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BlackFin
L502_ERR_LDR_FILE_READ = -181;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BlackFin
L502_ERR_LDR_FILE_FORMAT = -182;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> LDR-<2D><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BlackFin <20><> HDMA
L502_ERR_LDR_FILE_UNSUP_FEATURE = -183;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BlackFin
L502_ERR_LDR_FILE_UNSUP_STARTUP_ADDR = -184;
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BlackFin
L502_ERR_BF_REQ_TIMEOUT = -185;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> BlackFin <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_BF_CMD_IN_PROGRESS = -186;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BlackFin
L502_ERR_BF_CMD_TIMEOUT = -187;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> BlackFin
L502_ERR_BF_CMD_RETURN_INSUF_DATA = -188;
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BlackFin <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_BF_LOAD_RDY_TOUT = -189;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_ERR_BF_NOT_PRESENT = -190;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BlackFin <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> HDMA
L502_ERR_BF_INVALID_ADDR = -191;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> BlackFin
L502_ERR_BF_INVALID_CMD_DATA_SIZE = -192;
{-------- <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ------}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_GETDEVS_FLAGS_ONLY_NOT_OPENED = X502_GETDEVS_FLAGS_ONLY_NOT_OPENED;
{-------- <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. ---------------}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_DIGOUT_WORD_DIS_H = $00020000;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_DIGOUT_WORD_DIS_L = $00010000;
{-------- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -------------------}
L502_REF_FREQ_2000KHZ = 2000000; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2<><32><EFBFBD>
L502_REF_FREQ_1500KHZ = 1500000; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1.5<EFBFBD><EFBFBD><EFBFBD>
{-------- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> ----------------------}
L502_ADC_RANGE_10 = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> +/-10V
L502_ADC_RANGE_5 = 1; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> +/-5V
L502_ADC_RANGE_2 = 2; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> +/-2V
L502_ADC_RANGE_1 = 3; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> +/-1V
L502_ADC_RANGE_05 = 4; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> +/-0.5V
L502_ADC_RANGE_02 = 5; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> +/-0.2V
{-------- <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ------------------}
L502_LCH_MODE_COMM = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
L502_LCH_MODE_DIFF = 1; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_LCH_MODE_ZERO = 2; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
{-------- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ------------------------------------}
L502_SYNC_INTERNAL = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_SYNC_EXTERNAL_MASTER = 1; // <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_SYNC_DI_SYN1_RISE = 2; // <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DI_SYN1
L502_SYNC_DI_SYN2_RISE = 3; // <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DI_SYN2
L502_SYNC_DI_SYN1_FALL = 6; // <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DI_SYN1
L502_SYNC_DI_SYN2_FALL = 7; // <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DI_SYN2
{-------- <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -------------------}
L502_PROC_FLAGS_VOLT = 1; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{-------- <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -----------------}
L502_STREAM_ADC = $01; //<2F><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD>
L502_STREAM_DIN = $02; // <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_STREAM_DAC1 = $10; // <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
L502_STREAM_DAC2 = $20; // <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
L502_STREAM_DOUT = $40; // <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>
L502_STREAM_ALL_IN = L502_STREAM_ADC or L502_STREAM_DIN;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>
L502_STREAM_ALL_OUT = L502_STREAM_DAC1 or L502_STREAM_DAC2 or L502_STREAM_DOUT;
{--- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -----}
L502_STREAM_OUT_WORD_TYPE_DOUT = $0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
L502_STREAM_OUT_WORD_TYPE_DAC1 = $40000000; // <20><><EFBFBD> <20><><EFBFBD> 1-<2D><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
L502_STREAM_OUT_WORD_TYPE_DAC2 = $80000000; // <20><><EFBFBD> <20><><EFBFBD> 2-<2D><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
{------------------ <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> L502 ------------------------------}
L502_MODE_FPGA = 0; // <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BlackFin
L502_MODE_DSP = 1; // <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_MODE_DEBUG = 2; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
{------------------- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> -----------------------------------}
L502_DAC_CH1 = 0; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
L502_DAC_CH2 = 1; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
{----------- <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD> -----------------}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD>
L502_DAC_FLAGS_VOLT = $0001;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD>.
L502_DAC_FLAGS_CALIBR = $0002;
{------------------ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DMA ------------------------------------}
L502_DMA_CH_IN = 0; // <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> DMA <20><> <20><><EFBFBD><EFBFBD>
L502_DMA_CH_OUT = 1; // <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> DMA <20><> <20><><EFBFBD><EFBFBD><EFBFBD>
{--- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>, <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ----}
L502_PULLUPS_DI_H = $01; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_PULLUPS_DI_L = $02; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_PULLUPS_DI_SYN1 = $04; // <20><><EFBFBD><EFBFBD><EFBFBD> SYN1
L502_PULLUPS_DI_SYN2 = $08; // <20><><EFBFBD><EFBFBD><EFBFBD> SYN2
{--------------- <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ---------------}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
L502_DEVFLAGS_DAC_PRESENT = X502_DEVFLAGS_DAC_PRESENT;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BlackFin
L502_DEVFLAGS_BF_PRESENT = X502_DEVFLAGS_BF_PRESENT;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_DEVFLAGS_GAL_PRESENT = X502_DEVFLAGS_GAL_PRESENT;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><> Flash-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
L502_DEVFLAGS_FLASH_DATA_VALID = $00010000;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><> Flash-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
L502_DEVFLAGS_FLASH_ADC_CALIBR_VALID = $00020000;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><> Flash-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
L502_DEVFLAGS_FLASH_DAC_CALIBR_VALID = $00040000;
{----------------<2D><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>----------------------}
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
L502_OUT_CYCLE_FLAGS_FORCE = $01;
type
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
t_l502_hnd = t_x502_hnd;
{ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> }
t_l502_cbr_coef = record
offs: Double; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
k : Double; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
end;
{ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. }
t_l502_cbr = record
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
adc: array[0..L502_ADC_RANGE_CNT-1] of t_l502_cbr_coef;
res1: array[0..63] of LongWord;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
dac: array[0..L502_DAC_CH_CNT-1] of t_l502_cbr_coef;
res2: array[0..19] of LongWord;
end;
{ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> L502.}
t_l502_info = record
name: array[0..L502_DEVNAME_SIZE-1] of AnsiChar; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ("L502")
serial: array[0..L502_SERIAL_SIZE-1] of AnsiChar; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
devflags: LongWord; // <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
fpga_ver : Word; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
plda_ver : Byte; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
res : array[0..120] of Byte; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
cbr : t_l502_cbr; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><> Flash-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
end;
function L502_Create(): t_l502_hnd; stdcall;
function L502_Free(hnd: t_l502_hnd): LongInt; stdcall;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function L502_Close(hnd: t_l502_hnd): LongInt; stdcall;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function L502_GetDevInfo(hnd: t_l502_hnd; out info: t_l502_info) : LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function L502_Configure(hnd: t_l502_hnd; flags: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function L502_SetLChannel(hnd: t_l502_hnd; lch, phy_ch, mode, range, avg: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function L502_SetLChannelCount(hnd: t_l502_hnd; lch_cnt : LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function L502_GetLChannelCount(hnd: t_l502_hnd; out lch_cnt: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD>
function L502_SetAdcFreqDivider(hnd: t_l502_hnd; adc_freq_div : LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD>
function L502_SetAdcInterframeDelay(hnd: t_l502_hnd; delay : LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
function L502_SetDinFreqDivider(hnd: t_l502_hnd; din_freq_div: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
function L502_SetAdcFreq(hnd: t_l502_hnd; var f_acq, f_frame: Double): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function L502_SetDinFreq(hnd: t_l502_hnd; var f_din: Double): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
function L502_GetAdcFreq(hnd: t_l502_hnd; out f_acq, f_frame: Double): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_SetRefFreq(hnd: t_l502_hnd; freq: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_SetSyncMode(hnd: t_l502_hnd; sync_mode: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_SetSyncStartMode(hnd: t_l502_hnd; sync_start_mode: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function L502_SetMode(hnd: t_l502_hnd; mode: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_GetMode(hnd: t_l502_hnd; out mode: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>.
function L502_SetAdcCoef(hnd: t_l502_hnd; range: LongWord; k, offs: Double): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>.
function L502_GetAdcCoef(hnd: t_l502_hnd; range: LongWord; out k, offs: Double): LongInt; stdcall;
{----------------------- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ------------------}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>.
function L502_AsyncOutDac(hnd: t_l502_hnd; ch: LongWord; data: Double; flags: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_AsyncOutDig(hnd: t_l502_hnd; val, msk: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_AsyncInDig(hnd: t_l502_hnd; out din: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>.
function L502_AsyncGetAdcFrame(hnd: t_l502_hnd; flags: LongWord; tout: LongWord; out data: array of Double): LongInt; stdcall;
{-------------- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ----}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD>.
function L502_StreamsEnable(hnd: t_l502_hnd; streams: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD>.
function L502_StreamsDisable(hnd: t_l502_hnd; streams: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_StreamsStart(hnd: t_l502_hnd): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_StreamsStop(hnd: t_l502_hnd): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function L502_IsRunning(hnd: t_l502_hnd): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_Recv(hnd: t_l502_hnd; out buf : array of LongWord; size: LongWord; tout : LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_Send(hnd: t_l502_hnd; const buf : array of LongWord; size: LongWord; tout: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_ProcessAdcData(hnd: t_l502_hnd; const src: array of LongWord;
out dest: array of Double; var size : LongWord;
flags : LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_ProcessData(hnd: t_l502_hnd; const src: array of LongWord; size: LongWord;
flags : LongWord; out adc_data: array of Double; var adc_data_size : LongWord;
out din_data: array of LongWord; var din_data_size: LongWord):LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_ProcessDataWithUserExt(hnd: t_l502_hnd; const src: array of LongWord; size: LongWord;
flags : LongWord; out adc_data: array of Double; var adc_data_size : LongWord;
out din_data: array of LongWord; var din_data_size: LongWord;
out usr_data: array of LongWord; var usr_data_size: LongWord):LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_PrepareData(hnd: t_l502_hnd; const dac1, dac2: array of Double;
const digout: array of LongWord; size, flags : LongWord;
out out_buf: array of LongWord):LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>.
function L502_GetRecvReadyCount(hnd: t_l502_hnd; out rdy_cnt: LongWord):LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>.
function L502_GetSendReadyCount(hnd: t_l502_hnd; out rdy_cnt: LongWord):LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_GetNextExpectedLchNum(hnd: t_l502_hnd; out lch: LongWord):LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function L502_PreloadStart(hnd: t_l502_hnd): LongInt; stdcall;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>
function L502_OutCycleLoadStart(hnd: t_l502_hnd; size: LongWord):LongInt; stdcall;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>
function L502_OutCycleSetup(hnd: t_l502_hnd; flags: LongWord):LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function L502_OutCycleStop(hnd: t_l502_hnd; flags: LongWord):LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_SetDmaBufSize(hnd: t_l502_hnd; dma_ch, size: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> DMA.
function L502_SetDmaIrqStep(hnd: t_l502_hnd; dma_ch, step: LongWord): LongInt; stdcall;
{------------ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -------------------}
function L502_BfCheckFirmwareIsLoaded(hnd: t_l502_hnd; out version: LongWord): LongInt; stdcall;
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BlackFin.
function L502_BfLoadFirmware(hnd: t_l502_hnd; filename: string): LongInt; stdcall;
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_BfMemRead(hnd: t_l502_hnd; addr : LongWord; out regs: array of LongWord;
size: LongWord): LongInt; stdcall;
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_BfMemWrite(hnd: t_l502_hnd; addr : LongWord;
const regs: array of LongWord; size: LongWord): LongInt; stdcall;
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_BfExecCmd(hnd: t_l502_hnd; cmd_code : Word; par : LongWord;
const snd_data : array of LongWord; snd_size : LongWord;
out rcv_data : array of LongWord; rcv_size : LongWord;
tout: LongWord; out recvd_size: LongWord): LongInt; stdcall;
{------------------- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> Flash-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -------------}
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> Flash-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_FlashRead(hnd: t_l502_hnd; addr: LongWord;
out data: array of Byte; size: LongWord): LongInt; stdcall;
///<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> Flash-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_FlashWrite(hnd: t_l502_hnd; addr: LongWord;
const data: array of Byte; size: LongWord): LongInt; stdcall;
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><> Flash-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_FlashErase(hnd: t_l502_hnd; addr: LongWord; size: LongWord): LongInt; stdcall;
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Flash-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_FlashWriteEnable(hnd: LongWord): LongInt; stdcall;
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Flash-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_FlashWriteDisable(hnd: t_l502_hnd): LongInt; stdcall;
{----------------- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ------------------}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_GetDllVersion() : LongWord; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function L502_GetDriverVersion(hnd: t_l502_hnd; out ver: LongWord): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function L502_GetErrorString(err: LongInt) : string; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_LedBlink(hnd: t_l502_hnd): LongInt; stdcall;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_SetDigInPullup(hnd: t_l502_hnd; pullups : LongWord): LongInt; stdcall;
implementation
function L502_Create() : t_l502_hnd; stdcall; external 'l502api.dll';
function L502_Free(hnd: t_l502_hnd) : LongInt; stdcall; external 'l502api.dll';
function _get_serials( ser_arr: p_x502_serial_array; size:LongWord;
flags:LongWord; out devcnt: LongWord) : LongInt;
stdcall; external 'l502api.dll' name 'L502_GetSerialList';
function _get_dev_records_list(out list; size:LongWord;
flags : LongWord; out devcnt: LongWord) : LongInt;
stdcall; external 'l502api.dll' name 'L502_GetDevRecordsList';
function _open(hnd: t_l502_hnd; serial: PAnsiChar) : LongInt; stdcall; external 'l502api.dll' name 'L502_Open';
function L502_Close(hnd : t_l502_hnd) : LongInt; stdcall; external 'l502api.dll';
function L502_GetDevInfo(hnd : t_l502_hnd; out info : t_l502_info) : LongInt; stdcall; external 'l502api.dll';
function L502_Configure(hnd: t_l502_hnd; flags: LongWord): LongInt; stdcall; external 'l502api.dll';
function L502_SetLChannel(hnd: t_l502_hnd; lch, phy_ch, mode, range, avg: LongWord): LongInt; stdcall; external 'l502api.dll';
function L502_SetLChannelCount(hnd: t_l502_hnd; lch_cnt : LongWord): LongInt; stdcall; external 'l502api.dll';
function L502_GetLChannelCount(hnd: t_l502_hnd; out lch_cnt: LongWord): LongInt; stdcall; external 'l502api.dll';
function L502_SetAdcFreqDivider(hnd: t_l502_hnd; adc_freq_div : LongWord): LongInt; stdcall; external 'l502api.dll';
function L502_SetAdcInterframeDelay(hnd: t_l502_hnd; delay : LongWord): LongInt; stdcall; external 'l502api.dll';
function L502_SetDinFreqDivider(hnd: t_l502_hnd; din_freq_div: LongWord): LongInt; stdcall; external 'l502api.dll';
function L502_SetAdcFreq(hnd: t_l502_hnd; var f_acq, f_frame: Double): LongInt; stdcall; external 'l502api.dll';
function L502_SetDinFreq(hnd: t_l502_hnd; var f_din: Double): LongInt; stdcall; external 'l502api.dll';
function L502_GetAdcFreq(hnd: t_l502_hnd; out f_acq, f_frame: Double): LongInt; stdcall; external 'l502api.dll';
function L502_SetRefFreq(hnd: t_l502_hnd; freq: LongWord): LongInt; stdcall; external 'l502api.dll';
function L502_SetSyncMode(hnd: t_l502_hnd; sync_mode: LongWord): LongInt; stdcall; external 'l502api.dll';
function L502_SetSyncStartMode(hnd: t_l502_hnd; sync_start_mode: LongWord): LongInt; stdcall; external 'l502api.dll';
function L502_SetMode(hnd: t_l502_hnd; mode: LongWord): LongInt; stdcall; external 'l502api.dll';
function L502_GetMode(hnd: t_l502_hnd; out mode: LongWord): LongInt; stdcall; external 'l502api.dll';
function L502_SetAdcCoef(hnd: t_l502_hnd; range: LongWord; k, offs: Double): LongInt; stdcall; external 'l502api.dll';
function L502_GetAdcCoef(hnd: t_l502_hnd; range: LongWord; out k, offs: Double): LongInt; stdcall; external 'l502api.dll';
function L502_AsyncOutDac(hnd: t_l502_hnd; ch: LongWord; data: Double; flags: LongWord): LongInt; stdcall; external 'l502api.dll';
function L502_AsyncOutDig(hnd: t_l502_hnd; val, msk: LongWord): LongInt; stdcall; external 'l502api.dll';
function L502_AsyncInDig(hnd: t_l502_hnd; out din: LongWord): LongInt; stdcall; external 'l502api.dll';
function _get_adc_frame(hnd: t_l502_hnd; flags: LongWord; tout: LongWord; out data): LongInt; stdcall; external 'l502api.dll' name 'L502_AsyncGetAdcFrame';
function L502_StreamsEnable(hnd: t_l502_hnd; streams: LongWord): LongInt; stdcall; external 'l502api.dll';
function L502_StreamsDisable(hnd: t_l502_hnd; streams: LongWord): LongInt; stdcall; external 'l502api.dll';
function L502_StreamsStart(hnd: t_l502_hnd): LongInt; stdcall; external 'l502api.dll';
function L502_IsRunning(hnd: t_l502_hnd): LongInt; stdcall; external 'l502api.dll';
function L502_StreamsStop(hnd: t_l502_hnd): LongInt; stdcall; external 'l502api.dll';
function _recv(hnd: t_l502_hnd; out buf; size: LongWord; tout : LongWord): LongInt; stdcall; external 'l502api.dll' name 'L502_Recv';
function _send(hnd: t_l502_hnd; const buf; size: LongWord; tout : LongWord): LongInt; stdcall; external 'l502api.dll' name 'L502_Send';
function _process_adc_data(hnd: t_l502_hnd; const src; out dest; var size : LongWord;
flags : LongWord): LongInt; stdcall; external 'l502api.dll' name 'L502_ProcessAdcData';
function _process_data(hnd: t_l502_hnd; const src; size: LongWord;
flags : LongWord; out adc_data; var adc_data_size : LongWord;
out din_data; var din_data_size: LongWord):LongInt; stdcall; external 'l502api.dll' name 'L502_ProcessData';
function _process_data_usr(hnd: t_l502_hnd; const src; size: LongWord;
flags : LongWord; out adc_data; var adc_data_size : LongWord;
out din_data; var din_data_size: LongWord;
out usr_data; var usr_data_size: LongWord):LongInt; stdcall; external 'l502api.dll' name 'L502_ProcessDataWithUserExt';
function _prepare_data(hnd: t_l502_hnd; const dac1, dac2; const digout; size, flags : LongWord;
out out_buf):LongInt; stdcall; external 'l502api.dll' name 'L502_PrepareData';
function L502_GetRecvReadyCount(hnd: t_l502_hnd; out rdy_cnt: LongWord):LongInt; stdcall; external 'l502api.dll';
function L502_GetSendReadyCount(hnd: t_l502_hnd; out rdy_cnt: LongWord):LongInt; stdcall; external 'l502api.dll';
function L502_GetNextExpectedLchNum(hnd: t_l502_hnd; out lch: LongWord):LongInt; stdcall; external 'l502api.dll';
function L502_PreloadStart(hnd: t_l502_hnd): LongInt; stdcall; external 'l502api.dll';
function L502_OutCycleLoadStart(hnd: t_l502_hnd; size: LongWord):LongInt; stdcall; external 'l502api.dll';
function L502_OutCycleSetup(hnd: t_l502_hnd; flags: LongWord):LongInt; stdcall; external 'l502api.dll';
function L502_OutCycleStop(hnd: t_l502_hnd; flags: LongWord):LongInt; stdcall; external 'l502api.dll';
function L502_SetDmaBufSize(hnd: t_l502_hnd; dma_ch, size: LongWord): LongInt; stdcall; external 'l502api.dll';
function L502_SetDmaIrqStep(hnd: t_l502_hnd; dma_ch, step: LongWord): LongInt; stdcall; external 'l502api.dll';
function L502_BfCheckFirmwareIsLoaded(hnd: t_l502_hnd; out version: LongWord): LongInt; stdcall; external 'l502api.dll';
function _bf_load_firm(hnd: t_l502_hnd; filename: PAnsiChar): LongInt; stdcall; external 'l502api.dll' name 'L502_BfLoadFirmware';
function _bf_mem_read(hnd: t_l502_hnd; addr : LongWord; out regs; size: LongWord): LongInt; stdcall; external 'l502api.dll' name 'L502_BfMemRead';
function _bf_mem_write(hnd: t_l502_hnd; addr : LongWord; const regs; size: LongWord): LongInt; stdcall; external 'l502api.dll' name 'L502_BfMemWrite';
function _bf_exec_cmd(hnd: t_l502_hnd; cmd_code : Word; par : LongWord;
const snd_data; snd_size : LongWord; out rcv_data; rcv_size : LongWord;
tout: LongWord; out recved_size: LongWord): LongInt; stdcall; external 'l502api.dll' name 'L502_BfExecCmd';
function _flash_read(hnd: t_l502_hnd; addr: LongWord; out data; size: LongWord): LongInt; stdcall; external 'l502api.dll' name 'L502_FlashRead';
function _flash_write(hnd: t_l502_hnd; addr: LongWord; const data; size: LongWord): LongInt; stdcall; external 'l502api.dll' name 'L502_FlashWrite';
function L502_FlashErase(hnd: t_l502_hnd; addr: LongWord; size: LongWord): LongInt; stdcall; external 'l502api.dll';
function L502_FlashWriteEnable(hnd: LongWord): LongInt; stdcall; external 'l502api.dll';
function L502_FlashWriteDisable(hnd: t_l502_hnd): LongInt; stdcall; external 'l502api.dll';
function L502_GetDllVersion() : LongWord; stdcall; external 'l502api.dll';
function L502_GetDriverVersion(hnd: t_l502_hnd; out ver: LongWord): LongInt; stdcall; external 'l502api.dll';
function _get_err_str(err : LongInt) : PAnsiChar; stdcall; external 'l502api.dll' name 'L502_GetErrorString';
function L502_LedBlink(hnd: t_l502_hnd): LongInt; stdcall; external 'l502api.dll';
function L502_SetDigInPullup(hnd: t_l502_hnd; pullups : LongWord): LongInt; stdcall; external 'l502api.dll';
{
function L502_GetSerialList(out serials: t_l502_serial_list; flags: LongWord) : LongInt; overload;
var
ser_arr : p_l502_serial_array;
devcnt: LongWord;
res, i : LongInt;
begin
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
res := _get_serials(nil, 0, flags, devcnt);
if (res >= 0) and (devcnt>0) then
begin
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> devcnt <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ser_arr:=GetMemory(devcnt*L502_SERIAL_SIZE);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
res:= _get_serials(ser_arr, devcnt, flags, PLongWord(nil)^);
if (res > 0) then
begin
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SetLength(serials, res);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
for i:=0 to res-1 do
serials[i] := string(ser_arr[i]);
end;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
FreeMemory(ser_arr);
end;
L502_GetSerialList:= res;
end;
}
function L502_GetSerialList(out serials: array of string; flags: LongWord; out devcnt: LongWord) : LongInt; overload;
var
ser_arr : p_x502_serial_array;
res, i : LongInt;
begin
if (Length(serials) > 0) then
begin
ser_arr:=GetMemory(Length(serials)*X502_SERIAL_SIZE);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
res := _get_serials(ser_arr, Length(serials), flags, devcnt);
if res >= 0 then
begin
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
for i:=0 to res-1 do
serials[i] := string(ser_arr[i]);
end;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
FreeMemory(ser_arr);
end
else
begin
res:= _get_serials(nil, 0, flags, devcnt);
end;
L502_GetSerialList:=res;
end;
function L502_GetSerialList(out serials: array of string; flags: LongWord) : LongInt; overload;
begin
L502_GetSerialList:= L502_GetSerialList(serials, flags, PCardinal(nil)^);
end;
function L502_GetDevRecordsList(out list: array of t_x502_devrec; flags : LongWord; out devcnt: LongWord) : LongInt; overload;
begin
if (Length(list) > 0) then
begin
L502_GetDevRecordsList := _get_dev_records_list(list, Length(list), flags, devcnt);
end
else
begin
L502_GetDevRecordsList:= _get_dev_records_list(PCardinal(nil)^, 0, flags, devcnt);
end;
end;
function L502_GetDevRecordsList(out list: array of t_x502_devrec; flags : LongWord) : LongInt; overload;
begin
L502_GetDevRecordsList:= L502_GetDevRecordsList(list, flags, PCardinal(nil)^);
end;
function L502_Open(hnd: t_l502_hnd; serial: string) : LongInt;
begin
L502_Open:=_open(hnd, PAnsiChar(AnsiString(serial)));
end;
function L502_GetErrorString(err: LongInt) : string;
begin
L502_GetErrorString:= string(_get_err_str(err));
end;
function L502_AsyncGetAdcFrame(hnd: t_l502_hnd; flags: LongWord; tout: LongWord; out data: array of Double): LongInt; stdcall;
var err: LongInt;
lch_cnt: LongWord;
begin
err:= L502_GetLChannelCount(hnd, lch_cnt);
if err=L502_ERR_OK then
begin
if LongWord(Length(data)) < lch_cnt then
err:=L502_ERR_INSUFFICIENT_ARRAY_SIZE
else
err:=_get_adc_frame(hnd,flags,tout,data);
end;
L502_AsyncGetAdcFrame:=err;
end;
function L502_Recv(hnd: t_l502_hnd; out buf : array of LongWord; size: LongWord; tout : LongWord): LongInt; stdcall;
begin
if LongWord(Length(buf)) < size then
L502_Recv:=L502_ERR_INSUFFICIENT_ARRAY_SIZE
else
L502_Recv:=_recv(hnd, buf, size, tout);
end;
function L502_Send(hnd: t_l502_hnd; const buf : array of LongWord; size: LongWord; tout: LongWord): LongInt; stdcall;
begin
if LongWord(Length(buf)) < size then
L502_Send:=L502_ERR_INSUFFICIENT_ARRAY_SIZE
else
L502_Send:=_send(hnd,buf,size,tout);
end;
function L502_ProcessAdcData(hnd: t_l502_hnd; const src: array of LongWord;
out dest: array of Double; var size : LongWord;
flags : LongWord): LongInt; stdcall;
begin
if (LongWord(Length(src)) < size) or (LongWord(Length(dest)) < size) then
L502_ProcessAdcData:=L502_ERR_INSUFFICIENT_ARRAY_SIZE
else
L502_ProcessAdcData:=_process_adc_data(hnd, src, dest, size, flags);
end;
function L502_ProcessData(hnd: t_l502_hnd; const src: array of LongWord; size: LongWord;
flags : LongWord; out adc_data: array of Double; var adc_data_size : LongWord;
out din_data: array of LongWord; var din_data_size: LongWord):LongInt; stdcall;
begin
if (LongWord(Length(adc_data)) < adc_data_size) or (LongWord(Length(din_data)) < din_data_size)
or (LongWord(Length(src)) < size) then
L502_ProcessData:=L502_ERR_INSUFFICIENT_ARRAY_SIZE
else
L502_ProcessData:=_process_data(hnd, src, size, flags, adc_data, adc_data_size, din_data, din_data_size);
end;
function L502_ProcessDataWithUserExt(hnd: t_l502_hnd; const src: array of LongWord; size: LongWord;
flags : LongWord; out adc_data: array of Double; var adc_data_size : LongWord;
out din_data: array of LongWord; var din_data_size: LongWord;
out usr_data: array of LongWord; var usr_data_size: LongWord):LongInt; stdcall;
begin
if (LongWord(Length(adc_data)) < adc_data_size) or (LongWord(Length(din_data)) < din_data_size)
or (LongWord(Length(src)) < size) or (LongWord(Length(usr_data)) < usr_data_size) then
L502_ProcessDataWithUserExt:=L502_ERR_INSUFFICIENT_ARRAY_SIZE
else
L502_ProcessDataWithUserExt:=_process_data_usr(hnd, src,size,flags,adc_data,
adc_data_size, din_data, din_data_size, usr_data, usr_data_size);
end;
function L502_PrepareData(hnd: t_l502_hnd; const dac1, dac2: array of Double;
const digout: array of LongWord; size, flags : LongWord;
out out_buf: array of LongWord):LongInt; stdcall;
begin
L502_PrepareData:=_prepare_data(hnd, dac1, dac2, digout, size, flags, out_buf);
end;
function L502_BfLoadFirmware(hnd: t_l502_hnd; filename: string): LongInt; stdcall;
begin
L502_BfLoadFirmware:=_bf_load_firm(hnd, PAnsiChar(AnsiString(filename)));
end;
function L502_BfMemRead(hnd: t_l502_hnd; addr : LongWord; out regs: array of LongWord;
size: LongWord): LongInt; stdcall;
begin
if (LongWord(Length(regs)) < size) then
L502_BfMemRead := L502_ERR_INSUFFICIENT_ARRAY_SIZE
else
L502_BfMemRead:=_bf_mem_read(hnd, addr, regs, size);
end;
function L502_BfMemWrite(hnd: t_l502_hnd; addr : LongWord;
const regs: array of LongWord; size: LongWord): LongInt; stdcall;
begin
if (LongWord(Length(regs)) < size) then
L502_BfMemWrite := L502_ERR_INSUFFICIENT_ARRAY_SIZE
else
L502_BfMemWrite:=_bf_mem_write(hnd, addr, regs, size);
end;
function L502_BfExecCmd(hnd: t_l502_hnd; cmd_code : Word; par : LongWord;
const snd_data : array of LongWord; snd_size : LongWord;
out rcv_data : array of LongWord; rcv_size : LongWord;
tout: LongWord; out recvd_size: LongWord): LongInt; stdcall;
begin
if (LongWord(Length(snd_data)) < snd_size) or
(LongWord(Length(rcv_data)) < rcv_size) then
L502_BfExecCmd := L502_ERR_INSUFFICIENT_ARRAY_SIZE
else
L502_BfExecCmd:=_bf_exec_cmd(hnd, cmd_code, par, snd_data, snd_size,
rcv_data, rcv_size, tout, recvd_size);
end;
function L502_FlashRead(hnd: t_l502_hnd; addr: LongWord;
out data: array of Byte; size: LongWord): LongInt; stdcall;
begin
if (LongWord(Length(data)) < size) then
L502_FlashRead := L502_ERR_INSUFFICIENT_ARRAY_SIZE
else
L502_FlashRead:=_bf_mem_write(hnd, addr, data, size);
end;
///<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> Flash-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
function L502_FlashWrite(hnd: t_l502_hnd; addr: LongWord;
const data: array of Byte; size: LongWord): LongInt; stdcall;
begin
if (LongWord(Length(data)) < size) then
L502_FlashWrite := L502_ERR_INSUFFICIENT_ARRAY_SIZE
else
L502_FlashWrite:=_bf_mem_write(hnd, addr, data, size);
end;
end.

View File

@ -0,0 +1,507 @@
#include <Windows.h>
#include <SetupAPI.h>
#include <initguid.h>
#include <stddef.h>
#include <tchar.h>
#include "../l502api_private.h"
#include <winioctl.h>
/* GUID интерфейса устройств lpcie для связи приложения с драйвером */
DEFINE_GUID (GUID_LPCIE_INTERFACE,
0x53869b9a, 0x7875, 0x4fd3, 0x9e, 0x04, 0xbe, 0xc8, 0x1a, 0x92, 0xf9, 0xa9);
#define L502_IOCTL_TIMEOUT 500
typedef struct {
int32_t size;
SP_DEVICE_INTERFACE_DETAIL_DATA *intf_detail;
} t_lpcie_devlst_intptr;
static int32_t f_ioctl(HANDLE hDevice,
uint32_t dwIoControlCode, // control code of operation to perform
void* lpInBuffer, // pointer to buffer to supply input data
uint32_t nInBufferSize, // size of input buffer in bytes
void* lpOutBuffer, // pointer to buffer to receive output data
uint32_t nOutBufferSize, // size of output buffer in bytes
uint32_t* rx_size,
uint32_t TimeOut) { // таймаут в мс
uint32_t RealBytesTransferred;
uint32_t BytesReturned;
OVERLAPPED Ov;
int32_t err = X502_ERR_OK;
uint32_t syserr = 0;
// инициализируем OVERLAPPED структуру
memset(&Ov, 0x0, sizeof(OVERLAPPED));
// создаём событие для асинхронного запроса
Ov.hEvent = CreateEvent(NULL, FALSE , FALSE, NULL);
if(!Ov.hEvent) {
err = X502_ERR_MEMORY_ALLOC;
} else {
// посылаем требуемый запрос
if(!DeviceIoControl( hDevice, dwIoControlCode,
lpInBuffer, nInBufferSize,
lpOutBuffer, nOutBufferSize,
&BytesReturned, &Ov)) {
syserr = GetLastError();
if(syserr != ERROR_IO_PENDING) {
CloseHandle(Ov.hEvent);
err = X502_ERR_IOCTL_FAILD;
GetOverlappedResult(hDevice, &Ov, &RealBytesTransferred, TRUE);
}
}
}
if (err == X502_ERR_OK) {
// ждём окончания выполнения запроса
if (WaitForSingleObject(Ov.hEvent, TimeOut) == WAIT_TIMEOUT) {
CancelIo(hDevice);
CloseHandle(Ov.hEvent);
err = X502_ERR_IOCTL_TIMEOUT;
GetOverlappedResult(hDevice, &Ov, &RealBytesTransferred, TRUE);
}
}
// попробуем получить кол-во реально переданных байт данных
if (err == X502_ERR_OK) {
if(!GetOverlappedResult(hDevice, &Ov, &RealBytesTransferred, TRUE)) {
syserr = GetLastError();
CancelIo(hDevice);
CloseHandle(Ov.hEvent);
err = X502_ERR_IOCTL_FAILD;
} else if(nOutBufferSize != RealBytesTransferred) {
CancelIo(hDevice);
CloseHandle(Ov.hEvent);
} else {
CloseHandle(Ov.hEvent);
}
}
if ((err == X502_ERR_OK) && (rx_size != NULL)) {
*rx_size = RealBytesTransferred;
}
if (err==X502_ERR_IOCTL_FAILD) {
if (syserr == ERROR_NO_SYSTEM_RESOURCES)
err = X502_ERR_INSUFFICIENT_SYSTEM_RESOURCES;
}
return err;
}
int32_t l502_port_fpga_reg_write(t_x502_hnd hnd, uint32_t reg, uint32_t val) {
t_lpcie_mem_rw mem_wr = {reg,val};
return f_ioctl (L502_PCI_IFACE_FILE(hnd),
LPCIE_IOCTL_MEMFPGA_WR, &mem_wr, sizeof(mem_wr),
NULL, 0, NULL, L502_IOCTL_TIMEOUT) ?
X502_ERR_FPGA_REG_READ : 0;
}
int32_t l502_port_fpga_reg_read(t_x502_hnd hnd, uint32_t reg, uint32_t *val) {
uint32_t rd_val;
int32_t err = f_ioctl (L502_PCI_IFACE_FILE(hnd),
LPCIE_IOCTL_MEMFPGA_RD, &reg, sizeof(reg),
&rd_val, sizeof(rd_val), NULL, L502_IOCTL_TIMEOUT);
if (err != X502_ERR_OK) {
err = X502_ERR_FPGA_REG_READ;
} else if (val != NULL) {
*val = rd_val;
}
return err;
}
int32_t l502_port_stream_set_params(t_x502_hnd hnd, t_lpcie_stream_ch_params *par) {
return f_ioctl(L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_STREAM_SET_PARAMS, par,
sizeof(t_lpcie_stream_ch_params), NULL, 0, NULL,
L502_IOCTL_TIMEOUT);
}
int32_t l502_port_stream_start(t_x502_hnd hnd, uint32_t ch, uint32_t single) {
return f_ioctl(L502_PCI_IFACE_FILE(hnd), single ? LPCIE_IOCTL_STREAM_START_SINGLE :
LPCIE_IOCTL_STREAM_START,
&ch, sizeof(ch), NULL, 0, NULL,
L502_IOCTL_TIMEOUT);
}
int32_t l502_port_stream_stop(t_x502_hnd hnd, uint32_t ch, uint32_t flags) {
return f_ioctl(L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_STREAM_STOP, &ch, sizeof(ch), NULL, 0, NULL,
L502_IOCTL_TIMEOUT);
}
int32_t l502_port_stream_free(t_x502_hnd hnd, uint32_t ch, uint32_t flags) {
return f_ioctl(L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_STREAM_FREE, &ch, sizeof(ch), NULL, 0, NULL,
L502_IOCTL_TIMEOUT);
}
int32_t l502_port_stream_rdy_size(t_x502_hnd hnd, uint32_t ch, uint32_t *rdy_size) {
uint32_t rd_val;
int32_t err = f_ioctl (L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_STREAM_GET_RDY_SIZE, &ch, sizeof(ch),
&rd_val, sizeof(rd_val), NULL, L502_IOCTL_TIMEOUT);
if ((err == X502_ERR_OK) && (rdy_size != NULL))
*rdy_size = rd_val;
return err;
}
int32_t l502_port_cycle_load_start(t_x502_hnd hnd, uint32_t ch, uint32_t size, uint32_t min_irq_step) {
t_lpcie_cycle_set_par par;
memset(&par, 0, sizeof(par));
par.ch = ch;
par.size = size;
par.irq_step = min_irq_step;
return f_ioctl (L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_CYCLE_LOAD, &par, sizeof(par), NULL, 0,
NULL, L502_IOCTL_TIMEOUT);
}
int32_t l502_port_cycle_setup(t_x502_hnd hnd, uint32_t ch, uint32_t evt) {
t_lpcie_cycle_evt_par par;
memset(&par, 0, sizeof(par));
par.ch = ch;
par.evt = evt;
return f_ioctl (L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_CYCLE_SWITCH, &par, sizeof(par), NULL, 0,
NULL, L502_IOCTL_TIMEOUT);
}
int32_t l502_port_cycle_stop(t_x502_hnd hnd, uint32_t ch, uint32_t evt) {
t_lpcie_cycle_evt_par par;
memset(&par, 0, sizeof(par));
par.ch = ch;
par.evt = evt;
return f_ioctl (L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_CYCLE_STOP, &par, sizeof(par), NULL, 0,
NULL, L502_IOCTL_TIMEOUT);
}
int32_t l502_port_cycle_check_setup(t_x502_hnd hnd, uint32_t ch, uint32_t *done) {
uint32_t rd_val;
int32_t err = f_ioctl (L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_CYCLE_CHECK_SETUP, &ch, sizeof(ch),
&rd_val, sizeof(rd_val), NULL, L502_IOCTL_TIMEOUT);
if ((err == X502_ERR_OK) && (done != NULL))
*done = rd_val;
return err;
}
int32_t l502_port_renew_info(t_x502_hnd hnd) {
return f_ioctl(L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_RELOAD_DEVINFO, NULL, 0, NULL, 0, NULL,
L502_IOCTL_TIMEOUT);
}
int32_t l502_port_get_drv_ver(t_x502_hnd hnd, uint32_t *ver) {
uint32_t rd_val;
int32_t err = f_ioctl (L502_PCI_IFACE_FILE(hnd), LPCIE_IOCTL_GET_DRV_VERSION, NULL, 0,
&rd_val, sizeof(rd_val), NULL, L502_IOCTL_TIMEOUT);
if ((err == X502_ERR_OK) && (ver != NULL))
*ver = rd_val;
return err;
}
int32_t l502_port_stream_read(t_x502_hnd hnd, uint32_t* buff, uint32_t size, uint32_t timeout) {
int send_size = 4*size;
uint32_t NumberOfBytesRead = 0;
int32_t err = X502_ERR_OK;
OVERLAPPED Ov;
// инициализируем OVERLAPPED структуру
memset(&Ov, 0, sizeof(OVERLAPPED));
Ov.hEvent = CreateEvent(NULL, FALSE , FALSE, NULL);
if(!Ov.hEvent) {
err = X502_ERR_MEMORY_ALLOC;
}
if (err == X502_ERR_OK) {
// посылаем асинхронный запрос на сбор необходимого кол-ва данных
if(!ReadFile(L502_PCI_IFACE_FILE(hnd), buff, send_size, NULL, &Ov)) {
if(GetLastError() != ERROR_IO_PENDING) {
CancelIo(L502_PCI_IFACE_FILE(hnd));
CloseHandle(Ov.hEvent);
err = X502_ERR_RECV;
GetOverlappedResult(L502_PCI_IFACE_FILE(hnd), &Ov, &NumberOfBytesRead, TRUE);
}
}
}
// ждём окончания выполнения запроса
if (err == X502_ERR_OK) {
if (WaitForSingleObject(Ov.hEvent, timeout) == WAIT_TIMEOUT) {
CancelIo(L502_PCI_IFACE_FILE(hnd));
CloseHandle(Ov.hEvent);
GetOverlappedResult(L502_PCI_IFACE_FILE(hnd), &Ov, &NumberOfBytesRead, TRUE);
} else if(!GetOverlappedResult(L502_PCI_IFACE_FILE(hnd), &Ov, &NumberOfBytesRead, TRUE)) {
CancelIo(L502_PCI_IFACE_FILE(hnd));
CloseHandle(Ov.hEvent);
err = X502_ERR_RECV;
} else {
CloseHandle(Ov.hEvent);
}
}
return err != X502_ERR_OK ? err : NumberOfBytesRead/4;
}
int32_t l502_port_stream_write(t_x502_hnd hnd, const uint32_t* buff,
uint32_t size, uint32_t timeout) {
int send_size = 4*size;
uint32_t NumberOfBytesRead = 0;
int32_t err = X502_ERR_OK;
OVERLAPPED Ov;
// инициализируем OVERLAPPED структуру
memset(&Ov, 0, sizeof(OVERLAPPED));
Ov.hEvent = CreateEvent(NULL, FALSE , FALSE, NULL);
if(!Ov.hEvent) {
err = X502_ERR_MEMORY_ALLOC;
}
if (err == X502_ERR_OK) {
// посылаем асинхронный запрос на сбор необходимого кол-ва данных
if(!WriteFile(L502_PCI_IFACE_FILE(hnd), buff, send_size, NULL, &Ov)) {
if(GetLastError() != ERROR_IO_PENDING) {
CancelIo(L502_PCI_IFACE_FILE(hnd));
CloseHandle(Ov.hEvent);
err = X502_ERR_SEND;
GetOverlappedResult(L502_PCI_IFACE_FILE(hnd), &Ov, &NumberOfBytesRead, TRUE);
}
}
}
// ждём окончания выполнения запроса
if (err == X502_ERR_OK) {
if (WaitForSingleObject(Ov.hEvent, timeout) == WAIT_TIMEOUT) {
CancelIo(L502_PCI_IFACE_FILE(hnd));
CloseHandle(Ov.hEvent);
GetOverlappedResult(L502_PCI_IFACE_FILE(hnd), &Ov, &NumberOfBytesRead, TRUE);
} else if(!GetOverlappedResult(L502_PCI_IFACE_FILE(hnd), &Ov, &NumberOfBytesRead, TRUE)) {
CancelIo(L502_PCI_IFACE_FILE(hnd));
CloseHandle(Ov.hEvent);
err = X502_ERR_SEND;
} else {
CloseHandle(Ov.hEvent);
}
}
return err != X502_ERR_OK ? err : NumberOfBytesRead/4;
}
static int32_t f_get_file_par(SP_DEVICE_INTERFACE_DETAIL_DATA *detail, TCHAR* filebuf,
const TCHAR* file, char* res, uint32_t req_size,
uint32_t* read_size) {
HANDLE ifile;
int32_t err = 0;
_tcscpy(filebuf, TEXT(detail->DevicePath));
_tcscat(filebuf, file);
ifile = CreateFile(filebuf, GENERIC_READ,
FILE_SHARE_READ,
NULL, OPEN_EXISTING,
0, NULL);
if (ifile != INVALID_HANDLE_VALUE) {
DWORD read_cnt=0;
if (!ReadFile(ifile, res, req_size, &read_cnt, NULL)) {
err = X502_ERR_GET_INFO;
} else {
if (read_size!=NULL)
*read_size = read_cnt;
}
CloseHandle(ifile);
} else {
err = X502_ERR_GET_INFO;
}
return err;
}
static int f_fill_devlist(SP_DEVICE_INTERFACE_DETAIL_DATA *detail,
t_x502_devrec *info) {
int32_t err = X502_ERR_OK;
TCHAR *filename = malloc(sizeof(TCHAR)*21 + _tcslen(detail->DevicePath));
if (filename == NULL) {
err = X502_ERR_MEMORY_ALLOC;
} else {
err = f_get_file_par(detail, filename, TEXT("\\name"), info->devname,
sizeof(info->devname), NULL);
if (err == X502_ERR_OK) {
/* получаем серийный номер устройства */
err = f_get_file_par(detail, filename, TEXT("\\sn"), info->serial,
sizeof(info->serial), NULL);
}
/* получаем информацию, открыто ли устройство */
if (err == X502_ERR_OK) {
char val = '0';
f_get_file_par(detail, filename, TEXT("\\opened"), &val, 1, NULL);
if (!err && (val!='0'))
info->flags |= X502_DEVFLAGS_DEVREC_OPENED;
}
/* получаем информацию, присутствует ли BlackFin */
if (err == X502_ERR_OK) {
char val = '0';
if ((f_get_file_par(detail, filename, TEXT("\\bf"), &val, 1, NULL)==0)
&& (val != '0')) {
info->flags |= X502_DEVFLAGS_BF_PRESENT;
}
if ((f_get_file_par(detail, filename, TEXT("\\dac"), &val, 1, NULL)==0)
&& (val != '0')) {
info->flags |= X502_DEVFLAGS_DAC_PRESENT;
}
if ((f_get_file_par(detail, filename, TEXT("\\gal"), &val, 1, NULL)==0)
&& (val != '0')) {
info->flags |= X502_DEVFLAGS_GAL_PRESENT;
}
}
if (err == X502_ERR_OK) {
err = l502_devlist_gen(info, detail);
}
free(filename);
}
return err;
}
int32_t l502_port_free_iface_data(void *intptr) {
free(intptr);
return X502_ERR_OK;
}
int32_t l502_port_open(t_x502_hnd hnd, const t_x502_devrec *devinfo) {
SP_DEVICE_INTERFACE_DETAIL_DATA *detail = (SP_DEVICE_INTERFACE_DETAIL_DATA *)devinfo->internal->iface_data;
int32_t err = X502_ERR_OK;
HANDLE file = CreateFile(detail->DevicePath, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, NULL);
if (file != INVALID_HANDLE_VALUE) {
hnd->iface_data = malloc(sizeof(t_pci_iface_data));
if (hnd->iface_data == NULL) {
err = X502_ERR_MEMORY_ALLOC;
CloseHandle(file);
} else {
L502_PCI_IFACE_FILE(hnd) = file;
}
} else {
DWORD syserr = GetLastError();
if (syserr == ERROR_ACCESS_DENIED) {
err = X502_ERR_DEVICE_ACCESS_DENIED;
} else if (syserr == ERROR_FILE_NOT_FOUND) {
err = X502_ERR_DEVICE_NOT_FOUND;
} else {
err = X502_ERR_DEVICE_OPEN;
}
}
return err;
}
int32_t l502_port_close(t_x502_hnd hnd) {
if (hnd->iface_data !=NULL) {
CloseHandle(L502_PCI_IFACE_FILE(hnd));
free(hnd->iface_data);
hnd->iface_data = NULL;
}
return X502_ERR_OK;
}
X502_EXPORT(int32_t) L502_GetDevRecordsList(t_x502_devrec *list, uint32_t size,
uint32_t flags, uint32_t *devcnt) {
HDEVINFO infoSet;
SP_DEVINFO_DATA infoData;
DWORD index=0;
uint32_t curcnt=0;
int32_t err = X502_ERR_OK;
infoData.cbSize = sizeof(SP_DEVINFO_DATA);
/* получаем список устройств с подержкой интерфейса lpcie */
infoSet = SetupDiGetClassDevs(&GUID_LPCIE_INTERFACE,NULL,
NULL,
DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
/* проходимся по всем устройствам из списка */
while (SetupDiEnumDeviceInfo(infoSet, index, &infoData)) {
SP_DEVICE_INTERFACE_DATA intfData;
intfData.cbSize = sizeof(intfData);
/* получаем информацию о интерфейсе */
if (SetupDiEnumDeviceInterfaces(infoSet, &infoData, &GUID_LPCIE_INTERFACE,
0, &intfData)) {
DWORD req_size;
/* узнаем резмер детальной информации о интерфейсе (нужна для
получения имени устройства) */
if (!SetupDiGetDeviceInterfaceDetail(infoSet, &intfData, NULL,
0, &req_size, NULL)
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
SP_DEVICE_INTERFACE_DETAIL_DATA* detail =
(SP_DEVICE_INTERFACE_DETAIL_DATA*) malloc(req_size);
if (detail != NULL) {
int detail_used = 0;
/* пытаемся получить всю информацию */
detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (SetupDiGetDeviceInterfaceDetail(infoSet, &intfData,
detail, req_size,
NULL, NULL)) {
t_x502_devrec info;
int info_used = 0;
detail_used = 1;
X502_DevRecordInit(&info);
/* получаем информацию о устройстве из служебных файлов,
* предоставляемых драйвером */
if (f_fill_devlist(detail, &info) == X502_ERR_OK) {
/* если нужны только не открытые, то уже открытое
* устройство пропускаем */
if (!(flags & X502_GETDEVS_FLAGS_ONLY_NOT_OPENED) ||
!(info.flags & X502_DEVFLAGS_DEVREC_OPENED)) {
/* если есть место в списке - то сохраняем
* полученную информацию */
if ((list!=NULL) && (curcnt < size)) {
list[curcnt] = info;
info_used = 1;
}
curcnt++;
}
}
if (!info_used)
X502_FreeDevRecordList(&info,1);
}
if (!detail_used) {
free(detail);
}
} else {
err = X502_ERR_MEMORY_ALLOC;
}
}
}
index++;
}
if (infoSet != NULL) {
SetupDiDestroyDeviceInfoList(infoSet);
}
if (devcnt != NULL)
*devcnt = curcnt;
return err != X502_ERR_OK ? err : curcnt > size ? size : curcnt ;
}