Go Down

Topic: Renaming Issues in Arduino Leonardo (Read 1 time) previous topic - next topic

dev_000

Hey guys,

Hope you are doing great.

I am doing a personal project wherein I am messing around with a custom Atmega32u4 board based on Leonardo design. I am trying to rename the board to a custom name with a custom VID and PID for my personal use.

I followed the steps at http://steven.casagrande.io/articles/compiling-arduino-caterina-with-new-vidpid/
I recompiled Arduino Caterina Bootloader code based on LUFA with the changes in the VID, PID and the enumeration names in the Descriptor.c file as follows(I did correct for the sizing of the String length to make it match with 16 with spaces).

Code: [Select]

const USB_Descriptor_String_t ProductString =
{
 .Header                 = {.Size = USB_STRING_LEN(16), .Type = DTYPE_String},

 #if DEVICE_PID == 0x0036
 .UnicodeString          = L"Arduino Leonardo"
 #elif DEVICE_PID == 0x0037
 .UnicodeString = L"Arduino Micro   "
 #elif DEVICE_PID == 0x003C
 .UnicodeString = L"Arduino Esplora "
 //*****************************
 #elif DEVICE_PID == 0x0ADB // Random PID number
 .UnicodeString = L"Hello World     "
 //*****************************
 #else
 .UnicodeString = L"USB IO board    "
 #endif
};

const USB_Descriptor_String_t ManufNameString =
{
 .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
 
 #if DEVICE_VID == 0x2341
 .UnicodeString = L"Arduino LLC"
 //*****************************
 #elif DEVICE_VID == 0x0BAD // Random VID number
 .UnicodeString = L"HelloVendor"
 //*****************************
 #else
 .UnicodeString = L"Unknown    "
 #endif
};


I recompiled the project and generated the bootloader hex file and burned it to the new custom board via Atmel Studio and JTAGICE3 Programmer. Upload was successful. I uninstalled the new board from the device manager, Replugged it back to the PC and it shows up listed with the name USB Serial Device in the Ports Section of the Device Manager.

It is not showing up with the name Hello World as mentioned in the recompiled bootloader. So I thought the issue was with the bootloader but when I checked the PID and VID of the newly flashed device(By right clicking and checking properties in Device Manager for the new device), it shows up same as the one I mentioned in the new code. So am I assuming bootloader is OK.

In order to debug the problem, I plugged in an Arduino Leonardo along with the custom board to compare the USB properties. What is surprising is that in the properties of the custom board, Bus reported device description section, it shows up as Hello World (Check attachment below with the name Bus Reported.png) but Device description section shows it as USB Serial Device

Exploring further, I was doing a side by side analysis of the two boards. I have attached the images for that. (Check attachments 1-4.png) It seems that it could be the issue with Windows?

I can flash new codes in the new board via Arduino IDE after I edited the boards.txt and added a new entry to the Arduino IDE. It programs fine without any issues.


1. Any ideas how I can fix this issue to make Windows renumerate my device with my custom name? I am sure people would have tried this already on a Leonardo board.

2. Second question is when I look at the bootloader sizes of Arduino Caterina Leonardo Production version has a file size of around 75.9KB on Windows whereas the newly compiled bootloader which I compiled was only around 11KB. Is that an issue? Why so, why is the Leonardo's production bootloader appear to be much larger?
(I know both the above file sizes are wrong as its in the machine readable format, Actual flashed size on the microcontroller will be around 4KB I assume)

3. Third question is, when I plug in the original Arduino Leonardo, it enumerates as Arduino Leonardo Bootloader for the first 8sec and then enumerates itself as Arduino Leonardo. I know why this happens, but I am not sure where in the code this is made to happen? How is the enumeration names changing? Which part of the code is responsible for this?
The enumerated name also changes from Arduino Leonardo Bootloader to Arduino Leonardo in the Arduino IDE in Tools->Ports Section. Where is the code which enables this part?


Hoping someone can help me out with these issues.
Thanks in advance.



pert

I don't know much about this stuff so take it with a bit of salt but I'll try to answer some things:

3. Third question is, when I plug in the original Arduino Leonardo, it enumerates as Arduino Leonardo Bootloader for the first 8sec and then enumerates itself as Arduino Leonardo. I know why this happens, but I am not sure where in the code this is made to happen? How is the enumeration names changing? Which part of the code is responsible for this?
The first part is the bootloader code. The second part is Arduino core library code that is part of the program you upload (sketch).

The enumerated name also changes from Arduino Leonardo Bootloader to Arduino Leonardo in the Arduino IDE in Tools->Ports Section. Where is the code which enables this part?
The name shown in the Arduino IDE's Tools > Port menu is controlled by the boards.txt name property of the board associated with that the VID/PID of the device creating that port (as defined by the boards.txt vid and pid properties for that board).

dev_000

Thanks a lot for the response pert.
Quote
The first part is the bootloader code. The second part is Arduino core library code that is part of the program you upload (sketch).
This make sense I suppose. I did arough search ..hardware\arduino\avr\cores\arduino\ folder contents though to see if there is a reference but couldnt find it. I guess I missed it somewhere in USB stack implementation.

Quote
The name shown in the Arduino IDE's Tools > Port menu is controlled by the boards.txt name property of the board associated with that the VID/PID of the device creating that port (as defined by the boards.txt vid and pid properties for that board).
In the boards.txt section on Leonardo,(Copy pasted below) I cant find a section which lists the text "Arduino Leonardo Bootloader". So I am guessing the its taking the name directly from the Windows system USB implementation?

Code: [Select]

leonardo.name=Arduino Leonardo
leonardo.vid.0=0x2341
leonardo.pid.0=0x0036
leonardo.vid.1=0x2341
leonardo.pid.1=0x8036
leonardo.vid.2=0x2A03
leonardo.pid.2=0x0036
leonardo.vid.3=0x2A03
leonardo.pid.3=0x8036

leonardo.upload.tool=avrdude
leonardo.upload.protocol=avr109
leonardo.upload.maximum_size=28672
leonardo.upload.maximum_data_size=2560
leonardo.upload.speed=57600
leonardo.upload.disable_flushing=true
leonardo.upload.use_1200bps_touch=true
leonardo.upload.wait_for_upload_port=true

leonardo.bootloader.tool=avrdude
leonardo.bootloader.low_fuses=0xff
leonardo.bootloader.high_fuses=0xd8
leonardo.bootloader.extended_fuses=0xcb
leonardo.bootloader.file=caterina/Caterina-Leonardo.hex
leonardo.bootloader.unlock_bits=0x3F
leonardo.bootloader.lock_bits=0x2F

leonardo.build.mcu=atmega32u4
leonardo.build.f_cpu=16000000L
leonardo.build.vid=0x2341
leonardo.build.pid=0x8036
leonardo.build.usb_product="Arduino Leonardo"
leonardo.build.board=AVR_LEONARDO
leonardo.build.core=arduino
leonardo.build.variant=leonardo
leonardo.build.extra_flags={build.usb_flags}


Does anyone else have any inputs as to why the name is not enumerating properly. I currently stuck at this point with no obvious answers. :(

pert

#3
Mar 19, 2018, 12:21 pm Last Edit: Mar 19, 2018, 12:22 pm by pert Reason: Linkify URL
This make sense I suppose. I did arough search ..hardware\arduino\avr\cores\arduino\ folder contents though to see if there is a reference but couldnt find it. I guess I missed it somewhere in USB stack implementation.
The actual name string is set by the usb_product property in boards.txt:
https://github.com/arduino/ArduinoCore-avr/blob/master/boards.txt#L313
Code: [Select]
leonardo.build.usb_product="Arduino Leonardo"
The compiler flag to set the USB_PRODUCT macro to that value is defined in platform.txt:
https://github.com/arduino/ArduinoCore-avr/blob/master/platform.txt#L130
Code: [Select]
build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}'
That build.usb_flags property containing the compiler flag is transfered to the build.extra_flags property back in boards.txt:
https://github.com/arduino/ArduinoCore-avr/blob/master/boards.txt#L317
Code: [Select]
leonardo.build.extra_flags={build.usb_flags}
Then finally the build.extra_flags property is added to the compilation recipe in platform.txt:
https://github.com/arduino/ArduinoCore-avr/blob/master/platform.txt#L57
Code: [Select]
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"


So now we need to find where this USB_PRODUCT macro is used in the core:
https://github.com/arduino/ArduinoCore-avr/blob/7d4bca50419f2b2e57f92e9bec1cbbbe6d846fc1/cores/arduino/USBCore.cpp#L49
Code: [Select]
const u8 STRING_PRODUCT[] PROGMEM = USB_PRODUCT;
https://github.com/arduino/ArduinoCore-avr/blob/7d4bca50419f2b2e57f92e9bec1cbbbe6d846fc1/cores/arduino/USBCore.cpp#L523
Code: [Select]
return USB_SendStringDescriptor(STRING_PRODUCT, strlen(USB_PRODUCT), TRANSFER_PGM);

In the boards.txt section on Leonardo,(Copy pasted below) I cant find a section which lists the text "Arduino Leonardo Bootloader". So I am guessing the its taking the name directly from the Windows system USB implementation?
I actually can't reproduce your findings in the Tools > Board menu. My Tools > Board menu always shows the name string from boards.txt. If I change that string in boards.txt and then restart the IDE sure enough the string shown next to the Leonardo's port changes accordingly. I'm using Windows 10 with Arduino IDE 1.8.5. Obviously that is specific to the Arduino IDE. Other programs like Windows Device Manager have no idea of this name property in boards.txt and will instead use the "Bus reported device descriptor, which is coded into the bootloader and sketch firmware on the ATmega32U4. I'm not sure why the Arduino IDE doesn't use the descriptor in the Port menu.

I can think of two possible sources for this "Arduino Leonardo Bootloader" string: The bootloader, and the driver.

pert

Note that you need to restart the Arduino IDE before any changes you make to boards.txt or platform.txt take effect.

dev_000

Thanks for that.

I did something stupid now. I reflashed my Leonardo with my custom built firmware without saving the bootloader which was already their in the Leonardo. The Leonardo device enumerated itself as USB serial Device as my custom board. Then I reflashed the Leonardo-prod-firmware-2012-12-10.hex in the ..\bootloaders\caterina folder. After this, I cant seem to recreate the 3rd problem. (Re-enumerating as a different names in IDE Tools section or Device Manager right after plugging in and after 8seconds) Then new bootloader seems to have done away with the 8 second delay? Can some one confirm this?

I am not sure which bootloader was present at first in my Arduino Leonardo board. I should have saved a copy of the hex file by reading it back from the device :(

@Pert If you get time, I would be really thankful if would be able to compile the LUFA firmware and see if question 1 is repeatable in your machine. Steps to compile are as follows.
  • Download LUFA version 111009 from the LUFA website.
  • Extract and copy the folder LUFA-111009 to Arduino IDE's bootloader location of D:\Arduino\hardware\arduino\avr\bootloaders\cateri
  • Open Descriptors.c file in the above location.
    Navigate down to line 192 (const USB_Descriptor_String_t ProductString). and change your PID by adding a line
Code: [Select]
#elif DEVICE_PID == 0x10FF // Random PID number
    .UnicodeString = L"Hello World     "
  • Add the VID also to USB_Descriptor_String_t ManufNameString 
  • Open the Makefile at the location D:\Arduino\hardware\arduino\avr\bootloaders\caterina\ and modify LUFA_PATH to locate the LUFA_111009 folder as follows
    LUFA_PATH = LUFA-111009
  • Also at the beginning of the makefile add VID = 0x0BAD  and PID = 0x0ADB (The new VID and PID numbers) around line 53 and 63 respectively. Save the files.
  • Open the Command line from the D:\Arduino\hardware\arduino\avr\bootloaders\caterina\ folder and type make in CMD. Caterina.hex is created. Rename it to Caterina-NewBoardName.hex to avoid rewrites during new compilation.
  • Upload the new hex file with Atmel Studio and JTAG ICE Programmer to the Atmega32u4 via ISP Headers
  • Delete the device in the device manager and re-plugin to see the effect of the name change.

dev_000

Just an update.
Even the production caterina bootloader shipped with Arduino software, renumerates itself as "Arduino Leonardo bootloader" for the first 8seconds when a hard reset is performed on the board by pressing the push button. After 8 seconds it changes back  to "Arduino Leonardo"


Can someone please help me question 1 mentioned here? I am simply not able to rename the device in Windows after the new compiled bootloader. Can someone please confirm if its repeatable or if there is a solution for this issue?

dev_000

Hey guys,

Just updating for people running into this issue in the future.

I had almost given up on this topic. But thought of giving it one more shot.
So continuing from above, once you make the edits in Descriptors.c and the makefile, go ahead and make the bootloader hex file. Burn this bootloader to your Arduino Leonardo.

So what I think is happening is that Windows 10 is not taking the device driver properly and it recognises it as a generic driver. We need our custom driver inf file.

Now we need to tell Windows to recognize the USB device properly. For that, download the .inf file from https://github.com/Galvant/usb_driversEdit the sections [DeviceList] and [DeviceList.NTamd64] with the name you used for your sketch and bootloder with equivalent PID and VID. Make sure to use the correct VID for sketch and bootloader as you edited in Descriptors.c. In the [Strings] section edit the parameters with whatever you want. Save the file.


Now plug in the device with the new burned hex file. Go to device Manager in Windows 10. Right the click on the enumerated device.(Most likely it enumerates itself as a generic USB Serial Device). Uninstall the driver. Physically remove the device from the USB Port and replug it in. Now we have to update the driver from the generic driver to the new .inf file which we created now. There is a problem because Windows 10 doesn't take drivers which are not digitally signed. So you have to restart your PC after disabling the Driver Enforcement Feature in Windows. Use this video to see how.


Once you have disabled the Driver Enforcement and restarted the PC. Go to Device Manager and right click the device click on Update Driver. In the next screen, select Browse my computer for driver software. In the next screen, Select "Let me PickDriver from a list" and click Next. (Its important you do it this way as Search for drivers in location at the top doesn't seemed to updating the driver for me. Now in the next screen, select Have Disk and Browse to location where you saved our custom inf file which we made in the Copy manufacturer's file from section. Click OK. It would say driver is not digitally signed. Press Next. You would get a popup on whether you want to install a unsigned driver. Click yes and the next screen would install the driver for you.
Now in your device manager you would see the new name pop up.

So this much works. But there is still a problem which I need your help with. The new name gets recognized for the "Sketch" but not when bootloader is active, ie) when you press the reset button on board(Not when you power on the device) for 8seconds. The device still gets recognized as "USB serial Device" not as the name I made it to be.
Can someone please help me out where Arduino drivers are achieving this? If I can fix it to show my custom name in the Bootloader mode, this project will be complete.

Hoping someone can take a look at this.
Thanks in advance. 

pert

Glad to hear you've made progress. Is there a different VID/PID when it's in bootloader mode?

xl97

OUCH!..

Man this is always been something I have wanted to do/learn how to do (for some Pro-Micro projects in the past)..

but man does this seem like a lot or work from my quickly skimming the thread.

Also.. if you have to delete/remove drivers and install new drivers, .inf files..etc..etc. 

This isnt really a 'permanent' solution that is done athe Arduino/board level?  (so if you go to another machine, none of the applies any more?)..... am I understanding that correctly?

dev_000

Glad to hear you've made progress. Is there a different VID/PID when it's in bootloader mode?
Yes. PIDs are different but its just that names are not enumerated properly in Windows for Bootloader mode. Its quite late here now. I will give this a shot tomorrow.

Quote
This isnt really a 'permanent' solution that is done athe Arduino/board level?  (so if you go to another machine, none of the applies any more?)..... am I understanding that correctly?
Yup. Although I havent tested on other PCs, I think the solution is to use the custom inf file for a particular custom board and manually update driver installation in each PC you use.

dev_000

Hey guys,

I haven't still figured out how to solve this problem.

The device even with the custom bootloader and custom driver .inf files,  still enumerates itself as "USB Serial Device" in Windows 10 when the device is in the "bootloader" mode. The device enumerates itself properly with the custom name in the "Sketch" mode.

I don't know how Arduino Leonardo's drivers manage to make this work in Windows 10.

If ever anyone figures out on how to do the renaming properly on Atmega32u4, please do post it here.

PS: I am surprised that this topic hasn't come up more often in this forum, for people who were developing custom boards based on Arduino Leonardo or Micro.

pert

still enumerates itself as "USB Serial Device" in Windows 10 when the device is in the "bootloader" mode.
That sounds like a generic name that Windows automatically provides rather than some string in the bootloader code or driver.

Question: Do you actually need the bootloader for your application? If you connect your ISP programmer to the board and do a Sketch > Upload Programmer then the bootloader is erased. Of course then you can't do uploads over serial but maybe you don't need that?

PS: I am surprised that this topic hasn't come up more often in this forum, for people who were developing custom boards based on Arduino Leonardo or Micro.
The topic of the device name when not in bootloader mode has definitely come up, though I think it's not a topic many people on the forum are able to help with and I think very few are so dedicated to finding a solution as you have been.

dev_000

Quote
That sounds like a generic name that Windows automatically provides rather than some string in the bootloader code or driver.
Yup. I think its a generic driver which Windows uses when it cant find a particulat PID/VID pair.

Quote
Question: Do you actually need the bootloader for your application? If you connect your ISP programmer to the board and do a Sketch > Upload Programmer then the bootloader is erased. Of course then you can't do uploads over serial but maybe you don't need that?
I need the bootloader because I need the upload over serial. Since its a personal project, I am prepared to work with this non-enumeration issue as well. But the problem doesn't seem to be solved perfectly in my books... That's going to nag me for a while till I find a solution.  :) 

dev_000

#14
Apr 22, 2018, 02:32 pm Last Edit: Apr 22, 2018, 02:40 pm by dev_000
Hey guys,

Another update. I think I might have fixed the problem.

I think issue was with the Windows and the 8sec bootloader time when its reset.

So what I did is the following
1. Plug in the board.

2. Go to device manager immediately(before board switches to "sketch" mode). Right click and update the driver.

3. Update the driver as I mentioned before(Automatic selection was not working for me)
Quote
In the next screen, select Browse my computer for driver software. In the next screen, Select "Let me PickDriver from a list" and click Next. (It's important you do it this way as Search for drivers in location at the top doesn't seem to be updating the driver for me. Now in the next screen, select Have Disk and Browse to location where you saved our custom inf file which we made in the "Copy manufacturer's file from" section. Click OK. It would say the driver is not digitally signed. Press Next. You would get a popup on whether you want to install an unsigned driver. Click yes and the next screen would install the driver for you.
4. Make sure during entire above process you keep resetting the board multiple times and make sure the board doesn't go into the "Sketch" mode after the 8sec timeout. This seems to be the problem. Windows sees one PID during the start of the driver installation process and by the end of it see the Sketch's PID. That I think is screwing up the driver installation.(Still, don't know how Leonardo and Micro does it effortlessly without these steps)

5. At the end of the driver installation, if you are still in the bootloader mode, the device with the bootloader, will enumerate, with the bootloader name properly in the device manager.


I guess I got a solution for this issue. Not that elegant, but it works nonetheless for my application. What I will do is, when I get time over the next couple of weeks, I will make a proper documentation for the actual steps needed to rename a Arduino Leonardo/Micro and post it here. Hopefully this will help out anyone searching for doing something similar in the future. They wouldnt have to waste their time figuring this thing out. :)

Thanks again for all your help.

Go Up