Skip to content

Commit

Permalink
Merge pull request #240 from lucianomartin/feature/update_win_libusb
Browse files Browse the repository at this point in the history
Update libusb host driver in RTOS device control
  • Loading branch information
xluciano authored Jul 22, 2024
2 parents 089a073 + de2e96c commit 6fb6fb3
Show file tree
Hide file tree
Showing 8 changed files with 2,361 additions and 510 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ UNRELEASED
----------

* FIXED: Windows host issue with pre-2013 Visual Studio Compiler and stdbool.h.
* UPDATED: libusb host drivers for Windows to v1.0.27. The device must now use WinUSB drivers on Windows.
* UPDATED: To tinyusb_src commit c61f5f4, it includes official support for USB test mode.
* FIXED: Adopted common format in error printouts of device control host drivers.

Expand Down
2 changes: 1 addition & 1 deletion modules/sw_services/device_control/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ else()
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
target_link_directories(framework_rtos_sw_services_device_control_host_usb INTERFACE "host/libusb/Win32")
set(libusb-1.0_INCLUDE_DIRS "host/libusb/Win32")
set(LINK_LIBS libusb)
set(LINK_LIBS libusb-1.0)
endif()

target_sources(framework_rtos_sw_services_device_control_host_usb
Expand Down
102 changes: 6 additions & 96 deletions modules/sw_services/device_control/host/device_access_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@
typedef enum { false = 0, true = 1} bool;
#endif // MSC
#include <stdlib.h>
#ifdef _WIN32
#ifdef WIN32
#include <windows.h>
#include "usb.h"
#else
#include <unistd.h>
#include <libusb.h>
#endif
#include <libusb.h>
#include "device_control_host.h"
#include "control_host_support.h"
#include "util.h"
Expand All @@ -25,11 +24,7 @@ typedef enum { false = 0, true = 1} bool;

static unsigned num_commands = 0;

#ifdef _WIN32
static usb_dev_handle *devh = NULL;
#else
static libusb_device_handle *devh = NULL;
#endif

static const int sync_timeout_ms = 500;

Expand All @@ -39,7 +34,7 @@ static const int sync_timeout_ms = 500;
void debug_libusb_error(int err_code)
{
#if defined _WIN32
PRINT_ERROR("libusb_control_transfer returned %s\n", usb_strerror());
PRINT_ERROR("libusb_control_transfer returned %s\n", libusb_error_name(errno));
#elif defined __APPLE__
PRINT_ERROR("libusb_control_transfer returned %s\n", libusb_error_name(err_code));
#elif defined __linux
Expand All @@ -59,15 +54,9 @@ control_ret_t control_query_version(control_version_t *version)
DBG(printf("%u: send version command: 0x%04x 0x%04x 0x%04x\n",
num_commands, windex, wvalue, wlength));

#ifdef _WIN32
int ret = usb_control_msg(devh,
USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, wvalue, windex, (char*)request_data, wlength, sync_timeout_ms);
#else
int ret = libusb_control_transfer(devh,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
0, wvalue, windex, request_data, wlength, sync_timeout_ms);
#endif

num_commands++;

Expand Down Expand Up @@ -123,15 +112,9 @@ control_write_command(control_resid_t resid, control_cmd_t cmd,
num_commands, windex, wvalue, wlength));
DBG(print_bytes(payload, payload_len));

#ifdef _WIN32
int ret = usb_control_msg(devh,
USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, wvalue, windex, (char*)payload, wlength, sync_timeout_ms);
#else
int ret = libusb_control_transfer(devh,
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
0, wvalue, windex, (unsigned char*)payload, wlength, sync_timeout_ms);
#endif

num_commands++;

Expand All @@ -145,15 +128,9 @@ control_write_command(control_resid_t resid, control_cmd_t cmd,
control_usb_fill_header(&windex, &wvalue, &wlength,
resid, CONTROL_CMD_SET_WRITE(cmd), 1);

#ifdef _WIN32
ret = usb_control_msg(devh,
USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, wvalue, windex, (char*)&status, wlength, sync_timeout_ms);
#else
ret = libusb_control_transfer(devh,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
0, wvalue, windex, &status, wlength, sync_timeout_ms);
#endif

if (ret != (int)1) {
debug_libusb_error(ret);
Expand All @@ -178,15 +155,9 @@ control_read_command(control_resid_t resid, control_cmd_t cmd,
DBG(printf("%u: send read command: 0x%04x 0x%04x 0x%04x\n",
num_commands, windex, wvalue, wlength));

#ifdef _WIN32
int ret = usb_control_msg(devh,
USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, wvalue, windex, (char*)payload, wlength, sync_timeout_ms);
#else
int ret = libusb_control_transfer(devh,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
0, wvalue, windex, payload, wlength, sync_timeout_ms);
#endif

num_commands++;

Expand All @@ -201,66 +172,6 @@ control_read_command(control_resid_t resid, control_cmd_t cmd,
return CONTROL_SUCCESS;
}

#ifdef _WIN32

static control_ret_t find_xmos_device(int vendor_id, int product_id)
{
for (struct usb_bus *bus = usb_get_busses(); bus && !devh; bus = bus->next) {
for (struct usb_device *dev = bus->devices; dev; dev = dev->next) {
if ((dev->descriptor.idVendor == vendor_id) &&
(dev->descriptor.idProduct == product_id)) {
devh = usb_open(dev);
if (!devh) {
PRINT_ERROR("Failed to open device\n");
return CONTROL_ERROR;
}
break;
}
}
}

if (!devh) {
PRINT_ERROR("Could not find device\n");
return CONTROL_ERROR;
}

return CONTROL_SUCCESS;
}

control_ret_t control_init_usb(int vendor_id, int product_id, int interface_num)
{
usb_init();
usb_find_busses(); /* find all busses */
usb_find_devices(); /* find all connected devices */

if (find_xmos_device(vendor_id, product_id) != CONTROL_SUCCESS)
return CONTROL_ERROR;

int r = usb_set_configuration(devh, 1);
if (r < 0) {
PRINT_ERROR("Setting config 1\n");
usb_close(devh);
return CONTROL_ERROR;
}

r = usb_claim_interface(devh, interface_num);
if (r < 0) {
PRINT_ERROR("Claiming interface %d %d\n", interface_num, r);
return CONTROL_ERROR;
}

return CONTROL_SUCCESS;
}

control_ret_t control_cleanup_usb(void)
{
usb_release_interface(devh, 0);
usb_close(devh);
return CONTROL_SUCCESS;
}

#else

control_ret_t control_init_usb(int vendor_id, int product_id, int interface_num)
{
int ret = libusb_init(NULL);
Expand All @@ -283,12 +194,13 @@ control_ret_t control_init_usb(int vendor_id, int product_id, int interface_num)
}

if (dev == NULL) {
PRINT_ERROR("Could not find device\n");
// Do not add any error printout here.
// This case will be called multiple times when searching for a list of devices.
return CONTROL_ERROR;
}

if (libusb_open(dev, &devh) < 0) {
PRINT_ERROR("Failed to open device. Ensure adequate permissions\n");
PRINT_ERROR("Failed to open device. Ensure adequate permissions if using Linux,\nor remove any pre-installed drivers with Device Manager on Windows.\n");
return CONTROL_ERROR;
}

Expand All @@ -305,6 +217,4 @@ control_ret_t control_cleanup_usb(void)
return CONTROL_SUCCESS;
}

#endif // _WIN32

#endif // USE_USB
42 changes: 42 additions & 0 deletions modules/sw_services/device_control/host/libusb/Win32/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Generating Required Files

This guide outlines the steps to generate necessary files in this folder using a Windows environment.

## Prerequisites

- Windows operating system
- Visual Studio 2022 with Visual Studio tools installed

## Instructions

1. **Install Visual Studio 2022 Tools**: Ensure that Visual Studio 2022 is installed with the necessary tools for C/C++ development.

2. **Download libusb-1.0 Source Code**:
- Navigate to the [libusb GitHub repository](https://github.com/libusb/libusb) and download the source code for version 1.0.27 as a ZIP file from [this link](https://github.com/libusb/libusb/archive/refs/tags/v1.0.27.zip).

3. **Extract the ZIP Archive**:
- Unzip the downloaded archive to a convenient location on your machine.

4. **Copy Header File**:
- Locate the `libusb.h` file in the extracted folder at `libusb-1.0.27\libusb`.
- Copy `libusb.h` to the folder where you want the generated files to reside.

5. **Open Command Prompt**:
- Open an "x86 Native Tools Command Prompt for VS 2022". This can be found in the Start Menu under Visual Studio 2022 Tools.

6. **Build libusb**:
- Navigate to the `msvc` directory within the extracted `libusb-1.0.27` folder.
- Execute the following command to build libusb:
```
msbuild -p:PlatformToolset=v143,Platform=win32,Configuration=Release libusb.sln
```
- This command compiles the libusb solution using the Visual Studio 2022 (v143) toolset for the Win32 platform in Release configuration.
7. **Copy Generated Library**:
- After the build completes, locate the generated `libusb-1.0.lib` file in `libusb-1.0.27\build\v143\Win32\Release\lib`.
- Copy `libusb-1.0.lib` to the folder where you want the generated files to reside.
## Notes
- Ensure that you have administrative rights if you encounter permission issues during these steps.
- For any issues related to Visual Studio tools or the build process, refer to the Visual Studio 2022 documentation or the libusb GitHub repository's issue tracker.
Binary file not shown.
Loading

0 comments on commit 6fb6fb3

Please sign in to comment.