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
|
||||
#| "arm" # Teensy 3.0
|
||||
#| "arm" # Teensy 3.1
|
||||
set( COMPILER_FAMILY "arm" )
|
||||
#set( COMPILER_FAMILY "avr" )
|
||||
#set( COMPILER_FAMILY "arm" )
|
||||
set( COMPILER_FAMILY "avr" )
|
||||
|
||||
message( STATUS "Compiler Family:" )
|
||||
message( "${COMPILER_FAMILY}" )
|
||||
|
@ -48,7 +48,7 @@ list( APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR} ) # Use local find scripts
|
||||
#| Linux - libusb
|
||||
if( CMAKE_SYSTEM_NAME MATCHES "Linux" )
|
||||
# Find libusb (not 1.0)
|
||||
find_package( LibUSB REQUIRED )
|
||||
find_package( LibUSB-1.0 REQUIRED )
|
||||
|
||||
# Defines
|
||||
set( DEFINES -s -DUSE_LIBUSB )
|
||||
@ -94,7 +94,7 @@ endif()
|
||||
#
|
||||
|
||||
#| Default CFLAGS
|
||||
set( CFLAGS -O2 -Wall )
|
||||
set( CFLAGS -O2 -Wall -std=gnu99 )
|
||||
|
||||
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_INCLUDE_DIRS - the libusb include directory
|
||||
@ -48,18 +48,20 @@ if ( LIBUSB_LIBRARIES AND LIBUSB_INCLUDE_DIRS )
|
||||
else ()
|
||||
find_path( LIBUSB_INCLUDE_DIR
|
||||
NAMES
|
||||
usb.h
|
||||
libusb.h
|
||||
PATHS
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
/include
|
||||
PATH_SUFFIXES
|
||||
libusb-1.0
|
||||
)
|
||||
|
||||
find_library( LIBUSB_LIBRARY
|
||||
NAMES
|
||||
usb
|
||||
usb-1.0
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
@ -83,7 +85,7 @@ else ()
|
||||
endif ()
|
||||
else ()
|
||||
if ( LIBUSB_FIND_REQUIRED )
|
||||
message( FATAL_ERROR "Could not find libusb" )
|
||||
message( FATAL_ERROR "Could not find libusb-1.0" )
|
||||
endif ()
|
||||
endif ()
|
||||
|
@ -198,106 +198,137 @@ int main(int argc, char **argv)
|
||||
|
||||
#if defined(USE_LIBUSB)
|
||||
|
||||
// http://libusb.sourceforge.net/doc/index.html
|
||||
#include <usb.h>
|
||||
#include <libusb-1.0/libusb.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;
|
||||
struct usb_device *dev;
|
||||
usb_dev_handle *h;
|
||||
char buf[128];
|
||||
int r;
|
||||
libusb_device **devs;
|
||||
struct libusb_device_handle *handle = NULL;
|
||||
struct libusb_device_handle *ret = NULL;
|
||||
|
||||
usb_init();
|
||||
usb_find_busses();
|
||||
usb_find_devices();
|
||||
//printf_verbose("\nSearching for USB device:\n");
|
||||
for (bus = usb_get_busses(); bus; bus = bus->next) {
|
||||
for (dev = bus->devices; dev; dev = dev->next) {
|
||||
//printf_verbose("bus \"%s\", device \"%s\" vid=%04X, pid=%04X\n",
|
||||
// bus->dirname, dev->filename,
|
||||
// dev->descriptor.idVendor,
|
||||
// dev->descriptor.idProduct
|
||||
//);
|
||||
if (dev->descriptor.idVendor != vid) continue;
|
||||
if (dev->descriptor.idProduct != pid) continue;
|
||||
h = usb_open(dev);
|
||||
if (!h) {
|
||||
printf_verbose("Found device but unable to open");
|
||||
continue;
|
||||
}
|
||||
#ifdef LIBUSB_HAS_GET_DRIVER_NP
|
||||
r = usb_get_driver_np(h, 0, buf, sizeof(buf));
|
||||
if (r >= 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
|
||||
// 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
|
||||
r = usb_claim_interface(h, 0);
|
||||
if (r < 0) {
|
||||
usb_close(h);
|
||||
printf_verbose("Unable to claim interface, check USB permissions");
|
||||
continue;
|
||||
}
|
||||
return h;
|
||||
if ( libusb_init( NULL ) != 0 )
|
||||
fprintf( stderr, "libusb_init failed.\n" );
|
||||
|
||||
size_t count = libusb_get_device_list( NULL, &devs );
|
||||
if ( count < 0 )
|
||||
fprintf( stderr, "libusb_get_device_list failed.\n" );
|
||||
|
||||
for ( size_t c = 0; c < count; c++ )
|
||||
{
|
||||
struct libusb_device_descriptor desc;
|
||||
libusb_device *dev = devs[c];
|
||||
|
||||
if ( libusb_get_device_descriptor( dev, &desc ) < 0 )
|
||||
fprintf( stderr, "libusb_get_device_descriptor failed.\n" );
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
// Only required on Linux, other platforms will just ignore this call
|
||||
libusb_detach_kernel_driver( handle, 0 );
|
||||
|
||||
// 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.
|
||||
// normally Apple's IOKit should be used on Mac OS-X
|
||||
// XXX Is this still valid with libusb-1.0?
|
||||
|
||||
// Attempt to claim interface
|
||||
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;
|
||||
}
|
||||
|
||||
ret = handle;
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
|
||||
libusb_free_device_list( devs, 1 );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static usb_dev_handle *libusb_teensy_handle = NULL;
|
||||
static struct libusb_device_handle *libusb_teensy_handle = NULL;
|
||||
|
||||
int teensy_open(void)
|
||||
int teensy_open()
|
||||
{
|
||||
teensy_close();
|
||||
libusb_teensy_handle = open_usb_device(0x16C0, 0x0478);
|
||||
if (libusb_teensy_handle) return 1;
|
||||
|
||||
libusb_teensy_handle = open_usb_device( 0x16C0, 0x0478 );
|
||||
|
||||
if ( libusb_teensy_handle )
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int teensy_write(void *buf, int len, double timeout)
|
||||
int teensy_write( void *buf, int len, double timeout )
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!libusb_teensy_handle) return 0;
|
||||
while (timeout > 0) {
|
||||
r = usb_control_msg(libusb_teensy_handle, 0x21, 9, 0x0200, 0,
|
||||
(char *)buf, len, (int)(timeout * 1000.0));
|
||||
if (r >= 0) return 1;
|
||||
if ( !libusb_teensy_handle )
|
||||
return 0;
|
||||
|
||||
while ( timeout > 0 ) {
|
||||
r = libusb_control_transfer( libusb_teensy_handle,
|
||||
0x21, 9, 0x0200, 0,
|
||||
(unsigned char *)buf, len,
|
||||
(int)(timeout * 1000.0) );
|
||||
|
||||
if ( r >= 0 )
|
||||
return 1;
|
||||
|
||||
//printf("teensy_write, r=%d\n", r);
|
||||
usleep(10000);
|
||||
usleep( 10000 );
|
||||
timeout -= 0.01; // TODO: subtract actual elapsed time
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void teensy_close(void)
|
||||
void teensy_close()
|
||||
{
|
||||
if (!libusb_teensy_handle) return;
|
||||
usb_release_interface(libusb_teensy_handle, 0);
|
||||
usb_close(libusb_teensy_handle);
|
||||
if ( !libusb_teensy_handle)
|
||||
return;
|
||||
|
||||
libusb_release_interface( libusb_teensy_handle, 0 );
|
||||
libusb_close( libusb_teensy_handle );
|
||||
|
||||
libusb_teensy_handle = NULL;
|
||||
}
|
||||
|
||||
int hard_reboot(void)
|
||||
int hard_reboot()
|
||||
{
|
||||
usb_dev_handle *rebootor;
|
||||
struct libusb_device_handle *rebootor;
|
||||
int r;
|
||||
|
||||
rebootor = open_usb_device(0x16C0, 0x0477);
|
||||
if (!rebootor) return 0;
|
||||
r = usb_control_msg(rebootor, 0x21, 9, 0x0200, 0, "reboot", 6, 100);
|
||||
usb_release_interface(rebootor, 0);
|
||||
usb_close(rebootor);
|
||||
if (r < 0) return 0;
|
||||
rebootor = open_usb_device( 0x16C0, 0x0477 );
|
||||
|
||||
if (!rebootor)
|
||||
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;
|
||||
}
|
||||
|
||||
|
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)
|
||||
- cmake
|
||||
- gcc-core
|
||||
- gcc-g++ or gcc-c++
|
||||
|
||||
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.
|
||||
|
@ -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
|
||||
|
||||
##| 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
|
||||
set( MacroModule "PartialMap" )
|
||||
|
Reference in New Issue
Block a user