Porting teensy-loader-cli to use libusb-1.0 (from 0.1).
- Currently only Linux tested.
This commit is contained in:
parent
a82d239efc
commit
cc3f062875
@ -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}" )
|
||||||
|
@ -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} )
|
||||||
|
|
||||||
|
@ -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 ()
|
||||||
|
|
@ -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
1
README
@ -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.
|
||||||
|
@ -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" )
|
||||||
|
Reference in New Issue
Block a user