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

Differentiate multiple USB programmers of the same VID/PID (libusb or hidapi or libftdi) #973

Closed
mcuee opened this issue May 22, 2022 · 36 comments · Fixed by #1588
Closed
Labels
enhancement New feature or request

Comments

@mcuee
Copy link
Collaborator

mcuee commented May 22, 2022

Ref: the following enhancement requests talk about usbasp

But this can be extended to other USB based programmers. If you have multiple programmers of the same types connected, the best is to differentiate them by serial number. Or you can differentiate with the Manufacturer/Product strings. Then there is another possibility is to use the locations (USB ports).

@mcuee
Copy link
Collaborator Author

mcuee commented May 22, 2022

Specific to hidapi: at least you can get the vendor_id, product_id, path, serial_number.
Ref: https://github.com/libusb/hidapi/blob/master/hidtest/test.c

@mcuee
Copy link
Collaborator Author

mcuee commented May 22, 2022

For libusb, same that you can get the vendor_id, product_id and serial_number. You can also get the path using libusb_get_bus_number and libusb_get_port_number.
https://github.com/libusb/libusb/blob/master/examples/xusb.c

@mcuee
Copy link
Collaborator Author

mcuee commented May 22, 2022

For libftdi, ftdi_usb_get_strings() can probably be used.
https://www.intra2net.com/en/developer/libftdi/documentation/ftdi_8h.html#a17e8eae09e58bd3bfeeab8decfce7fd9

@mcuee mcuee changed the title Differential multiple USB programmers of the same VID/PID (libusb or hidapi or libftdi) Differentiate multiple USB programmers of the same VID/PID (libusb or hidapi or libftdi) Jun 12, 2022
@mcuee
Copy link
Collaborator Author

mcuee commented Jun 12, 2022

Ref: OpenOCD libusb-1.0 helper may give some hints as well.
Ref: https://github.com/openocd-org/openocd/blob/master/src/jtag/drivers/libusb_helper.c

It can be done using libusb-0.1 API as well since avrdude is still mostly using libusb-0.1 API.

@mcuee mcuee added the enhancement New feature or request label Jun 19, 2022
@MikeRaffa
Copy link
Contributor

I have some working code for USBASP, specifying programmer with -P usb:xxx:xxx.

Any interest in adding this to the project?

@dl8dtl
Copy link
Contributor

dl8dtl commented Mar 8, 2023

How did you solve the multiplatform aspects? (Windows, Linux, MacOS, BSD)

@MCUdude
Copy link
Collaborator

MCUdude commented Mar 8, 2023

Any interest in adding this to the project?

It would be great if you could create a PR for this! usb_libusb.c and usb_hidapi.c already reads the serial number from the device and store this in a string, usbsn, but it looks like usbasp.c uses libusb directly.

@dl8dtl
Copy link
Contributor

dl8dtl commented Mar 8, 2023

As a remark (since I once implemented the serno matcher in stk500v2/jtag): serial numbers can sometimes be long, and it makes most sense to just match the trailing part. (OpenOCD requires the full serial number, which is hard to type when typing manually on the commandline.)

@MikeRaffa
Copy link
Contributor

Sounds like there's some value to potentially adding that. I'll do some cleanup/testing and then submit something if it looks like it's working.

I've only tested on Linux so far. I could check on Windows/Mac as well; not sure what the usblib differences are there. The method I'm using is by USB bus (usb:xxx:xxx). Not sure if serial no. is prefereable.

@dl8dtl
Copy link
Contributor

dl8dtl commented Mar 8, 2023

Using a serial number is much preferable – however, I'm afraid most (all?) USBasp implementations just don't offer a serial number at all.
For devices lacking a serial number, it might make some sense to offer alternative ways to distinguish different programmers. But then, I'm afraid every operating system needs to be treated differently.
Either case, please don't forget to update the documentation, or at least to provide a text block we can include into the documentation files. (We can handle the respective markup if you are unfamiliar with that.)

@mcuee
Copy link
Collaborator Author

mcuee commented Mar 11, 2023

For devices lacking a serial number, it might make some sense to offer alternative ways to distinguish different programmers. But then, I'm afraid every operating system needs to be treated differently.

The USB bus:port number may be another way to distinguish the devices: libusb_get_port_number() and libusb_get_port_numbers(). But then libusb-1.0 API is needed.
https://libusb.sourceforge.io/api-1.0/group__libusb__dev.html#ga14879a0ea7daccdcddb68852d86c00c4
https://github.com/libusb/libusb/blob/master/examples/listdevs.c

@mcuee
Copy link
Collaborator Author

mcuee commented Mar 11, 2023

Using a serial number is much preferable – however, I'm afraid most (all?) USBasp implementations just don't offer a serial number at all.

Indeed, unless the user is willing to rebuild the FW and program different units with different serial number.

It would be good to such FW capability to usbasp FW but then we need to have a host software as well (Microchip PICKit 2 FW and host SW have the capability to program the SN and differentiate the units).

@dioannidis
I am not so sure if you are interested to add such capability to your usbasp FW. The HID side-channel may be used to program the serial number.

@dioannidis
Copy link

@mcuee

@dioannidis I am not so sure if you are interested to add such capability to your usbasp FW. The HID side-channel may be used to program the serial number.

I already implement it. The serial number ( 4 digits only ) is stored in eeprom and one can read / write it via HID calls only ( do I need to support control requests calls also ? ) . Didn't commit it yet cause I didn't test it enough.

FYI, I choose to add, the eeprom read / write functionality, to the V-USB driver ( see obdev/v-usb#35 ) instead of using the usbFunctionDescriptor / usbFunctionSetup mechanism, because I thought that one may choose to store all the descriptors to eeprom instead of flash to save space.

I'll try to find time to test it little more and upload it ASAP .

@dioannidis
Copy link

dioannidis commented Mar 11, 2023

@mcuee, @MCUdude , @dl8dtl

Also we need to inform the avrdude that there is a serial number descriptor read / write functionality using the 4 bytes capability control request response ( USBASP_FUNC_GETCAPABILITIES ).

Currently, the capability response ( in my firmware ) uses the 1st byte to report if it supports TPI and / or HIDUART and the 2nd byte if the USBasp device uses a different crystal from the default 12MHz.

<snip>
/* USBASP capabilities */
#define USBASP_CAP_0_TPI                0x01
#define USBASP_CAP_6_UART               0x40
#define USBASP_CAP_HIDUART              0x80

#define USBASP_CAP_12MHZ_CLOCK          0x00
#define USBASP_CAP_16MHZ_CLOCK          0x01
#define USBASP_CAP_18MHZ_CLOCK          0x02
#define USBASP_CAP_20MHZ_CLOCK          0x03
<snip>

Where do you propose to add the serial number capability ?

<snip>
#define USBASP_FUNC_SETSERIALNUMBER	125
#define USBASP_FUNC_GETSERIALNUMBER	126
<snip>

Do I need to change the USBASP_FUNC_SETSERIALNUMBER, USBASP_FUNC_GETSERIALNUMBER defines to other values ?

@mcuee
Copy link
Collaborator Author

mcuee commented Mar 12, 2023

@mcuee, @MCUdude , @dl8dtl

Also we need to inform the avrdude that there is a serial number descriptor read / write functionality using the 4 bytes capability control request response ( USBASP_FUNC_GETCAPABILITIES ).

@dioannidis

I am not so sure if avrdude wants to be involved in that function of write the serial number as it is specific to your usbasp firmware. I tend to think you have to provide that functionality through your host application, outside of avrdude.

avrdude will just read the serail number of your device and utilize to differentiate different units.

Adding @stefanrueger as well in this discussion.

@mcuee
Copy link
Collaborator Author

mcuee commented Mar 12, 2023

Releavent discussion from libusb project.
libusb/libusb#1258

Take note HIDAPI provides multiple aspects of the HID device for matching the device.

Device Found
  type: 046d c52b
  path: \\?\HID#VID_046D&PID_C52B&MI_00#7&34f0fd76&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}\KBD
  serial_number:
  Manufacturer: Logitech
  Product:      USB Receiver
  Release:      1203
  Interface:    0
  Usage (page): 0x6 (0x1)
  Bus type: 1

@dl8dtl
Copy link
Contributor

dl8dtl commented Mar 12, 2023

I am not so sure if avrdude wants to be involved in that function of write the serial number as it is specific to your usbasp firmware. I tend to think you have to provide that functionality through your host application, outside of avrdude.

Me neither.

Since it's HIDAPI, I guess it would be easy enough to offer some Python implementation, and thus be quite platform independant. If I were you @dioannidis I wouldn't bother too much with capabilties: just hack a Python script that produces a semi-random serial number, and fire it to the USBasp device: if the device can handle it, it's fine. If not, the user is just at the same point where it has been before. ;-)

\?\HID#VID_046D&PID_C52B&MI_00#7&34f0fd76&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}\KBD

Pah, that would be really lengthy to type …

@dioannidis
Copy link

dioannidis commented Mar 12, 2023

@dl8dtl, @mcuee , @MCUdude , @stefanrueger

Well, I tend to think that USBasp goes hand to hand with avrdude, over 90% ( or more ) of the time. I don't think I ever used a USBasp device using other software which is not using avrdude under the hood .

As I already wrote above, I've already implemented the functionality in my USBasp fork locally and after some tests this week it will be commited .

Anyway, I thought that it will be useful if the avrdude project "dictates" / "proposes" an entry point for all the usbasp firmwares to implement the serial number change set, HIDAPI or not. That will solve the platform independent issue also ...

@MikeRaffa
Copy link
Contributor

I've looked into this a bit more and come to a couple of conclusions:

1.) The USB path method for differentiating between multiple USBASP devices isn't great for my workflow. At least on my Ubuntu VM, the -P usb:xxx:yyy doesn't correspond to physical hub/port, so it changes each bootup or when a device is plugged in. That means it's only useful within a single session and requires some experimentation to determine which USBASP is which.

2.) I reprogrammed the USBASP firmware with the code from here https://www.fischl.de/usbasp/ with a specified serial number in the firmware/usbconfig.h file, and it seemed like a relatively painless process. It does require two USBASPs (a target and another to program the firmware on the target). That's now working with my avrdude modification to allow for -P usb:xxx (where xxx is serial number).

I still have the option of specifying -P usb:xxx:yyy for the USB bus/device in my changes here, and it seems to make sense to leave that in as well for users who don't want to go to the trouble of reprogramming their USBASP. Any thoughts?

@dioannidis
Copy link

@MikeRaffa

Where can I found your avrdude patch reg. serial number ? I see no repos at https://github.com/MikeRaffa ...

@MikeRaffa
Copy link
Contributor

I haven't uploaded anything yet. Just got it working in my environment. Still need to get it working with the different libusb versions and test on Windows.

@dl8dtl
Copy link
Contributor

dl8dtl commented Mar 14, 2023

Well, there is no obligation to have everything already tested and final before uploading it to your own forked repository. ;-) So if you decide to publish your own fork, others just get the possibility to peek at your work already.

@dioannidis
Copy link

@mcuee

I uploaded a development version of the firmware ( for atmega88 ) at https://www.nephelae.eu/usbasp88.zip . Also the host app ( only for win64 ) is at https://www.nephelae.eu/vusbserialnumber-x86_64-win64.zip .

Any feedback is appreciated ...

C:\VUSBSerialNumber.exe -h

USBasp Serial Number utility (for FW https://github.com/dioannidis/usbasp )

 -l  List USBasp devices with HID support.
 -s  Serial Number to update ( 4 Digits numeric only i.e. 3456, 2222, etc ).
 -i  USBasp list index. Used with -s if there are more than one USBasp connected at the same time.

examples

Update the first found USBasp's serial number
 VUSBSerialNumber -s 1234

Update the specific USBasp's serial number using USBasp list index
 VUSBSerialNumber -i 2 -s 1234

@MikeRaffa
Copy link
Contributor

Preliminary version of -P bus/device and serial_number support for USBASP is here https://github.com/MikeRaffa/avrdude.

@mcuee
Copy link
Collaborator Author

mcuee commented Mar 15, 2023

@dioannidis

Can you provide the hex file for ATmega8A? My USBAsp unit based on ATmega88 is a bit fragile and not as robust as the ones based on ATmega8A. Thanks.

@dioannidis
Copy link

@mcuee

Can you provide the hex file for ATmega8A? My USBAsp unit based on ATmega88 is a bit fragile and not as robust as the ones based on ATmega8A. Thanks.

Of course. Here it is https://www.nephelae.eu/usbasp8.zip .

@dioannidis
Copy link

@mcuee

Please download the hex files again, because I forgot to build them for 12Mhz crystal . I have a custom usbasp board which I test various crystals and it had an 18MHz on .... Apologies ...

( don't forget this firmware implements a composite device so only the mingw build of avrdude will work .... )

@mcuee
Copy link
Collaborator Author

mcuee commented Mar 15, 2023

@dioannidis

Your FW works very well. Itested with two USBASP (Atmega8A) units.

The only minor issue is with the host software -- I need to hit a return to exit.
Edit: another issue: somehow the serial number 6666 becomes 0666.

PS C:\work\avr\avrdude_test\avrdude_bin\usbasp_sn> .\VUSBSerialNumber.exe -l

USBasp Serial Number utility (for FW https://github.com/dioannidis/usbasp )


USBasp List Index: 0

type: 16C0 05DC
path: \\?\HID#VID_16C0&PID_05DC&MI_01#7&259174a7&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
serial number: 0000
Manufacturer:  www.fischl.de
Product:       USBasp
Release:       1.10
Interface:     1

USBasp List Index: 1

type: 16C0 05DC
path: \\?\HID#VID_16C0&PID_05DC&MI_02#7&1ba36e5&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
serial number: 0000
Manufacturer:  www.fischl.de
Product:       USBasp
Release:       1.10
Interface:     2

USBasp List Index: 2

type: 16C0 05DC
path: \\?\HID#VID_16C0&PID_05DC&MI_01#7&28dd995c&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
serial number: 0888
Manufacturer:  www.fischl.de
Product:       USBasp
Release:       1.10
Interface:     1

USBasp List Index: 3

type: 16C0 05DC
path: \\?\HID#VID_16C0&PID_05DC&MI_02#7&5065b9a&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
serial number: 0888
Manufacturer:  www.fischl.de
Product:       USBasp
Release:       1.10
Interface:     2


PS C:\work\avr\avrdude_test\avrdude_bin\usbasp_sn> .\VUSBSerialNumber.exe -i 0 -s 6666

USBasp Serial Number utility (for FW https://github.com/dioannidis/usbasp )


USBasp List Index: 0

type: 16C0 05DC
path: \\?\HID#VID_16C0&PID_05DC&MI_01#7&259174a7&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
serial number: 0000
Manufacturer:  www.fischl.de
Product:       USBasp
Release:       1.10
Interface:     1

Updating USBasp Serial Number ...

USBasp List Index: 0

type: 16C0 05DC
path: \\?\HID#VID_16C0&PID_05DC&MI_01#7&259174a7&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
serial number: 0666
Manufacturer:  www.fischl.de
Product:       USBasp
Release:       1.10
Interface:     1

@mcuee
Copy link
Collaborator Author

mcuee commented Mar 15, 2023

@MikeRaffa
Your fork is good for Windows as well using serial number. I connected two USBasp units (one with serial number 0001 and the other one with serial number 0888) , and then another USBasp as target to the unit with serial number 0888. git main will fail but your patch works fine.

Take note all three units are still using WinUSB for Interface 0 and HID driver for Interface 1 (USB composite device) so I have to use MinGW to build avrdude binary due to issue #968 as mentioned @dioannidis.

PS C:\work\avr\avrdude_test\avrdude_bin\usbasp_sn> .\VUSBSerialNumber.exe -l

USBasp Serial Number utility (for FW https://github.com/dioannidis/usbasp )


USBasp List Index: 0

type: 16C0 05DC
path: \\?\HID#VID_16C0&PID_05DC&MI_01#8&6001234&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
serial number: 0001
Manufacturer:  www.fischl.de
Product:       USBasp
Release:       1.10
Interface:     1

USBasp List Index: 1

type: 16C0 05DC
path: \\?\HID#VID_16C0&PID_05DC&MI_01#7&28dd995c&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
serial number: 0888
Manufacturer:  www.fischl.de
Product:       USBasp
Release:       1.10
Interface:     1

USBasp List Index: 2

type: 16C0 05DC
path: \\?\HID#VID_16C0&PID_05DC&MI_02#7&5065b9a&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
serial number: 0888
Manufacturer:  www.fischl.de
Product:       USBasp
Release:       1.10
Interface:     2

PS C:\work\avr\avrdude_test\avrdude_bin\usbasp_sn> .\avrdude -c usbasp -p m8a

avrdude error: program enable: target does not answer (0x01)
avrdude error: initialization failed, rc=-1
        - double check the connections and try again
        - use -B to set lower ISP clock frequency, e.g. -B 125kHz
        - use -F to override this check


avrdude done.  Thank you.

PS C:\work\avr\avrdude_test\avrdude_bin\usbasp_sn> .\avrdude_issue973 -c usbasp -p m8a -P usb:0888

avrdude_issue973: AVR device initialized and ready to accept instructions
avrdude_issue973: device signature = 0x1e9307 (probably m8a)

avrdude_issue973 done.  Thank you.

@dioannidis
Copy link

@mcuee

The only minor issue is with the host software -- I need to hit a return to exit.
Edit: another issue: somehow the serial number 6666 becomes 0666.

Fixed both issues . Please download again the host app https://www.nephelae.eu/vusbserialnumber-x86_64-win64.zip .

@mcuee
Copy link
Collaborator Author

mcuee commented Mar 15, 2023

The only minor issue is with the host software -- I need to hit a return to exit.
Edit: another issue: somehow the serial number 6666 becomes 0666.

Fixed both issues . Please download again the host app https://www.nephelae.eu/vusbserialnumber-x86_64-win64.zip .

@dioannidis

Thanks. Now the issues are fixed.

@dioannidis
Copy link

I will remove the zip files as I updated the repository ( https://github.com/dioannidis/usbasp ) with all the changes .
The vusbserialnumber utility functionality added in the USBaspHIDUART utility.

C:\USBaspHIDUART.exe

USBasp HIDUART Test App

 -l  List USBasp HID devices
 -i  Select USBasp index ( default 0 )
 -b  Set Baud ( default 9600 )
 -c  Set Crystal Hz ( default 12 MHz or 12000000 Hz )
 -s  Select USBasp with serial number.
     4 Digits numeric only i.e. 3456, 2222, etc ).
 -u  Serial Number to update ( 4 Digits numeric only i.e. 3456, 2222, etc ).
     Use with index -i when more than one USBasp are connected.
 -r  Continuous read input
 -w  Interactive send output

examples

Read from USBasp at index 0 with 4800 baud
 USBaspHIDUART -b 4800 -r

Interactive write to USBasp at index 1 with 9600 baud
 USBaspHIDUART -i 1 -w

Interactive write to USBasp with serial number 1111 with 9600 baud
 USBaspHIDUART -s 1111 -w

Read from USBasp at index 1 with 19200 baud from a device with 20 MHz crystal
 USBaspHIDUART -i 1 -b 19200 -c 20000000 -r

Read from USBasp with serial number 2345 with 19200 baud from a device with 20 MHz crystal
 USBaspHIDUART -s 2345 -b 19200 -c 20000000 -r

Update the first found USBasp's serial number with 3456
 USBaspHIDUART -u 3456

Update the USBasp's at index 3 serial number with 3456
 USBaspHIDUART -i 3 -u 3456

After adding the capability functionality there will be a release 1.11 .

Thanks for testing and for the feedback .

@dioannidis
Copy link

Pre-release v1.11 is ready

@mcuee
Copy link
Collaborator Author

mcuee commented Jun 21, 2023

From here:
#1418 (comment)

The comment to the ft2232h programmer says:

# The drivers will look for a specific device and use the first one found.
# If you have mulitple devices, then look for unique information (like SN)
# and fill that in here.

What does it mean to look for unique information (like SN) and fill that in here? How would a user do that?

The user will need to put the USB Serial Number in the avrdude configure file.

The code has also the place holder for using the unique descriptor or index to identify the programmers, but not implemented yet.

avrdude/src/avrftdi.c

Lines 668 to 677 in 9269102

if (0 == pgm->usbsn[0]) /* we don't care about SN. Use first avail. */
serial = NULL;
else
serial = pgm->usbsn;
/* not used yet, but i put them here, just in case someone does needs or
* wants to implement this.
*/
desc = NULL;
index = 0;

@mcuee mcuee added help wanted Extra attention is needed and removed help wanted Extra attention is needed labels Jun 24, 2023
@mcuee
Copy link
Collaborator Author

mcuee commented Oct 29, 2023

Preliminary version of -P bus/device and serial_number support for USBASP is here https://github.com/MikeRaffa/avrdude.

@MikeRaffa

Just wondering if you are interested to create a PR based on the above codes. Thanks.

@MikeRaffa
Copy link
Contributor

Yes, I've been meaning to do that but have been busy with other stuff. I'll try to get it done this week.

MikeRaffa added a commit to MikeRaffa/avrdude that referenced this issue Dec 4, 2023
…e VID/PID (libusb or hidapi or libftdi)

Added code for USBasp to check for bus:device match using the -P option. Syntax is -P usb:<bus>:<device> (same as current USBTiny implementation).

This also supports serial number check with the alternative -P usb:<serial_number> format (no ':').

In verbose mode, prints out bus/device/serial number for any found USBasps.

Only tested on Linux, but it works with HAVE_LIBUSB_1_0 on or off (there's some slightly different code in the two versions of usbOpenDevice()).
MikeRaffa added a commit to MikeRaffa/avrdude that referenced this issue Dec 4, 2023
stefanrueger added a commit that referenced this issue Dec 18, 2023
Issue #973: Differentiate multiple USB programmers of the same VID/PI…
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants