Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add options --vid=<VID> --pid=<PID> --serial=<SERIAL> for soft reset with libusb #65

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Teensy Loader - Command Line Version#
# Teensy Loader - Command Line Version with options to set VID, PID, and serial number

The Teensy Loader is available in a command line version for advanced users who want to automate programming, typically using a Makefile. For most uses, the graphical version in Automatic Mode is much easier.

Expand Down Expand Up @@ -61,6 +61,12 @@ Optional command line parameters:

`-v` : Verbose output. Normally teensy_loader_cli prints only error messages if any operation fails. This enables verbose output, which can help with troubleshooting, or simply show you more status information.

`--vid=<VID>` : (only with libusb) Specify the Vendor ID to match for sending the soft reset.

`--pid=<PID>` : (only with libusb) Specify the Product ID to match for sending the soft reset.

`--serial=<SERIAL>` : (only with libusb) Specify the serial number to match for sending the soft reset.

## System Specific Setup

Linux requires UDEV rules for non-root users.
Expand Down
37 changes: 29 additions & 8 deletions teensy_loader_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ void usage(const char *err)
{
if(err != NULL) fprintf(stderr, "%s\n\n", err);
fprintf(stderr,
"Usage: teensy_loader_cli --mcu=<MCU> [-w] [-h] [-n] [-b] [-v] <file.hex>\n"
"Usage: teensy_loader_cli --mcu=<MCU> [--vid=<VID>] [--pid=<PID>] [--serial=<SERIAL>] [-w] [-h] [-n] [-b] [-v] <file.hex>\n"
"\t-w : Wait for device to appear\n"
"\t-r : Use hard reboot if device not online\n"
"\t-s : Use soft reboot if device not online (Teensy 3.x & 4.x)\n"
Expand Down Expand Up @@ -78,6 +78,11 @@ int reboot_after_programming = 1;
int verbose = 0;
int boot_only = 0;
int code_size = 0, block_size = 0;
int hard_vid = 0x16C0;
int hard_pid = 0x0477;
int soft_vid = 0x16C0;
int soft_pid = 0x0483;
char *opt_serial = NULL;
const char *filename=NULL;


Expand Down Expand Up @@ -227,13 +232,14 @@ int main(int argc, char **argv)
// http://libusb.sourceforge.net/doc/index.html
#include <usb.h>

usb_dev_handle * open_usb_device(int vid, int pid)
usb_dev_handle * open_usb_device(int vid, int pid, char *serial)
{
struct usb_bus *bus;
struct usb_device *dev;
usb_dev_handle *h;
char buf[128];
int r;
char string[256];

usb_init();
usb_find_busses();
Expand All @@ -253,6 +259,18 @@ usb_dev_handle * open_usb_device(int vid, int pid)
printf_verbose("Found device but unable to open\n");
continue;
}
if (serial) {
if (dev->descriptor.iSerialNumber) {
int ret = usb_get_string_simple(h, dev->descriptor.iSerialNumber, string, sizeof(string));
if (ret > 0) {
printf("Serial Number: %s\n", string);
if (strcmp(serial, string)) {
usb_close(h);
continue;
}
}
}
}
#ifdef LIBUSB_HAS_GET_DRIVER_NP
r = usb_get_driver_np(h, 0, buf, sizeof(buf));
if (r >= 0) {
Expand Down Expand Up @@ -287,7 +305,7 @@ static usb_dev_handle *libusb_teensy_handle = NULL;
int teensy_open(void)
{
teensy_close();
libusb_teensy_handle = open_usb_device(0x16C0, 0x0478);
libusb_teensy_handle = open_usb_device(0x16C0, 0x0478, NULL);
if (libusb_teensy_handle) return 1;
return 0;
}
Expand Down Expand Up @@ -321,7 +339,7 @@ int hard_reboot(void)
usb_dev_handle *rebootor;
int r;

rebootor = open_usb_device(0x16C0, 0x0477);
rebootor = open_usb_device(hard_vid, hard_pid, NULL);
if (!rebootor) return 0;
r = usb_control_msg(rebootor, 0x21, 9, 0x0200, 0, "reboot", 6, 100);
usb_release_interface(rebootor, 0);
Expand All @@ -334,7 +352,7 @@ int soft_reboot(void)
{
usb_dev_handle *serial_handle = NULL;

serial_handle = open_usb_device(0x16C0, 0x0483);
serial_handle = open_usb_device(soft_vid, soft_pid, opt_serial);
if (!serial_handle) {
char *error = usb_strerror();
printf("Error opening USB device: %s\n", error);
Expand Down Expand Up @@ -508,7 +526,7 @@ int hard_reboot(void)
HANDLE rebootor;
int r;

rebootor = open_usb_device(0x16C0, 0x0477);
rebootor = open_usb_device(hard_vid, hard_pid);
if (!rebootor) return 0;
r = write_usb_device(rebootor, "reboot", 6, 100);
CloseHandle(rebootor);
Expand Down Expand Up @@ -704,7 +722,7 @@ int hard_reboot(void)
IOHIDDeviceRef rebootor;
IOReturn ret;

rebootor = open_usb_device(0x16C0, 0x0477);
rebootor = open_usb_device(hard_vid, hard_pid);
if (!rebootor) return 0;
ret = IOHIDDeviceSetReport(rebootor,
kIOHIDReportTypeOutput, 0, (uint8_t *)("reboot"), 6);
Expand Down Expand Up @@ -811,7 +829,7 @@ int hard_reboot(void)
{
int r, rebootor_fd;

rebootor_fd = open_usb_device(0x16C0, 0x0477);
rebootor_fd = open_usb_device(hard_vid, hard_pid);
if (rebootor_fd < 0) return 0;
r = write(rebootor_fd, "reboot", 6);
delay(0.1);
Expand Down Expand Up @@ -1168,6 +1186,9 @@ void parse_options(int argc, char **argv)
if(strcasecmp(name, "help") == 0) usage(NULL);
else if(strcasecmp(name, "mcu") == 0) read_mcu(val);
else if(strcasecmp(name, "list-mcus") == 0) list_mcus();
else if(strcasecmp(name, "vid") == 0) hard_vid = soft_vid = strtoul(val, NULL, 16);
else if(strcasecmp(name, "pid") == 0) hard_pid = soft_pid = strtoul(val, NULL, 16);
else if(strcasecmp(name, "serial") == 0) opt_serial = val;
else {
fprintf(stderr, "Unknown option \"%s\"\n\n", arg);
usage(NULL);
Expand Down