@@ -41,6 +41,7 @@ void usage(const char *err)
4141 "\t-w : Wait for device to appear\n"
4242 "\t-r : Use hard reboot if device not online\n"
4343 "\t-s : Use soft reboot if device not online (Teensy3.x only)\n"
44+ "\t--serial-number=SERIAL_NUMBER : Serial number to use in conjunction with soft reboot (UNIX only).\n"
4445 "\t-n : No reboot after programming\n"
4546 "\t-b : Boot only, do not program\n"
4647 "\t-v : Verbose output\n"
@@ -74,6 +75,7 @@ void boot(unsigned char *buf, int write_size);
7475int wait_for_device_to_appear = 0 ;
7576int hard_reboot_device = 0 ;
7677int soft_reboot_device = 0 ;
78+ const char * soft_reboot_serial_number = NULL ;
7779int reboot_after_programming = 1 ;
7880int verbose = 0 ;
7981int boot_only = 0 ;
@@ -227,13 +229,14 @@ int main(int argc, char **argv)
227229// http://libusb.sourceforge.net/doc/index.html
228230#include <usb.h>
229231
230- usb_dev_handle * open_usb_device (int vid , int pid )
232+ usb_dev_handle * open_usb_device (int vid , int pid , const char * serial_number )
231233{
232234 struct usb_bus * bus ;
233235 struct usb_device * dev ;
234236 usb_dev_handle * h ;
235237 char buf [128 ];
236- int r ;
238+ const char * read_serial_number = NULL ;
239+ int r , i ;
237240
238241 usb_init ();
239242 usb_find_busses ();
@@ -253,6 +256,33 @@ usb_dev_handle * open_usb_device(int vid, int pid)
253256 printf_verbose ("Found device but unable to open\n" );
254257 continue ;
255258 }
259+
260+ if (serial_number != NULL ) {
261+ if (dev -> descriptor .iSerialNumber ) {
262+ // langid 0x0409 is English US
263+ r = usb_get_string (h , dev -> descriptor .iSerialNumber , 0x0409 , buf , 128 );
264+ if (r < 0 ) {
265+ usb_close (h );
266+ continue ;
267+ }
268+ // Seemsl like 16 bit wide chars are being sent
269+ for (i = 0 ; i < r /2 ; i ++ ){
270+ buf [i ] = buf [i * 2 ];
271+ }
272+ // The first char seems to be of value 16
273+ // meaning DATA LINK ESCAPE. Who knows what that means???
274+ read_serial_number = & buf [1 ];
275+ } else {
276+ // No serial number
277+ usb_close (h );
278+ continue ;
279+ }
280+ if (strncmp (serial_number , read_serial_number , strlen (serial_number ))) {
281+ // Serial number doesn't match
282+ usb_close (h );
283+ continue ;
284+ }
285+ }
256286 #ifdef LIBUSB_HAS_GET_DRIVER_NP
257287 r = usb_get_driver_np (h , 0 , buf , sizeof (buf ));
258288 if (r >= 0 ) {
@@ -287,7 +317,7 @@ static usb_dev_handle *libusb_teensy_handle = NULL;
287317int teensy_open (void )
288318{
289319 teensy_close ();
290- libusb_teensy_handle = open_usb_device (0x16C0 , 0x0478 );
320+ libusb_teensy_handle = open_usb_device (0x16C0 , 0x0478 , NULL );
291321 if (libusb_teensy_handle ) return 1 ;
292322 return 0 ;
293323}
@@ -321,7 +351,7 @@ int hard_reboot(void)
321351 usb_dev_handle * rebootor ;
322352 int r ;
323353
324- rebootor = open_usb_device (0x16C0 , 0x0477 );
354+ rebootor = open_usb_device (0x16C0 , 0x0477 , NULL );
325355 if (!rebootor ) return 0 ;
326356 r = usb_control_msg (rebootor , 0x21 , 9 , 0x0200 , 0 , "reboot" , 6 , 100 );
327357 usb_release_interface (rebootor , 0 );
@@ -334,7 +364,7 @@ int soft_reboot(void)
334364{
335365 usb_dev_handle * serial_handle = NULL ;
336366
337- serial_handle = open_usb_device (0x16C0 , 0x0483 );
367+ serial_handle = open_usb_device (0x16C0 , 0x0483 , soft_reboot_serial_number );
338368 if (!serial_handle ) {
339369 char * error = usb_strerror ();
340370 printf ("Error opening USB device: %s\n" , error );
@@ -373,6 +403,8 @@ int soft_reboot(void)
373403#include <ddk/hidsdi.h>
374404#include <ddk/hidclass.h>
375405
406+ // Serial number checking not implemented on Windows
407+ // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/hidsdi/nf-hidsdi-hidd_getserialnumberstring
376408HANDLE open_usb_device (int vid , int pid )
377409{
378410 GUID guid ;
@@ -1149,7 +1181,6 @@ void parse_options(int argc, char **argv)
11491181 if (strncmp (arg , "-mmcu=" , 6 ) == 0 ) {
11501182 read_mcu (strchr (arg , '=' ) + 1 );
11511183 }
1152-
11531184 else if (arg [0 ] == '-' ) {
11541185 if (arg [1 ] == '-' ) {
11551186 char * name = & arg [2 ];
@@ -1167,6 +1198,9 @@ void parse_options(int argc, char **argv)
11671198 if (strcasecmp (name , "help" ) == 0 ) usage (NULL );
11681199 else if (strcasecmp (name , "mcu" ) == 0 ) read_mcu (val );
11691200 else if (strcasecmp (name , "list-mcus" ) == 0 ) list_mcus ();
1201+ else if (strcasecmp (name , "serial-number" ) == 0 ) {
1202+ soft_reboot_serial_number = val ;
1203+ }
11701204 else {
11711205 fprintf (stderr , "Unknown option \"%s\"\n\n" , arg );
11721206 usage (NULL );
0 commit comments