serial: prepare serial over HID in common layer and build support

Search for the optional HIDAPI library. Call the library's init and exit
routine, and print version information. Extend the common serial layer's
code paths for open, list, and find USB to also support serial over HID.

This commit prepares serial over HID, but the HIDAPI specific transport
for serial communication still is empty in this implementation.
This commit is contained in:
Gerhard Sittig 2017-03-26 15:48:36 +01:00 committed by Uwe Hermann
parent ad5aa993ae
commit 4417074c68
7 changed files with 91 additions and 3 deletions

View File

@ -119,6 +119,7 @@ endif
if NEED_SERIAL
libsigrok_la_SOURCES += \
src/serial.c \
src/serial_hid.c \
src/serial_libsp.c \
src/scpi/scpi_serial.c
endif

1
README
View File

@ -41,6 +41,7 @@ Requirements for the C library:
- libserialport >= 0.1.1 (optional, used by some drivers)
- librevisa >= 0.0.20130412 (optional, used by some drivers)
- libusb-1.0 >= 1.0.16 (optional, used by some drivers)
- hidapi >= 0.8.0 (optional, used for some HID based "serial cables")
- libftdi1 >= 1.0 (optional, used by some drivers)
- libgpib (optional, used by some drivers)
- libieee1284 (optional, used by some drivers)

View File

@ -101,6 +101,9 @@ SR_ARG_OPT_PKG([libserialport], [LIBSERIALPORT], ,
SR_ARG_OPT_PKG([libftdi], [LIBFTDI], , [libftdi1 >= 1.0])
SR_ARG_OPT_PKG([libhidapi], [LIBHIDAPI], ,
[hidapi >= 0.8.0], [hidapi-hidraw >= 0.8.0], [hidapi-libusb >= 0.8.0])
# FreeBSD comes with an "integrated" libusb-1.0-style USB API.
# This means libusb-1.0 is always available; no need to check for it.
# On Windows, require the latest version we can get our hands on,
@ -130,7 +133,7 @@ SR_ARG_OPT_CHECK([libieee1284], [LIBIEEE1284],, [
AS_IF([test "x$sr_have_libieee1284" = xyes],
[SR_PREPEND([SR_EXTRA_LIBS], [-lieee1284])])
AS_IF([test "x$sr_have_libserialport" = xyes],
AS_IF([test "x$sr_have_libserialport" = xyes -o "x$sr_have_libhidapi" = xyes],
sr_have_serial_comm=yes, sr_have_serial_comm=no)
AS_IF([test "x$sr_have_serial_comm" = xyes],
[AC_DEFINE([HAVE_SERIAL_COMM], [1], [Specifies whether serial communication is supported.])])
@ -612,6 +615,7 @@ $sr_driver_summary
Enabled serial communication transports:
- serial comm ................... $sr_have_serial_comm
- libserialport ................. $sr_have_libserialport
- hidapi ........................ $sr_have_libhidapi
Enabled SCPI backends:
- TCP............................. yes

View File

@ -164,6 +164,11 @@ SR_API GSList *sr_buildinfo_libs_get(void)
#endif
l = g_slist_append(l, m);
#endif
#ifdef HAVE_LIBHIDAPI
m = g_slist_append(NULL, g_strdup("hidapi"));
m = g_slist_append(m, g_strdup_printf("%s", CONF_LIBHIDAPI_VERSION));
l = g_slist_append(l, m);
#endif
#ifdef HAVE_LIBFTDI
m = g_slist_append(NULL, g_strdup("libftdi"));
m = g_slist_append(m, g_strdup_printf("%s", CONF_LIBFTDI_VERSION));
@ -591,6 +596,20 @@ SR_API int sr_init(struct sr_context **ctx)
ret = SR_ERR;
goto done;
}
#endif
#ifdef HAVE_LIBHIDAPI
/*
* According to <hidapi.h>, the hid_init() routine just returns
* zero or non-zero, and hid_error() appears to relate to calls
* for a specific device after hid_open(). Which means that there
* is no more detailled information available beyond success/fail
* at this point in time.
*/
if (hid_init() != 0) {
sr_err("HIDAPI hid_init() failed.");
ret = SR_ERR;
goto done;
}
#endif
sr_resource_set_hooks(context, NULL, NULL, NULL, NULL);
@ -626,6 +645,9 @@ SR_API int sr_exit(struct sr_context *ctx)
WSACleanup();
#endif
#ifdef HAVE_LIBHIDAPI
hid_exit();
#endif
#ifdef HAVE_LIBUSB_1_0
libusb_exit(ctx->libusb_ctx);
#endif

View File

@ -29,6 +29,9 @@
#include "config.h"
#include <glib.h>
#ifdef HAVE_LIBHIDAPI
#include <hidapi.h>
#endif
#ifdef HAVE_LIBSERIALPORT
#include <libserialport.h>
#endif
@ -744,6 +747,10 @@ struct sr_serial_dev_inst {
/** libserialport port handle */
struct sp_port *sp_data;
#endif
#ifdef HAVE_LIBHIDAPI
/* TODO */
hid_device *hid_dev;
#endif
};
#endif
@ -1177,6 +1184,8 @@ struct ser_lib_functions {
size_t (*get_rx_avail)(struct sr_serial_dev_inst *serial);
};
extern SR_PRIV struct ser_lib_functions *ser_lib_funcs_libsp;
SR_PRIV int ser_name_is_hid(struct sr_serial_dev_inst *serial);
extern SR_PRIV struct ser_lib_functions *ser_lib_funcs_hid;
#endif
/*--- ezusb.c ---------------------------------------------------------------*/

View File

@ -91,8 +91,15 @@ SR_PRIV int serial_open(struct sr_serial_dev_inst *serial, int flags)
sr_spew("Opening serial port '%s' (flags %d).", serial->port, flags);
/* Default to the libserialport transport layer. */
serial->lib_funcs = ser_lib_funcs_libsp;
/*
* Determine which serial transport library to use. Derive the
* variant from the serial port's name. Default to libserialport
* for backwards compatibility.
*/
if (ser_name_is_hid(serial))
serial->lib_funcs = ser_lib_funcs_hid;
else
serial->lib_funcs = ser_lib_funcs_libsp;
if (!serial->lib_funcs)
return SR_ERR_NA;
@ -930,6 +937,10 @@ SR_API GSList *sr_serial_list(const struct sr_dev_driver *driver)
list_func = ser_lib_funcs_libsp->list;
tty_devs = list_func(tty_devs, append_port_list);
}
if (ser_lib_funcs_hid && ser_lib_funcs_hid->list) {
list_func = ser_lib_funcs_hid->list;
tty_devs = list_func(tty_devs, append_port_list);
}
return tty_devs;
}
@ -966,6 +977,11 @@ SR_PRIV GSList *sr_serial_find_usb(uint16_t vendor_id, uint16_t product_id)
tty_devs = find_func(tty_devs, append_port_find,
vendor_id, product_id);
}
if (ser_lib_funcs_hid && ser_lib_funcs_hid->find_usb) {
find_func = ser_lib_funcs_hid->find_usb;
tty_devs = find_func(tty_devs, append_port_find,
vendor_id, product_id);
}
return tty_devs;
}

35
src/serial_hid.c Normal file
View File

@ -0,0 +1,35 @@
/*
* This file is part of the libsigrok project.
*
* Copyright (C) 2017-2019 Gerhard Sittig <gerhard.sittig@gmx.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <libsigrok/libsigrok.h>
#include "libsigrok-internal.h"
/** @cond PRIVATE */
#define LOG_PREFIX "serial-hid"
/** @endcond */
SR_PRIV int ser_name_is_hid(struct sr_serial_dev_inst *serial)
{
(void)serial;
return 0;
}
SR_PRIV struct ser_lib_functions *ser_lib_funcs_hid = NULL;