STM32 Switching from standard peripheral to HAL. USB device always shows up as "Unknown Device" in windows - usb

I have a project that needs to be compatible with STM32F1s and STM32F4s. I'm starting with a basic project that can use GPIOs and am now trying to get USB HID support. I have USB HID working on STM32F4s with another project using the standard peripheral drivers and USB OTG, but am having a difficult time with the HAL drivers. No matter what I've tried the USB device keeps showing up as an Unknown Device in windows. Where can I best start debugging this issue? Stepping through the code with an SWD makes it seem like the board seems to be working as it should. As far as I can tell the endpoints and descriptors for HID are correct.

Use STM32CubeMX to setup USB for you. Then you need to change the heap size, because the default one is not big enough. For some reason, you cannot change the heap size from STM32CubeMX. To change it, you need to edit the start up file (startup_stm32f4.....s) and find the line:
Heap_Size EQU 0x00000200
and change the value to a bigger one, for example:
Heap_Size EQU 0x00002000

Related

ST-LINK could not connect to the target

I'm trying to connect to stm32f401rbt6 with st-link utility.
The MCU has 6 pins connected, as on the image below.
The target is powered by a lab power supply, target GND is connected to the ST-Link GND
When I plug it to the computer, st-link utility says it can't connect.
Tried:
Update ST-Link firmware
Connect under reset is by default, tried all available methods
Checked connectivity for the pins on the image
Connected with the same ST-Link to other MCU
Desoldered the MCU and soldered another one
The issue is still remain. Please suggest what I'm doing wrong, or how to check that my MCU is alive.
I once had similiar issues and i figuered out, that decoupling capacitors were vital. After soldering this onto the pcb, it worked like a charm.
(Similar question: Stm32CubeProgrammer not connecting (no error msg) using ST-LINK V2 dongle and Lora E5 mini board)
You can try the following suggestions. Some ST devices are a lot more sensitive than others when it comes to programming. I have had some ST devices programming without issues and then using practically the same setup on other devices it just won't work.
Place a 22ohm resistor in series on the SWDIO and SWCLK lines. This link suggests only placing it on the SWDIO line but I found that I needed it on the SWCLK line as well. Typical SWD Circuit
For the ST Link Settings try using these:
Reduce the frequency from 4MHz to a lower frequency
Use SWD
Use connect under reset
Don't use an external pull-up on the NRST line.
Make sure that your programming wires between the ST-LINK and the target board are as short as is conveniently possible.
(This one I must stress as being important) Make sure that your processor's ground pins are all connected very closely together (i.e. the tracks between them are as short as possible) and that very importantly your programmer ground is also connected to the same ground pins very closely.- At high programming speeds a thin or long unbalanced (different length) ground track to the processor can cause a problem with some devices.
Whatever you are using to supply power to the processor must have a supply with a similar voltage as the ST-LINK (mine is 3V) - (although I have found that if the processor supply is 3.3V programming seems to still work most of the time.) (Remember the original ST-Link does not supply power only reads the power level.)
A dodgy programming setup can accidentally set the protection to LEVEL 2 bricking your device - so if you have been trying and not getting any further, it might be time to replace your IC.
Prior to changing / erasing a device that had been programmed to LEVEL 1, you might need to first enable the PCROP_RDP option byte. - Once enabled, you should be able to change from LEVEL 1 to LEVEL 0 that will automatically erase the device.
Some people have suggested holding the device in reset until just after pressing the erase button to enable erasing it.
I hope these suggestions help...

Why might an Adafruit CircuitPython board's filesystem fail to mount?

Why would the file system (CIRCUITPY) of an Adafruit board running CircuitPython not show up when connecting it to a suitable host via a micro usb cable?
This happens to me often, usually when I am copying files via Windows, most often with my trinket which uses the integrated chip flash memory rather than the separate SPI flash chip. Why? I don't know. A bug somewhere obviously. :)
So the solution.
Always save your work files locally or use a source code solution like git
Switch to the boot mode (double click reset)
Drag the erase.uf2 file to clear the flash memory
Drag the circuit python uf2 file to reflash python
Restore your files saved on your PC
Basically, I've made it a habit to assume the flash memory is temporary and volatile and not store any critical code only there.
You can read more about the erase uf2 and reflashing, general troubleshooting here:
https://learn.adafruit.com/welcome-to-circuitpython/troubleshooting
Besides your first answer about the cable, because of the relatively inexpensive nature of the boards and direct access to their power/ground sometimes the EPROMs that the file system are hosted on just go bad and give unexpected results. Best idea is to:
Test your environment with another board.
Reflash micro python on your board so you can start from scratch (didn't mention if you'd tried that).
JerryN mentioned the most common cause of this is using a USB cable with no data wires. Some USB cables are designed for power-only and have 2 rather than 4 conductors. These will power the device but will prevent mounting of the drive and use of the serial connection over USB.
Unfortunately these cables are often not marked as power-only so can be difficult to spot.
Another case is where CPLAYBOOT (this varies per board, e.g. GEMMABOOT, FEATHERBOOT, TRINKETBOOT) disappears on Windows. This can be caused by installation of the Arduino software which has an old, conflicting driver from 2007. More information on Adafruit: Circuit Playground Express: Troubleshooting.
A very rare case is a mis-seated USB connector. In my case the power was ok but the data wasn't for a good quality cable which had previously worked fine. Unplugging the USB cable at the host end and re-inserting it solved the problem.

Limit usb power output

I work with an embedded device that has a USB host port. I would like to connect an iPhone to it and communicate via USB. I have done development on this and ported the functionality to connect to usbmux on the iPhone and have successful communication, however there is another problem.
All development was done with the iPhone connected to a powered USB hub that was connected to my device, as soon as I connected it directly, after enumeration it starts to drain the battery of my embedded device and causes a tension (voltage) drop that causes my device to turn off.
I know that after enumeration usb devices can draw up to 500 mA from the usb port, but I was wondering if there was a way to limit that to 100 mA (while still having the iPhone registered).
I found various questions regarding controlling voltage on the data pins or vcc from the usb port and I understand that's not possible, I'm looking for a software solution (although hardware solutions are welcome).
tl;dr: Is there a way to supply the iPhone with less than 500 mA after enumeration? Could I do this in software? Or do I need a hardware solution? I don't want to turn the port on/off, just limit the power draw of the iPhone.
NOTE: I am using Windows CE 6.0, if it is something that can only be done by modifying the drivers, or having direct access, there is no problem.
P.S. also, if there is a way to do this in *nix (or some other open source OS) that I could look at the source code and port it to Windows CE please let me know.
When a device shares its available configurations (see USB chapter 9), it specifies how much power it requires for each configuration. The host should look at all the available configurations and choose which one it wants.
In practice, however, these things don't work so smoothly.
The last time I looked at this, Windows always chose the first configuration. MacOS always chose the lowest power configuration (or highest, I can't remember). I never looked at WinCE or Linux.
If you're writing/modifying the driver, you can set your own rules for which configuration to choose, including looking for one that's 'self powered'. The iPhone, however, might only have one descriptor that always requests 500mA, bus powered. If so, then you're pretty much screwed since there's no way to let the iPhone know it's not OK to draw power.
That being said, I believe all the iPhone accessories are actually USB host (as opposed to USB device), and given that they don't always supply power, the iPhone must be capable of enumerating self powered.
I like the answer by Russ Schultz but I want to add another one:
No.
The descriptor of the peripheral device, iPhone in this case contains bMaxPower. If you enumerate this device, you also accept the power demand. It is not possible to only supply less, lets say 300 mA, if you already enumerated the device with the 500 mA desriptor. If this is what you wanted.
If the device provides multiple configurations, you are as mentioned by Russ free to write a driver which selects the configuration with less power. Hopefully, the device will then only consume the granted power.
Many peripheral devices just don't care. Most devices only provide one configuration with 500 mA. And there are a lot of devices which just consume more than they say ...

PIC Bootloader -- USB controller required?

I am working with a simple PIC18F2550 and I'm wondering about how to get a bootloader working on it. It's a very simple device with a USB port and CDC firmware. When I download Tiny Bootloader onto the pic, my PC doesn't recognize the device. Do I NEED to have a USB controller in my circuit in order for it to work? Such as the MAX232?
Would the same apply to the PIC32MX795F512L?
Thanks!
It is clear from the Tiny PIC boot loader documentation that it expects a UART connection rather than USB (that is what the MAX232 is for - it is an RS232 line driver).
You could simply do that and use an external serial to USB converter thus saving the code space required by the USB-CDC stack. Otherwise you will have to modify the boot loader code to use the CDC driver rather than the UART.
You will have to link the USB code with the boot loader, which will no doubt significantly increase its size. You may need therefore also to move the application start address to accommodate the boot loader. Furthermore, if the application needs USB comms, you may need a separate copy of the code in the application unless you provide a method of accessing the bootloader code from the application; which is possible, but not necessarily straightforward.
All that said, note the part at the end of the end of the page about extending the bootloader; On the face of it it seems unsuited to extension. Without looking at the code and its memory map, it is not clear why it has this constraint.
The PIC18F2550 has a USB interface built into it. It is called the "USB SIE" and there is a large section in the datasheet that documents it. If you make the right electrical connections, you should be able to connect your PIC18F2550 directly to a USB port without any active electronics between them. There is no reason you would need extra USB hardware just because you want to run a bootloader.
If you want to troubleshoot your problems with the bootloader, you should probably post another question with more details. It could be a problem with the PIC's configuration bits or something like that. I recommend trying to modify the bootloader to get it to blink an LED as a basic first step just so you can verify that you were able to get its code to run at all.

Android USBHost mode - why does my IRDA device fail on claimInterface?

I have a Lindy IRDA USB bridge attached to my Xperia Neo (Cyanogen Mod 9). I have changed the features to support host mode etc. All is looking fine in the code. I detect the device. I can see the interface and the two endpoints (one in, one out), however as soon as I try to claimInterface it fails, regardless of whether I atempt a force claim or not.
There appears to be no simple way to find out why the claim fails. Though strace gives me a clue as the ioctl call for claim interface fails with a device not found error.
Ignoring the failure gets me only as far as the request which then fails to queue or send.
The questions I have are (I think):-
What exactly is missing that is resulting in the claim failing?
Is there a way around this that ideally would not require root?
Is there a way to override the claim somehow?
OK, so I appear to have fallen into answering my own question here, but I see that a number of people are getting confused over the apparent support for USB Host and the "odd" behaviours that can be observed so hopefully this answer may help some of you out.
I posed 3 questions, I have a definitive answer for 1 & 3 but I am less certain about the other at this stage.
1) What exactly is missing, and why does this result in a bad claim?
The problem is that the device, a lindy IRDA dongle is being detected by the host (my Xperia Neo handset) but that the only configuration that it supports is demanding too much power for the handset to support.
Oddly, this does not prevent either a) the device from being detected and enumerated by the Android libraries or b) from it appearing to be powered (red LED glowing)
There is no report at the time of the failing claimInterface() call from any system libraries, however a dmesg|tail running when the device is attached gave the necessary insight.
dmesg | tail
<3>usb 1-1: device v066f p4200 is not supported
<6>usb 1-1: New USB device found, idVendor=066f, idProduct=4200
<6>usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
<6>usb 1-1: Product: IrDA/USB Bridge
<6>usb 1-1: Manufacturer: Sigmatel Inc
<6>usb 1-1: rejected 1 configuration due to insufficient available bus power
<4>usb 1-1: no configuration chosen from 1 choice
Further investigation showed that this little device was claiming a requirement for 440mA which seems rather a lot but there seems little that can be done about it.
Questions 2 Can anything that does not require root be done to work around this?
It seems not. In theory I could provide external power to the device through the use of a USB Y cable or similar hackery but I don't believe that that would change the underlying problem that the handset refuses the demand. Even with root it is not clear that anything can be done to override the power profile.
Question 3, is there a way to override the claimInterface() failure and force the communications?
This is a blunt no. The device has simply not been created by the kernel so there is nothing there to override in the first place. Which does make it somewhat puzzling as to why the Android libraries still offer it up.
As to Question 2 and power demands...
Most android devices that support Host/OTG that I have run across, will only support a maximum current draw of around 100 mA. Could you force it to work via some kernel source hackery? Likely, but you would run a very real risk of burning up the USB support circuitry in your android device. This is because the Boost converter that such devices use to power the external usb device only physically support that maximum 100 mA current draw.
Could you use a Y-Cable to supply the needed current externally? Yes, I have done this before on a device that had no boost converter, but you would then need to have a workaround in the kernel to tell it that you had such external power, and that it was now okay to power the device up.