AnsweredAssumed Answered

Cannot get STM32 host to enumerate a device

Question asked by magester1 on Apr 20, 2015
Latest reply on Aug 9, 2016 by gorse.joseph
Hello everyone!
This is my first time in the forums... so greetings to all of you.

I've been trying for the past week or two to compile the uC as a USB FS host and enumerate a device (for testing purposes I'm using a PC mouse), however, I haven't been able to do so till now.
I'm using the STM32F4Discovery board and compiling with the gcc ARM toolchain. The demonstration that comes pre-compiled into the kit works flawlessly as a USB device.

Ok, so onto the problem.
First, I used the STMcube to generate the code for a FS Host with HID class and wrote the necessary missing 'user code' to drive the Vbus pin. After compiling and running the program, it reaches the enumeration state (ENUM_IDLE) waiting for a response (CMD_WAIT, and further down CTRL_SETUP_WAIT) and never leaves this point. When querying the URB status it returns USBH_URB_NOTREADY. I can see the mouse lit up so I know power is reaching it, I'm trying to discard as many 'dumb' problems as I can.

Now, the provided host/device library doesn't really work for me, there are some things that don't work the way I need them to, so in time I was going to have to change it or re-write it. So, given that the generated code doesn't even seem to work I set on to that task.
I've read the Reference Manual, and it's really a shame to see how little the initialization process and such are documented. It's as if they expected you to go look at the examples, which I don't really mind but it could at least be noted so in the manual.
Anyway, I've gone through the process of setting up the needed registers with the appropriate values, even comparing against the generated code and the old USB_OTG/HOST/DEVICE library which, frustratingly enough, behave quite different during initialization and ISRs. And I seem to have reached the same blockage as with the STMcube code.
The manual states that when you change the PHY clk speed after detecting a new device you need to perform a port reset (if the value actually changed) via the PRST bit in the HPRT register and this is consistent with the old library, however, the STMcube generated code doesn't follow this step. Is there a reason for it? Which of the two should I follow?

After the host initialization routine (either performing the port reset or not) I set up channel 0 as a ctrl SETUP pipe. Then, I enable ch 0 and write two words to the TxFIFO (0x01000680, 0x00120000) which contain the standard get_descriptor request, right after that I enter an infinite loop. At this point 3 things can happen at random:
1) An HAINT interrupt triggers with HCINT(0) bits ACK and XFRC asserted. This is what *should* happen if the transaction was successful, right?
2) An HAINT interrupt triggers with HCINT(0) bit TXERR asserted. This indicates a 'Transaction Error', but it doesn't really tell you *what* caused the error... what should I do in this case?
3) Nothing... really, it just gets stuck in that loop because no interrupt is triggered whatsoever. Now, of course I could do something to avoid that, but how come no interrupt happens? Shouldn't I at least get a transaction failed or something?

Something I tried over that is to resend the transaction in case a couple of seconds go by with no response (or a TXERR). Although I'm not entirely sure how to preform this... is there any specific order in which to retry a transaction?
To start without much complication I decided to just restart the whole host, from disabling channel 0 and the host by setting PENA to 1 to flushing the FIFOs and performing a new port reset on the device. Basically, just calling the same host initialization routine again, however, after the channel is once again setup and enabled, writing to the TxFIFO does nothing, I go straight into case 3) above. Maybe I'm missing something and restarting the host is a more complex process, is this not how it's done? Should I just write into the FIFO those two words again and not worry about starting anew?

I've been fighting with this for almost two weeks now and have really reached a point I can't seem to move anymore forward.
I'd appreciate if someone could point me in the right direction. I can provide whatever other information is needed, I just felt that I shouldn't post my entire code or something like that right from the start, it's a bit long and might not even be necessary.