Archived
1
0

Porting teensy-loader-cli to use libusb-1.0 (from 0.1).

- Currently only Linux tested.
This commit is contained in:
Jacob Alexander 2014-04-18 00:18:02 -07:00
parent a82d239efc
commit cc3f062875
6 changed files with 113 additions and 81 deletions

View File

@ -25,8 +25,8 @@ set( CMAKE_USE_RELATIVE_PATHS 1 )
#| "avr" # Teensy++ 2.0 #| "avr" # Teensy++ 2.0
#| "arm" # Teensy 3.0 #| "arm" # Teensy 3.0
#| "arm" # Teensy 3.1 #| "arm" # Teensy 3.1
set( COMPILER_FAMILY "arm" ) #set( COMPILER_FAMILY "arm" )
#set( COMPILER_FAMILY "avr" ) set( COMPILER_FAMILY "avr" )
message( STATUS "Compiler Family:" ) message( STATUS "Compiler Family:" )
message( "${COMPILER_FAMILY}" ) message( "${COMPILER_FAMILY}" )

View File

@ -48,7 +48,7 @@ list( APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR} ) # Use local find scripts
#| Linux - libusb #| Linux - libusb
if( CMAKE_SYSTEM_NAME MATCHES "Linux" ) if( CMAKE_SYSTEM_NAME MATCHES "Linux" )
# Find libusb (not 1.0) # Find libusb (not 1.0)
find_package( LibUSB REQUIRED ) find_package( LibUSB-1.0 REQUIRED )
# Defines # Defines
set( DEFINES -s -DUSE_LIBUSB ) set( DEFINES -s -DUSE_LIBUSB )
@ -94,7 +94,7 @@ endif()
# #
#| Default CFLAGS #| Default CFLAGS
set( CFLAGS -O2 -Wall ) set( CFLAGS -O2 -Wall -std=gnu99 )
add_definitions( ${CFLAGS} ${DEFINES} ) add_definitions( ${CFLAGS} ${DEFINES} )

View File

@ -1,4 +1,4 @@
# Attempts to find libusb (not libusb-1.0) # Attempts to find libusb-1.0
# #
# LIBUSB_FOUND - system has libusb # LIBUSB_FOUND - system has libusb
# LIBUSB_INCLUDE_DIRS - the libusb include directory # LIBUSB_INCLUDE_DIRS - the libusb include directory
@ -48,18 +48,20 @@ if ( LIBUSB_LIBRARIES AND LIBUSB_INCLUDE_DIRS )
else () else ()
find_path( LIBUSB_INCLUDE_DIR find_path( LIBUSB_INCLUDE_DIR
NAMES NAMES
usb.h libusb.h
PATHS PATHS
/usr/include /usr/include
/usr/local/include /usr/local/include
/opt/local/include /opt/local/include
/sw/include /sw/include
/include /include
PATH_SUFFIXES
libusb-1.0
) )
find_library( LIBUSB_LIBRARY find_library( LIBUSB_LIBRARY
NAMES NAMES
usb usb-1.0
PATHS PATHS
/usr/lib /usr/lib
/usr/local/lib /usr/local/lib
@ -83,7 +85,7 @@ else ()
endif () endif ()
else () else ()
if ( LIBUSB_FIND_REQUIRED ) if ( LIBUSB_FIND_REQUIRED )
message( FATAL_ERROR "Could not find libusb" ) message( FATAL_ERROR "Could not find libusb-1.0" )
endif () endif ()
endif () endif ()

View File

@ -198,68 +198,78 @@ int main(int argc, char **argv)
#if defined(USE_LIBUSB) #if defined(USE_LIBUSB)
// http://libusb.sourceforge.net/doc/index.html #include <libusb-1.0/libusb.h>
#include <usb.h>
usb_dev_handle * open_usb_device(int vid, int pid) struct libusb_device_handle *open_usb_device( int vid, int pid )
{ {
struct usb_bus *bus; libusb_device **devs;
struct usb_device *dev; struct libusb_device_handle *handle = NULL;
usb_dev_handle *h; struct libusb_device_handle *ret = NULL;
char buf[128];
int r;
usb_init(); if ( libusb_init( NULL ) != 0 )
usb_find_busses(); fprintf( stderr, "libusb_init failed.\n" );
usb_find_devices();
//printf_verbose("\nSearching for USB device:\n"); size_t count = libusb_get_device_list( NULL, &devs );
for (bus = usb_get_busses(); bus; bus = bus->next) { if ( count < 0 )
for (dev = bus->devices; dev; dev = dev->next) { fprintf( stderr, "libusb_get_device_list failed.\n" );
//printf_verbose("bus \"%s\", device \"%s\" vid=%04X, pid=%04X\n",
// bus->dirname, dev->filename, for ( size_t c = 0; c < count; c++ )
// dev->descriptor.idVendor, {
// dev->descriptor.idProduct struct libusb_device_descriptor desc;
//); libusb_device *dev = devs[c];
if (dev->descriptor.idVendor != vid) continue;
if (dev->descriptor.idProduct != pid) continue; if ( libusb_get_device_descriptor( dev, &desc ) < 0 )
h = usb_open(dev); fprintf( stderr, "libusb_get_device_descriptor failed.\n" );
if (!h) {
printf_verbose("Found device but unable to open"); //printf("ID: %04x Product: %04x\n", desc.idVendor, desc.idProduct );
// Not correct device
if ( desc.idVendor != vid || desc.idProduct != pid )
continue;
// Attempt to open the device
if ( libusb_open( dev, &handle ) != 0 )
{
fprintf( stderr, "Found device but unable to open\n" );
continue; continue;
} }
#ifdef LIBUSB_HAS_GET_DRIVER_NP
r = usb_get_driver_np(h, 0, buf, sizeof(buf)); // Only required on Linux, other platforms will just ignore this call
if (r >= 0) { libusb_detach_kernel_driver( handle, 0 );
r = usb_detach_kernel_driver_np(h, 0);
if (r < 0) {
usb_close(h);
printf_verbose("Device is in use by \"%s\" driver", buf);
continue;
}
}
#endif
// Mac OS-X - removing this call to usb_claim_interface() might allow // Mac OS-X - removing this call to usb_claim_interface() might allow
// this to work, even though it is a clear misuse of the libusb API. // this to work, even though it is a clear misuse of the libusb API.
// normally Apple's IOKit should be used on Mac OS-X // normally Apple's IOKit should be used on Mac OS-X
r = usb_claim_interface(h, 0); // XXX Is this still valid with libusb-1.0?
if (r < 0) {
usb_close(h); // Attempt to claim interface
printf_verbose("Unable to claim interface, check USB permissions"); int err = libusb_claim_interface( handle, 0 );
if ( err < 0 )
{
libusb_close( handle );
fprintf( stderr, "Unable to claim interface, check USB permissions: %d\n", err );
continue; continue;
} }
return h;
} ret = handle;
} break;
return NULL;
} }
static usb_dev_handle *libusb_teensy_handle = NULL; libusb_free_device_list( devs, 1 );
int teensy_open(void) return ret;
}
static struct libusb_device_handle *libusb_teensy_handle = NULL;
int teensy_open()
{ {
teensy_close(); teensy_close();
libusb_teensy_handle = open_usb_device( 0x16C0, 0x0478 ); libusb_teensy_handle = open_usb_device( 0x16C0, 0x0478 );
if (libusb_teensy_handle) return 1;
if ( libusb_teensy_handle )
return 1;
return 0; return 0;
} }
@ -267,37 +277,58 @@ int teensy_write(void *buf, int len, double timeout)
{ {
int r; int r;
if (!libusb_teensy_handle) return 0; if ( !libusb_teensy_handle )
return 0;
while ( timeout > 0 ) { while ( timeout > 0 ) {
r = usb_control_msg(libusb_teensy_handle, 0x21, 9, 0x0200, 0, r = libusb_control_transfer( libusb_teensy_handle,
(char *)buf, len, (int)(timeout * 1000.0)); 0x21, 9, 0x0200, 0,
if (r >= 0) return 1; (unsigned char *)buf, len,
(int)(timeout * 1000.0) );
if ( r >= 0 )
return 1;
//printf("teensy_write, r=%d\n", r); //printf("teensy_write, r=%d\n", r);
usleep( 10000 ); usleep( 10000 );
timeout -= 0.01; // TODO: subtract actual elapsed time timeout -= 0.01; // TODO: subtract actual elapsed time
} }
return 0; return 0;
} }
void teensy_close(void) void teensy_close()
{ {
if (!libusb_teensy_handle) return; if ( !libusb_teensy_handle)
usb_release_interface(libusb_teensy_handle, 0); return;
usb_close(libusb_teensy_handle);
libusb_release_interface( libusb_teensy_handle, 0 );
libusb_close( libusb_teensy_handle );
libusb_teensy_handle = NULL; libusb_teensy_handle = NULL;
} }
int hard_reboot(void) int hard_reboot()
{ {
usb_dev_handle *rebootor; struct libusb_device_handle *rebootor;
int r; int r;
rebootor = open_usb_device( 0x16C0, 0x0477 ); rebootor = open_usb_device( 0x16C0, 0x0477 );
if (!rebootor) return 0;
r = usb_control_msg(rebootor, 0x21, 9, 0x0200, 0, "reboot", 6, 100); if (!rebootor)
usb_release_interface(rebootor, 0); return 0;
usb_close(rebootor);
if (r < 0) return 0; r = libusb_control_transfer( rebootor,
0x21, 9, 0x0200, 0,
(unsigned char*)"reboot", 6,
100 );
libusb_release_interface( rebootor, 0 );
libusb_close( rebootor );
if (r < 0)
return 0;
return 1; return 1;
} }

1
README
View File

@ -45,7 +45,6 @@ First make sure Cygwin is installed - http://www.cygwin.com/ - 32bit or 64bit is
- git (needed for some compilation info) - git (needed for some compilation info)
- cmake - cmake
- gcc-core - gcc-core
- gcc-g++ or gcc-c++
And make sure CMake is *NOT* installed through Cygwin. This is extremely important. And make sure CMake is *NOT* installed through Cygwin. This is extremely important.
If this is not possible, you'll have to play with your paths in Cygwin to prioritize the Windows version of CMake. If this is not possible, you'll have to play with your paths in Cygwin to prioritize the Windows version of CMake.

View File

@ -20,7 +20,7 @@
#| Please look at the {Scan,Macro,USB,Debug}/module.txt for information on the modules and how to create new ones #| Please look at the {Scan,Macro,USB,Debug}/module.txt for information on the modules and how to create new ones
##| Deals with acquiring the keypress information and turning it into a key index ##| Deals with acquiring the keypress information and turning it into a key index
set( ScanModule "ADCTest" ) set( ScanModule "DPH" )
##| Provides the mapping functions for DefaultMap and handles any macro processing before sending to the OutputModule ##| Provides the mapping functions for DefaultMap and handles any macro processing before sending to the OutputModule
set( MacroModule "PartialMap" ) set( MacroModule "PartialMap" )