[HN Gopher] Making USB devices - end to end guide to your first ...
___________________________________________________________________
Making USB devices - end to end guide to your first gadget
Author : todsacerdoti
Score : 350 points
Date : 2024-06-03 07:53 UTC (15 hours ago)
(HTM) web link (popovicu.com)
(TXT) w3m dump (popovicu.com)
| foz wrote:
| A very nice writeup and intro into USB, although - it's very
| focused on using an ST microcontroller, which is a lot more steps
| and toolchains compared the the recent ESP32 ecosystem that
| offers a number of easy plug-and-play ways to make USB devices
| work (for example, several projects from Adafruit's learning
| pages provide basic use cases). Another issue is differential
| pairs - having designed several working USB boards myself, this
| has not a concern for beginners, mainly relevant for doing high-
| speed work. USB controller ICs (as used typically with
| arduio/esp) can handle a lot of the details for you, so doing the
| calculations seems overkill, especially for someone making their
| first gadget.
| lemonlime0x3C33 wrote:
| I think it is nice to have a basic understanding of
| differential pairs and impedance, I will admit I never really
| had to do the calculations since the ecad software I use has
| several tools for routing differential pairs and even analyzing
| signals for impedance. But as long as you keep your traces
| really short it normally doesn't matter.
| vgalin wrote:
| I recently built a small hand-wired macro pad using an Arduino
| Pro Micro equipped with ATmega32U4, it's apparently quite
| popular amongst hobbyists building custom keyboards. Quick and
| fun project for a beginner, the most tedious part of this
| project was to carve the wooden case.
| fulladder wrote:
| > USB controller ICs (as used typically with arduio/esp) can
| handle a lot of the details for you
|
| Can anyone recommend any good USB controller ICs? I normally
| just use a microcontroller with USB built in.
| lemonlime0x3C33 wrote:
| I have had a good experience using microchips USB2514 and
| USB2512
| stragies wrote:
| I just looked up the USB2514, and it would seem to not
| support PerPortPowerSwitching. (used by e.g. uhubctrl to
| toggle/switch power to individual USB ports). Am I not
| reading the specs correctly?
| lemonlime0x3C33 wrote:
| I was able to reset downstream USB devices using usbreset
| to the individual ports (or the entire hub) in my design,
| using usbreset. I did also have a hardware reset built in
| using the cfg_sel0 and cfg_sel1 pins 24 & 25 and RESET_N.
| I did not try to turn off power to those ports for any
| extended time so I am not sure if that works.
| arrw wrote:
| Very cool guide.
|
| But if you are worried about soldering more fiddly stuff like
| those ARM processors: It doesn't have to be that big, STM32 is
| nice if you need the power, but for smaller stuff smaller
| controllers can be preferrable.
|
| E.g. one may also consider using VUSB, which is a library that
| bit-bangs USB on small Atmel microcontrollers:
| https://www.obdev.at/products/vusb/index.html Example board
| schematic we've used to teach students Linux kernel module
| programming: https://gitlab.cs.fau.de/i4/passt/passtboard-v2 with
| firmware http://www.poempelfox.de/ds1820tousb/ and
| https://gitlab.cs.fau.de/i4/passt/ds1820tousb
|
| Also very easy, if you are inclined towards Arduino style
| programming there are tons of boards you can just use as USB
| devices with the included libraries in very few lines of code,
| for example https://www.az-delivery.de/en/products/digispark-
| board
| unwind wrote:
| There's also things like the CH32V203 [1] which is a TSSOP-20
| with hardware USB and costs around $0.81 in singles. The
| software side might be a little more ... challenging, though.
|
| https://www.wch-ic.com/products/CH32V203.html?
| 15155 wrote:
| CH32F series is more or less the same and actually has
| CoreSight SWD and clone STM peripherals
| zoobab wrote:
| Software USB can also be done on the 10 cents CH32V003:
|
| https://github.com/cnlohr/rv003usb
| michaelt wrote:
| _> if you are worried about soldering more fiddly stuff like
| those ARM processors_
|
| If soldering's a worry, you can get quite reasonably priced dev
| boards with the microcontroller USB port already fitted and
| working - such as the NUCLEO-F429ZI
| https://www.st.com/en/evaluation-tools/nucleo-f429zi.html
|
| Very similar to the NUCLEO-F103RB board the post author used,
| but as well as the USB connector at the top of the board for
| the built in programmer/debugger, it also has one at the bottom
| of the board, wired straight to the microcontroller.
|
| You can also download the board's schematics, if you want to
| copy their choice of ESD protection and suchlike.
| lemonlime0x3C33 wrote:
| This is a very well written and informative article for working
| with USB, wish I had it when I first started USB signals.
| dvh wrote:
| I recently used CH340N (soic 8 virtual com port) and it was
| really easy. Easy soldering, no extra parts just directly connect
| to USB, works out of the box on Linux.
| anymouse123456 wrote:
| Friendly reminder that USB is not free.
|
| You must pay a one-time fee of $6,000 in exchange Vendor ID [0].
|
| [0] https://www.usb.org/getting-vendor-id
| zoobab wrote:
| See also https://pid.codes/
|
| For the DirtyJTAG project we use one of those:
|
| https://pid.codes/1209/C0CA/
| pjc50 wrote:
| .. or use someone else's. I believe there's a hobbyist VID
| under which you can reserve PIDs, or in many cases you can just
| copy an existing product if your device is generic enough and
| you're not planning to sell a big production run.
| hananova wrote:
| There's pid.codes which uses a vid of a defunct organization,
| but before that there was also the F055 vid. I still use that
| vid because no company will accept that vid, since it's
| commonly used by foss projects.
| michaelt wrote:
| Many chip vendors will give you a PID under their VID if you're
| making a product. For example this blog post uses and ST chip,
| and they'll provide a PID if you request it [1] - free of
| charge, but subject to some conditions.
|
| (Of course if your USB device needs Windows drivers, you'll
| still have to deal with things like code signing...)
|
| [1] https://community.st.com/t5/stm32-mcus-embedded-
| software/dea...
| brezelgoring wrote:
| Wow, first time I hear about it, this is an eye opening
| experience.
|
| I will think twice now before saying "why couldn't they just
| use USB for this?"
| kraskoss wrote:
| Even crazier, it's just a 16 bit value.
|
| What are they gonna do when they run out?
| yjftsjthsd-h wrote:
| > I will think twice now before saying "why couldn't they
| just use USB for this?"
|
| I dunno, I think either you're doing a small run and you can
| just bake in a Teensy or whatever, or you're doing a big run
| and $6k is a drop in the bucket.
| rm445 wrote:
| Yeah, I was going to ask about this. I think ST Micro will
| sublicense you a PID under their VID, but with restrictions,
| and companies attempting to buy a VID and sell PIDs as a
| service have been sued?
| Karliss wrote:
| The part that makes me feel most uncomfortable about usb
| VID/PIDs is that they are only 16bits each. While I don't think
| 4billion unique commercial USB devices is limit we will reach
| anytime soon, efficiently managing the available address space
| is a different question. And unlike IPv4 addresses a range of
| USB VID/PIDs can't be as easily reused without making the
| VID/PID meaningless.
| crote wrote:
| By that time they'll just add an extra field to the protocol
| and assign a special "see other field" VID/PID pair.
|
| For a lot of products the VID/PID combo isn't _that_
| important on a protocol level, and there 's technically no
| reason why two completely unrelated products couldn't be
| using the same pair. In practice you're mainly going to use
| them for software to target a _specific_ device, for example
| the Linux HID driver uses it to work around hardware
| /firmware bugs. But HID devices are self-describing, and
| that's the main mechanism used by the driver to figure out
| what has been attached and how to behave.
|
| If modern OSes can do the same to distinguish hardware with
| the extra field, sharing the same value for backwards
| compatibility with legacy machines really isn't going to be a
| big deal. It's not like MAC or IPv4 addresses where a clash
| will essentially kill all communication.
| crote wrote:
| For hobbyist use you can just pick a random value and it'll
| _usually_ work. Open-source hardware can get a product ID for
| free from https://pid.codes. Small-run commercial hardware can
| usually get a free product ID from the maker of their USB-
| capable chip. And once you're big enough that you're designing
| your own chip, $6,000 isn't such a big deal anymore.
|
| So yes, you are _technically_ right, but it really doesn 't
| matter all that much in practice. USB is by far one of the most
| accessible major hardware standards out there.
| andoma wrote:
| FWIW, for my own personal projects I resort to vendor id 6666
| (Prototype).
| teddyh wrote:
| I've commonly seen OpenMoko's ID, 1d50, used for free projects.
| See the list at <http://www.linux-usb.org/usb.ids>.
| hananova wrote:
| I just use 0xF055 as VID. What is the USB-IF gonna do?
| nudgeee wrote:
| NXP runs a USB VID/PID Program [0] for small production designs
| (<10,000 units) that use their MCUs. They'll give you 3 PIDs
| for free under one of their VIDs. I use this in my side
| projects (~200 units) and works pretty well!
|
| [0] https://community.nxp.com/t5/Kinetis-Microcontrollers/NXP-
| US...
| CamperBob2 wrote:
| Easy way around that is to license your PID(s) from MCS
| Electronics. They bought a VID before the USB-IF got around to
| prohibiting resale of PIDs.
| kevmo314 wrote:
| Are there any development boards with USB 3 support? I'm trying
| to prototype a USB C monitor sink but having trouble finding a
| board that has the power necessary to receive DisplayPort over
| USB.
| dfox wrote:
| There is this:
| https://octopart.com/cyusb3kit-003-cypress+semiconductor-494...
| and the pricing seems reasonable. When I looked for something
| like that two years ago the prices were order of magnitude
| higher.
| BertoldVdb wrote:
| This device is not really suited, it is a high speed USB3.0
| peripheral. You might be able to use it with the right
| software, but then you are just using the CPU in it.
| dfox wrote:
| The way how the Cypress FX series works (and for that
| matter majority of non-trivial USB-to-something chips do)
| is that there is a bunch of DMA-capable peripherals inside
| and the in fact ridiculously underpowered CPU core inside
| only sets up the required configuration for the DMA
| transactions to happen.
| BertoldVdb wrote:
| There is not much power needed to receive DisplayPort over USB
| (assuming you already can receive displayport signals or just
| route them to an external monitor).
|
| You just need to implement an USB billboard device (optional to
| make it work, but required by the spec IIRC) and signal the
| correct alternate function. Then DisplayPort signalling will be
| present on the USB-C plug. Then just connect the right AUX
| wires to the DisplayPort connector.
| 15155 wrote:
| Most FPGAs with transceivers can do it.
| kevmo314 wrote:
| Do you have an example? Looking for a product recommendation
| others have good experience with
| 15155 wrote:
| https://github.com/enjoy-digital/usb3_pipe
|
| I don't know that there are any fully-baked solutions for
| it though, but it's definitely doable in-FPGA with some
| effort.
| perbu wrote:
| fwiw; I've prototyped some USB gadgets using Raspberry Pi Zeroes
| and Composite USB in the Linux Kernel. At least storage and
| serial devices were pretty easy to get going.
|
| You'll need something like a shell script on the Raspberry to
| initialize the composite kernel module and you'll find the
| boildplate in the kernel docs.
| the__alchemist wrote:
| A note on USB-C, to augment the article's note: Wire the CC pins
| to appropriate resistors, or it probably won't work!
|
| And a note on the differential routing and impedance: For USB
| 2.0, it's not a big deal. Keep the traces of similar length, and
| reasonably direct. Probably next to each other. You probably
| don't need to worry about fine-tuning the length and trace
| widths, impedance control, RF best practices etc. Just connect
| the nets.
| jmole wrote:
| 480MBit/s is fast enough that you do need to worry about best
| practices and impedance matching within 10% or so. Many MCUs
| will also need series resistors between the USB PHY pins and
| the connector.
|
| Will you need to respin a board because you needed to use a 20
| mil trace instead of 24 mil? Probably not. All things
| considered, laying out a USB 2.0 differential pair is pretty
| low stakes. But you should still try and do it right - it's
| good practice.
| dnpls wrote:
| what about converting existing devices from USB-A to USB-C? I
| have a bunch of powerbanks lying around that I'd love to keep
| using but most of my devices now use a USB-C charging cable,
| would it be a simple case of replacing the ports and re-soldering
| or is there any extra component I need to add?
| the__alchemist wrote:
| I would use an adapter for that use case.
|
| The wiring of the ports on a new design is straightforward; you
| are using the same pins if it's USB 2.0 (As the article says),
| plus two extra connections that go to a resistors. If you can
| find ports that use the same footprint, feasible, but probably
| not worth it. Desoldering a port is a pain because you have to
| get all the pins to melting temperature concurrently, and you'd
| have to figure out how to wire those CC pins.
| the__alchemist wrote:
| OK, dumb question, but since we're talking USB on STM32: Does
| anyone know how to support receiving more than 64 bytes in a
| frame? I've been looping over 64 byte frames in software, but I
| know it's possible to go higher. (Up to 1Mbyte I think). The
| problem is, the Reference Manual lists settings for this that are
| not normal registers. They are a pseudo-register of some sort.
| Wondering if there is an easy workaround for this! (The non-OTG
| USB peripheral)
| genter wrote:
| USB full speed bulk transfer is limited to 64 bytes. (Dunno
| which stm32 you're talking about, but stm32g4 is only full
| speed.)
| jmole wrote:
| A single BULK USB endpoint can only support 64 bytes per
| transfer. You could make use of multiple endpoints (8 are
| available in total) or switch to isochronous endpoints which
| can support up to 1023 bytes per frame.
|
| Most hardware support for isochronous transfers requires DMA
| on the MCU side, so it tends to be a pain unless your vendor
| has a library that handles it for you.
|
| You can in general send up to 19 bulk transfers in a single
| frame (even on a single endpoint), but again, vendor
| libraries differ wildly in their support for this.
| AdamH12113 wrote:
| Note that isochronous transfers require kernel-mode drivers
| on the host side, so you won't be able to use libusb in
| that case. Bulk transfers are the way to go if you want
| high throughput.
| the__alchemist wrote:
| Isn't the restriction just on the reception side? So, if
| you have a MCU talking to a PC or another MCU, you can
| _send_ however many bytes you want, but not receive? I
| say this because A: The Reference Manual only indicates
| this limit for reception, and B: I only experienced this
| on reception: PCs seem capable of sending and receiving
| messages larger than 64-bytes, and STM32s seem capable of
| sending messages larger than 64-bytes, but not receiving
| (without isosynchronous, or anything special)
| AdamH12113 wrote:
| The limits on packet size are based on the transfer type
| (control, interrupt, isochronous, or bulk) and whether
| the connection is low speed (1.5 Mbps), full speed (12
| Mbps) or high speed (480 Mbps). The USB module on the MCU
| will be designed for the largest possible packet, which
| IIRC is a full-speed 1023-byte isochronous packet. (MCUs
| usually aren't fast enough to reach high speed.)
|
| Data larger than one packet can be sent as a multi-packet
| "transfer". This is where bulk transfers get their
| throughput -- at full speed, the largest bulk packet is
| only 64 bytes, but you can send 19 bulk packets per
| 1-millisecond frame, which gives 1216 bytes/millisecond,
| more than the 1023 bytes/millisecond possible with
| isochronous.
|
| You might be able to force the hardware to send
| nonstandard packets, but then it's not really USB any
| more.
| the__alchemist wrote:
| I appreciate the insight! That makes sense in context.
| the__alchemist wrote:
| G4 indeed! I think something in the RM implied it could go
| higher, but I had trouble interpreting it. Thanks for the
| explanation.
| petabyt wrote:
| I've been using https://github.com/xairy/raw-gadget to create a
| virtual USB device on my raspberry pi I've got plugged into my
| PC. I'm currently using It to emulate a MTP camera so I can spoof
| some proprietary software.
| worthless-trash wrote:
| You gotta give us more details than that! Sounds like fun!
| _spduchamp wrote:
| I use ESP32 mostly but I have a cheap hack that fits a lot of
| projects...
|
| For super quick easy custom controllers, also consider pulling
| the control board from discarded USB keyboards. Use conductive
| glue instead of solder to attach wires to the contacts, and a
| helping of hot glue to keep them secured. I've made cheap but
| very robust 1-button game controllers with an arcade button that
| sends a space bar click. You get all the debounce etc, no code.
| mcshicks wrote:
| I used to test devices for USB compliance a long time ago. One of
| the things I often saw problems with was the inrush current test.
| Basically too much bypass caps on the 5v. I didn't see it
| mentioned in the article. It's really easy to get focused on the
| high speed digital design but for compliance it's sometimes the
| less sexy stuff that gets you. No idea how this stuff works with
| newer versions of the standard but it seems like there still is a
| test. Nice article though.
|
| https://compliance.usb.org/index.asp?UpdateFile=Electrical#:....
| amelius wrote:
| What devices do people use to limit inrush current? You can
| make a current limiter with a few transistors, but I'm guessing
| there must be better integrated solutions (e.g. with
| temperature protection, etc.)
| mcshicks wrote:
| You can use inductors. Some USB cables have a choke on them.
| But basically the problem is when a large amount of circuitry
| all powers up at one when you plug in. So everything
| connected directly to USB 5v with a lot of large capacitors
| to filter the power. If you really need that then you can
| self power and avoid the problem.
| AdamH12113 wrote:
| Ive written bare-metal USB code on an MCU before, and I found it
| to be quite a shock compared to simple digital protocols like SPI
| or I2C. The physical and data link layers aren't much more
| complicated than, say, CAN, but beyond that you immediately run
| into a brick wall of descriptors, endpoints, and driver
| configuration. USB was designed from the ground up to be a plug-
| and-play ecosystem for PCs, and it really shows. Using the
| vendor-provided software as much as possible is definitely the
| way to go if you can.
|
| Some half-remembered hints: You want bulk transfers for high
| throughput (don't even look at isochronous). USB is a
| master/slave protocol so if you're not getting peak throughput
| it's usually due to something on the host (PC) side. If the
| license (LGPL) is compatible with your needs, libusb is pretty
| easy to use. If you're not using the vendor driver, a hardware
| USB protocol analyzer is _really_ helpful. USB in a NutShell[1]
| is a decent web reference for understanding the protocol.
|
| [1] https://www.beyondlogic.org/usbnutshell/usb1.shtml
___________________________________________________________________
(page generated 2024-06-03 23:01 UTC)