Native port driver BSoD

Yes, the ERASE button allows the SAM built-in bootloader to run as the BOSSA interface. If you have a sketch loaded then the bootloader does not run. The sketch runs as the Arduino Due USB interface. Which also should be emulating the HID keyboard and mouse, but it doesn't seem to be working.

Also note that I have successfully installed the Arduino Due.inf driver under Windows XP (Home/Pro) SP3. But the HID emulation still doesn't work. However, the standard serialUSB interface works okay.

With Arduino Due.inf Native port driver are you running the original .inf or have you made any changes to the driver content to make it work with
Windows XP SP3 ? I tried the changes suggested in earlier messages (like removing &MI00 and other suggestions ) with no luck,

but I'm sure somebody will find a solution to this driver question in near future, since quite many are reporting similar behaviour,

Seppo

Okay, I have done a little more testing scenarios. First on my Dell XPS Windows 7 SP1 64-bit, I found out the back USB ports are 3.0. Only the side port is USB 2.0. So previously I was only trying the back ports with my Due and Leonardo, both failed and got BSOD.

Now I tried multiple times the side USB 2.0 port and was able to get my Leonardo and Micro both to install the driver and work correctly with keyboard and mouse. Unfortunately my Due still died BSOD during the driver install. I think this could be because the HID emulation is not working correctly on the Due yet. So it may not be handshaking correctly with the driver install. (I say this because I have a couple of Windows XP SP3 32-bit systems that install the Due driver okay, and the SerialUSB works correctly, but the HID interface still never shows up.)

So for those of you with USB 3.0 ports, you may want to try it on USB 2.0 ports to see if it works any better, at least for the Leonardo and Micro. It would interesting if someone else can get the Due on a USB 2.0 port.

Strange things goes on,

on my HP laptop all works Bossa, Programming Port, Arduino Due, (Windows 7 64bit SP1) on an DELL Optiplex works Bossa and Programming Port nothing else Arduinodue.inf not trieed any modification known from Navie USB port drivers (Arduino Due mode) - #5 by hiduino - Arduino Due - Arduino Forum nothing helps.

Markus

In my opinion maybe it's not an Arduino problem it looks more like an problem with Dell and there USB-Ports... could be wrong.

My Sony Vaio Windows 7 SP1 64-bit, which has USB2.0 ports also gets BSOD when trying to install the ArduinoDue.inf drivers. I don't think it is limited to Dell.

Has anyone got the Due native port working with HID Keyboard and Mouse emulation on any Windows platform or other platforms?

Markus_L811:
e an problem with Dell and there USB-Ports... could be wrong.

Mine is a Thinkpad Lenovo. I cant seem to determine if it is 3.0 or 2.0 USB port

I have found a problem in the Device Descriptor defined in the file USBCore.cpp

USB_DeviceDescriptorA has a device class of 2 if CDC is enabled and a device class of 0, if it is not.

The problem is the Device Descriptor for a Composite Device, needs to have a device class of 0 or Windows will not know it is a Composite Device.

I changed the code to use Device Class 0 in either case and recompiled a sketch.

After changing that, I see 3 devices show up when connected to the Native port. I see a CDC device, a HID mouse, and HID Keyboard.

I haven't done any further testing to make sure they all work, but I don't get the BSOD anymore when installing the serial driver.

#ifdef CDC_ENABLED
#define DEVICE_CLASS 0x02
#else
#define DEVICE_CLASS 0x00
#endif

//	DEVICE DESCRIPTOR
const DeviceDescriptor USB_DeviceDescriptor =
	D_DEVICE(0x00,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1);

const DeviceDescriptor USB_DeviceDescriptorA =
	D_DEVICE(DEVICE_CLASS,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1);

...

if (USB_DEVICE_DESCRIPTOR_TYPE == t)
	{
		TRACE_CORE(puts("=> USBD_SendDescriptor : USB_DEVICE_DESCRIPTOR_TYPE\r\n");)
		if (setup.wLength >= 8)
		{
			_cdcComposite = 1;
		}
		desc_addr = _cdcComposite ?  (const uint8_t*)&USB_DeviceDescriptorA : (const uint8_t*)&USB_DeviceDescriptor;
        if( *desc_addr > setup.wLength ) {
            desc_length = setup.wLength;
        }
	}

Great! I tried that change of the Descriptor to 0 in "\arduino-1.5.1r2\hardware\arduino\sam\cores\arduino\USB\USBCore.cpp" and tested the KeyboardAndMouseControl example sketch and it worked correctly. (Note: I needed to delete the existing driver and let it reinstall to get the composite USB be recognized)

The question is, I double checked the "\arduino-1.0.2\hardware\arduino\cores\arduino\USBCore.cpp" file for the Leonardo and Micro, but they have the same class 2 definition if CDC_ENABLED? So what is different here that makes it work?

I was able to confirm the Descriptor modification with my other two laptops.
Dell XPS Windows 7 SP1 64-bit and Sony Vaio FW590 Windows 7 SP1 64-bit both installed the ArduinoDue.inf driver correctly now for the Native USB port. I also tested the KeyboardAndMouseController sketch and it works fine.

This modification is just a kludge at the moment. We need to figure out the proper code fix for this issue. Anyone else versed in USB stuff?

hiduino:
The question is, I double checked the "\arduino-1.0.2\hardware\arduino\cores\arduino\USBCore.cpp" file for the Leonardo and Micro, but they have the same class 2 definition if CDC_ENABLED? So what is different here that makes it work?

The reason is works on Leonardo is because of the following differences between Leonardo USBCore.cpp:

	if (USB_DEVICE_DESCRIPTOR_TYPE == t)
	{
		if (setup.wLength == 8)
			_cdcComposite = 1;
		desc_addr = _cdcComposite ?  (const u8*)&USB_DeviceDescriptorA : (const u8*)&USB_DeviceDescriptor;
	}

and Due USBCore.cpp:

	if (USB_DEVICE_DESCRIPTOR_TYPE == t)
	{
		TRACE_CORE(puts("=> USBD_SendDescriptor : USB_DEVICE_DESCRIPTOR_TYPE\r\n");)
		if (setup.wLength >= 8)
		{
			_cdcComposite = 1;
		}
		desc_addr = _cdcComposite ?  (const uint8_t*)&USB_DeviceDescriptorA : (const uint8_t*)&USB_DeviceDescriptor;
                if( *desc_addr > setup.wLength ) {
                    desc_length = setup.wLength;
                }
	}

When I captured a USB protocol trace on my system, setup.wLength was 18 for the Get_Descriptor request.

Therefore, on Leonardo, setup.wLength will not equal 8 and _cdcComposite will not get set to 1. So the function will return USB_DeviceDescriptor, which has the Device Class set to 0.

On Due, setup.wLength will be greater than or equal to 8 and _cdcComposite will get set to 1. So the function will return USB_DeviceDescriptorA , which has the Device Class set to 2.

If the Arduino only wanted to expose a CDC interface, then a Device Descriptor with a Device Class of 2 is correct.
If the Arduino is exposing more than one interface, then it should only return a Device Descriptor with a Device Class of 0. This indicates that each interface will specify its own class information and operate independently.

Great! Thanks for the explanation. That is very helpful in understanding what is going on.

The question is what intent is Arduino meant for this option? I would think everyone will have problems with this out of the factory.

Is setting the Class to 0 the correct action? Or changing the comparison to match the avr code? Or something else?

I am having the same issue on WinXP;
so should I change

#ifdef CDC_ENABLED
#define DEVICE_CLASS 0x02
#else
#define DEVICE_CLASS 0x00
#endif

to

#ifdef CDC_ENABLED
#define DEVICE_CLASS 0x00
#else
#define DEVICE_CLASS 0x00
#endif

in arduino-1.5.1r2\hardware\arduino\sam\cores\arduino\USB\USBCore.cpp?

Yes, that would be the quick fix. That worked for me on various Windows (XP/7 32/64-bit) machines.
I am not sure what the long term fix will be.

answered also here:

Louis,

first thank you, I've seen the forum thread, great work.

This commit was due to the behaviour seen on older macosx (<=10.6.8 ).

We got the following facts:

macosx versions <= 10.6.8 sends a wLenght of 0x12
if we keep the == condition (==0x08) the CDC-Serial is not seen from macosx
changing the condition to >= 0x08 make it working

Note that this happens only with high-speed devices. If you attach a low-speed device macosx
requests a wLength of 0x08. This probably makes Leonardo unaffected.

I'm going to set the condition back to ==, but my question now is: there is a workaround to make it
working also on macos 10.6.8 and older?

I am not sure why there is a need for conditional code to send a different Device Descriptor depending on the length of the request.

If I understand the USB specs properly, the device should return the same Device Descriptor, no matter what the length is requested.

The USB code looks like it is trying to handle three scenarios:

  1. CDC only
  2. HID only
  3. Composite: CDC and HID

If the USB code is configured as CDC only, CDC_ENABLED defined and HID_ENABLED not defined, then it should have a Device Descriptor with Device Class of 2.
If the USB code is configured as HID only, CDC_ENABLED not defined and HID_ENABLED defined, then it should have a Device Descriptor with Device Class of 0.
If the USB code is configured as Composite, CDC_ENABLED defined and HID_ENABLED defined, then it should have a Device Descriptor with Device Class of 0.

I believe that you could simplify the code and accomplish this behavior by making the following changes to the code:

  1. Change the preprocessor macro to set Device Class to 0 if HID is defined, this covers the HID only and Composite cases. Otherwise, set Device Class to 2, this covers the CDC only case.
  2. Eliminate the alternate USB_DeviceDescriptor.
  3. Remove the conditional code based on request length.
#ifdef HID_ENABLED
#define DEVICE_CLASS 0x00
#else
#define DEVICE_CLASS 0x02
#endif

//	DEVICE DESCRIPTOR
const DeviceDescriptor USB_DeviceDescriptor =
	D_DEVICE(DEVICE_CLASS,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1);

...

if (USB_DEVICE_DESCRIPTOR_TYPE == t)
	{
		TRACE_CORE(puts("=> USBD_SendDescriptor : USB_DEVICE_DESCRIPTOR_TYPE\r\n");)
		
		desc_addr = (const uint8_t*)&USB_DeviceDescriptor;
                if( *desc_addr > setup.wLength ) {
                    desc_length = setup.wLength;
                }
	}

I haven't fully tested this, but I think this will accomplish what is desired.

The question is why does it work on the most Windows Systems but not on all? What are the differences? There musst something that explains that.

I did some tests, replacing back the if condition to wLentgth==8, and with the full patch provided by Louis David,
here the results:

OS **wLength==8 ** LD patch
Win 7 ultimate (64) OK OK
Linux Ubuntu 11.04 (32) OK OK
MacOS 10.7.2 OK OK
MacOS 10.6.8 No Serial Port No Serial Port

With my Windows box I didn't experienced the BSoD, so probably both patches solves it as already reported in this thread.

For now I stick to what Leonardo do:

can you check if the latest ide-1.5.x solves the BSoD?

I'd like to apply the patch of Louis David, but I don't remember why the condition (with the duplicated descriptor) was introduced, I should clear that before.

Besides that, the question now is: what's the matter with macosx 10.6.8? Has anyone access to such SO and can explain what's happening?

I have attached the Due USB descriptor information captured from USB Prober on OS X 10.8.2.

It would be interesting to compare this information captured on 10.6.8

It would probably be helpful to have the captures from a failing case and a successful case on 10.6.8 to compare.

Arduino Due USB Descriptors.txt (13.1 KB)

Hi, you can find attached a couple of files generated by USB Prober on a Mac OS X 10.6.8, one for each behaviour (the names should be self-explanatory).

The "NoSerial" one is generated when on the Due is running a sketch (just a "SerialUSB.begin(115200);" and nothing else) uploaded with the IDE built from the fabc658a942de659d44f22f196701d04b857f094 commit.

The "SerialOK" one is generated uploading the same sketch with the same IDE, but after restoring the ">=8 patch" so that the serial port appears.

I hope this helps!

USBBusProbe_10.6.8_NoSerial.txt (13 KB)

USBBusProbe_10.6.8_SerialOK.txt (13 KB)