Go Down

Topic: Native port driver BSoD (Read 10285 times) previous topic - next topic

hiduino

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.


Markus_L811

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 http://arduino.cc/forum/index.php/topic,131100.msg987440.html#msg987440 nothing helps.

Markus

Markus_L811

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.

hiduino

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?


Msquare


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

Louis Davis

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.

Code: [Select]
#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;
        }
}

hiduino

#21
Nov 16, 2012, 01:33 am Last Edit: Nov 16, 2012, 01:56 am by hiduino Reason: 1
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?


hiduino

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?



Louis Davis



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:
Code: [Select]
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:
Code: [Select]
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.

hiduino

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?



Stan09

I am having the same issue on WinXP;
so should I change
Code: [Select]
#ifdef CDC_ENABLED
#define DEVICE_CLASS 0x02
#else
#define DEVICE_CLASS 0x00
#endif


to

Code: [Select]
#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?

hiduino

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.


cmaglie


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.


answered also here:
https://github.com/arduino/Arduino/commit/3e9ef444018f64f2eee76909a602dfb440d87ee5#commitcomment-2169570


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?
C.

Louis Davis

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.

Code: [Select]
#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.

Markus_L811

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.

Go Up