10 years, 9 months ago.

Is USBSerial giving problems on new Haswell macs for anyone else?

I have been using USBSerial for 1/2 year now on FRDM-KL25Z with no problems at all. All of a sudden (when testing on a new MacBook Air 2013) - I see that when connected to either USB port, the device no longer pops up in the /dev/tty.xxx list.

The error that dmesg displays is:

USBF:	110.115	The IOUSBFamily gave up enumerating a USB device after 10 retries.  (Port 1 of Hub at 0x14000000)
USBF:	110.115	The IOUSBFamily was not able to enumerate the device (Port 1 of Hub at 0x14000000).

I seem to have narrowed it down to be a problem on the new Haswell Mac laptops (tried it on a new Pro 2013 and Air 2013 that shows the problem - and an old Pro and Air (pre-2013) that works just fine.

At the moment, I am trying to modify the kext "driver" files in /System/Library/Extensions to grab my particular VID/PID and force some USB serial driver/module.

My guess:

1. the new macs use a new USB3 chip that - for some reason - is not compatible with the serial devices I have tried (google gives many examples of the same problem with e.g. Macbook Air 2013 and other devices)

2. the new macs are just more strict in the software so one needs to be 100% compliant with the USB CDC profile (somehow)

I have also tried to build with the latest mbed code from github (same result).

.. these are just guesses... digging further.

UPDATE:

I tried to make the VID/PID the same as for the main flashing port that seems to mount fine as a USB serial device on the mac... the problem then might be in the details of the CDC setup. I am attaching the two printouts of lsusb from linux with the details. /media/uploads/larsgk/nowork.txt /media/uploads/larsgk/worksusb.txt

4 Answers

10 years, 4 months ago.

I've been running into the same problem, on Windows 7 and 8 PCs, not Macs. The problem is similar to what you describe - it occurs when plugging the device into USB 3 ports, but not USB 2 ports.

I spent a while tracing through the USB message logs and instrumenting the mbed USB code, and I tracked down the problem to a handshake issue. I don't quite fully understand the protocol details, but what seems to be happening is that the device gets into a state where it thinks it's in DEVICE_TO_HOST mode at a point where it's trying to respond to one of the configuration messages. I think it might be timing related, because it's sporadic - it occurs with no apparent pattern at different points in the configuration handshake. The probability of the problem is high enough that it occurs with certainty within the first 5 or so message exchanges, but it sometimes occurs on the SET ADDRESS, sometimes on the GET FULL CONFIGURATION, and sometimes when the PC side stack starts asking for the configuration strings (product name, languages, etc). I suppose it's fortunate that the probability of failure on any given message is so high, since otherwise it would probably be even more maddening in that it would successfully connect some percentage of the time and only fail sporadically. As it is, I was motivated to try to fix it and not just chalk it up to gremlins!

As I said, I don't quite understand *why* the failure is occurring, or what's different in the USB protocol versions that triggers it only on USB 3 ports, but after trying a number of ad hoc solutions, I've come up with something that seems to be working quite reliably for me. In USBDevice/USBDevice/USBDevice.cpp (yes, that's a cpp file called USBDevice within a folder called USBDevice within the library called USBDevice :)), find the routine bool USBDevice::controlOut(void) at around line 181, and make the following change (added code shown with "+" marks):

bool USBDevice::controlOut(void) { /* Control transfer data OUT stage */ uint8_t buffer[MAX_PACKET_SIZE_EP0]; uint32_t packetSize;

/* Check we should be transferring data OUT */ if (transfer.direction != HOST_TO_DEVICE) { + controlIn(); + if (transfer.direction != HOST_TO_DEVICE) return false; }

/* Read from endpoint */ packetSize = EP0getReadResult(buffer);

This is the kind of stab-in-the-dark, "it seems to work but I'm not sure why" fix that I normally really hate. I really prefer to thoroughly understand the nature of the bug so that I can have confidence in the fix. But I've found it awfully overwhelming to try to learn enough about USB itself, the KL25Z USB hardware, and the mbed USB stack to truly understand what's going on, plus the debugging environment is awfully opaque given that Windows device drivers are half of the equation and a headless microcontroller is the other half.

If this fix works for you, let me know - it would make me more confident about it. Or if anyone understands the mbed code and USB protocols well enough to know if and why this fix *should* work, that would be good to hear about as well!

Oops, I see my code snippet didn't format very well. To clarify, I added two lines added to USBDevice::controlOut(). In the original code, the first 'if' in the routine just returns false. I changed it to

controlIn();

if (transfer.direction != HOST_TO_DEVICE) return false;

posted by Mike R 23 Jul 2014

If you use <<code>> and <</code>> (on seperate lines), you get properly formatted code, making it easier.

Btw FYI, I would test this since I also suffered from this issue (as shown by my old reply here). But one of the few good things about windows 8.1: The problem has disapeared since I upgraded to it.

posted by Erik - 23 Jul 2014

Erik - thanks for the tag tip. Here's the code snippet properly formatted (hopefully):

bool USBDevice::controlOut(void)
{
    /* Control transfer data OUT stage */
    uint8_t buffer[MAX_PACKET_SIZE_EP0];
    uint32_t packetSize;

    /* Check we should be transferring data OUT */
    if (transfer.direction != HOST_TO_DEVICE)
    {
+        controlIn();
+        if (transfer.direction != HOST_TO_DEVICE)
            return false;
    }

posted by Mike R 23 Jul 2014

The patch is working for my setup (Windows 7, Intel NUC with Haswell and USB3 only ports), many thanks! Until now I had to connect the KL25Z via a USB hub. Commited to my RTOS-aware library for KL25Z at https://mbed.org/users/alpov/code/USBDeviceLite/

posted by Ales Povalac 30 Jul 2014
10 years, 6 months ago.

Is this issue being actively investigated? If not, I can take a look over the next couple of days. I think I have everything here to reproduce and debug the issue that Lars is hitting but I don't want to duplicate the effort of others.

-Adam

Hey Adam! I was going to look at this but wont have a chance until late next week. If you want to have a go and update as you go I'll help out too if you don't get it nailed by then. CMSIS-DAP doesn't have this problem so that was going to be my starting point (looking in the IRQ).

posted by Sam Grove 28 Apr 2014

Sam, I will try to take a look on Monday to see if I can reproduce on my Haswell based MacBook Air and report back here.

posted by Adam Green 28 Apr 2014

I was able to reproduce this problem with this sample running on a KL25Z board.

Notes so far:

  • It fails to enumerate on my new MacBook Air with Haswell chipset but is successful on my older machine.
  • Inserting a USB 2.0 Hub in the path works around the issue.
  • Supplying the KL25Z with external power so that it isn't pulling power from USB 3.0 port has no impact: doesn't work on Haswell but does work on older machine.

I will start attempting to debug this issue later tonight.

posted by Adam Green 29 Apr 2014

Hi Adam,

thanks a lot for looking into this! - can you tell me if you think there is light at the end of the tunnel or if mbed/USB + USB3/Haswell/Mac is doomed?

br Lars

posted by Lars Knudsen 12 May 2014
10 years, 9 months ago.

Lars,

Something you can try is grab a USB2 (preferably) USB hub. Put it between your KL25Z and your Mac and see if it works.

I have a windows Asus laptop, with only USB3 ports, and it doesn't work for me. With USB hub in between it works fine. I logged USB traffic on my laptop, and it can be summarized as pretty much no traffic whatsoever without the usb hub. To rule out USB CDC compliancy you can try for example USB mouse code, but for me it is all the same.

Now after ignoring it a couple of months I have a reason again to look at it, so few days back I asked guy from http://mcuoneclipse.com/2013/08/01/using-the-frdm-kl25z-as-a-usb-mouse-device/ if he could send me a binary of his code, since that was made with a completely different USB stack. That way I could rule out if the KL25Z itself can't handle USB3, or if for example the PCB connection isn't great, which could be a problem on some USB chipsets and not on others. Now that code besides bricking my mbed (really don't set the reset pin as GPIO, I managed to unbrick it again, but with mbed it is not intended :P), also showed that it worked perfectly fine.

So I am planning in the coming days/weeks to try to figure out where it goes wrong. The problem is that while I have reasonable amounts of experience with regular uC programming, debugging a USB stack is a whole different game.

What is related, the K20 interface IC uses the same peripheral (well maybe different revision, but close enough). That one does work fine. Maybe someone who worked on the CMSIS-DAP code knows what is different between them? (Besides that they are completely different code bases).

Actually - the flashing port works and I have added two listings for the two ports' USB/CDC settings from linux. I think it might be that the CDC descriptors in the USBCDC code should be modified to work better.

posted by Lars Knudsen 20 Feb 2014

I've made a bug report on github for this:

https://github.com/mbedmicro/mbed/issues/193

posted by Lars Knudsen 01 Mar 2014
10 years, 8 months ago.

Hi Lars,

I am a bit confused about this bug report, so could you please give us a complete set of steps to reproduce the issue? Also, were you able to reproduce this issue on anything else than a Mac?

Thanks, Bogdan

The setup is the following:

[A] FRDM-KL25Z with nothing but the factory firmware on it [B] FRDM-KL25Z with firmware on it built with the latest mbed code from https://github.com/mbedmicro/mbed + our own app that initialized the USB Serial port with "serial = new USBSerial(0x2341, 0xbeef);" (we have tried combinations of VID/PID + earlier versions on the mbed repo from github).

We did do one change to the code - made USBDevice non-blocking in initialization like the newly added code to make it possible to boot while nothing is connected. I am 99% sure this is not what is causing it but will try to check.

We only use the flashing/USB SDA port for flashing the device and it's otherwise not connected.

Ok - here goes:

When connecting [A]'s "user USB" Serial (non-flashing) port to the new mac - or any other computer - it pops up as a tty/usb serial device (CDC profile and all)

When connecting [B]'s "user USB" Serial port to the new MacBook2013/Haswell devices - we get an error that "it could not enumerate" (ref: http://mbed.org/questions/2599/Is-USBSerial-giving-problems-on-new-Hasw/ )

We are having issues getting drivers signed for Win8 ... but for ALL other machines than Win8 (meaning: Ubuntu Linux, Chromebook, older macs [pre-haswell - even with new OSX on them] and Windows7) the USB Serial/CDC is detected and it's possible to communicate with the device.

The funny thing is that the factory firmware on the FRDM-KL25Z works with the same port on the same Mac where the mbed code fails (there is some simple touch data logging it sends out) so it's not a hardware issue.

Does that explain?

posted by Lars Knudsen 12 Mar 2014

Just want to add that I have filed a bug with apple also: 16311518

posted by Lars Knudsen 13 Mar 2014

Hi again - the Apple engineers replied - and they seem to be quite specific:

"This is not an OS X problem. It is a low level problem with the board when communicating with a USB 3.0 controller. The device is not responding to a SET_ADDRESS command. In other cases, it does not respond to the GET_DESCRIPTOR(CONFIGURATION). It has nothing to do with the descriptors programmed."

I am not a USB low level expert - so I hope that there are someone here who can help me out with what this means.

posted by Lars Knudsen 22 Apr 2014