I find the use of USB [HS] curious. What is there that you can do at >12Mbps with a 48MHz clock... I guess as long as you can process each byte in 32 instruction cycles, but I can't think of many use cases.
Lots, from HID devices like keyboards, mice, joysticks, to USB serial adapters and bridges to other buses, to debugging and development tools; and no, that's not how it works.
First, the USB full-speed (12 Mbit/s including overhead) device peripheral handles entire packets between zero and 64 bytes long. It is not like an UART where you receive one byte at a time. Furthermore, it handles the "header" part of each packet, directing the packet to a specific
endpoint (numbered, described in the USB device descriptor), so that you really only need to handle the data part of each packet only.
It is much closer to network datagram programming than working with a data stream byte at a time, really. It also means there is no inter-byte timing issues; you only need to handle each full packet.
What to use these devices for?
Lots.
- Any kind of standard driverless human interface device (HID), like keyboard, mice, joystick, gamepads, touchpads et cetera. The data protocol is simple and easy (except Microsoft as usual requiring odd quirks and special dispensation, because its built-in drivers are odd and not very intelligent), and is thoroughly documented (except for the Microsoft silliness, which you need to consult Microsoft for). My very first microcontroller project was actually an arcade game controller on a 50cm×20cm / 20"×8" birch board using a Teensy 2.0++ AVR microcontroller (AT90USB1280) appearing as a keyboard (with several different sets of keys the joystick and buttons generated) that I used to play online Flash puzzle platformer games.
If you've ever been annoyed at your preferred applications for not having better shortcuts, perhaps want better 3D rotation in CAD/CAM, or better 2D scrolling/panning, you could have solved that with a microcontroller with native USB for USB HID, and a suitable set of buttons, potentiometers, encoders, or even magnetic field sensors. And a 3D printer to make a nice enclosure for it. One of my forever projects is an e-Ink display with a capacitive touch panel, for a programmable physical toolbar (generating application-specific shortcut keypresses), for example.
- Any kind of data bridge between a computer and external device, from UART/Serial, I2C, SPI to GPIO. Unlike the FTDI devices, these can be programmed with additional logic, for example to do any timing-sensitive stuff, or provide an unified interface across similar but incompatible devices. For example, consider small display controllers, for example OLED display controllers, that provide an unified interface over USB Serial (i.e., appear as if serial ports) using a standardized format –– compare to AT command set for modems –– to query the display properties (flashed to the microcontroller) and to control the display contents. If HID devices are my favourite use case, this has to be the second-favourite one. It is an extremely easy way to add a display to Linux SBCs and appliances, as this way I don't need to hope for an exposed UART not already used for a terminal console, and can use an USB HUB to trivially add more than one device and not lose connectivity.
- Debugging and driver development for USB-connected devices. I do prefer to use Teensies with lots of RAM and Flash for this, because that way it is trivial to "replay" even long "USB conversations" with predefined response delays, recorded using Wireshark etc. when a device is talking to its Windows closed-source and buggy drivers, to write my own. I've done this for Silhouette Cameo vinyl cutters, without having any kind of access to one, but a friend in Canada – across the pond – having one, and doing experiments I request, recording the communication between the Windows driver/application and device, sending the log to me, and me examining and writing a Linux userspace driver.
- Quick purpose-designed tools to solve a problem without having to buy expensive test equipment. For example, to explore exposed pins on appliances like routers and TV boxes, one can use an expensive oscilloscope and logic analyzer setup with all sorts of decoders to probe if useful stuff like console UART is exposed; or you can use a few dollar native-USB microcontroller (possibly using a cheap $8 ADuM3160 USB isolator from eBay for isolating the microcontroller from the computer it is connected to, allowing grounding it to the appliance ground) and write a throwaway firmware to start with an ADC probe. When you find a pin with interesting flicker patterns, use a voltage level translator (I recommend TI TXU0n0m for all but I2C, and dedicated ones like PCA9306 for I2C), and connect the pins to the microcontroller peripheral.
What
I do not understand, is why anyone would use a microcontroller
without a native USB peripheral, and instead work with problematic USB-to-serial bridges and whatnot. The popularity of ATmega328/ATmega328p in particular baffles me, as there are several AVRs only a little more expensive but much more useful with native USB support. (ATmega32u4 is my favourite, but I do like both ATmega8/16/32u series and AT90USB series.)
For those preferring PICs over AVRs, the USB ones exist too, starting at PIC16F1454 (under 1.5€ in singles at Mouser).
For those preferring 8051 (MCS-51) cores, there are CH55x programmable with open source tools.
For those preferring ARM Cortex M cores, just about all manufacturers have these, many with Arduino cores for even quicker development (for debugging and throwaway/single-use tools).
My preferred combo is having one (or more, because Windows) HID endpoint, and one or more USB Serial endpoints for bulk data. You can use Force Feedback HID messages or raw HID messages to configure the HID device from an userspace GUI application (easy to do in e.g. Python), although I like to use the USB Serial for this (but via
termios and
termios.tty Python interfaces on all non-Windows OSes, and not pyserial or similar). An extremely typical use case is to remap the arcade plank to a different set of keypresses at run time. In Linux/BSDs/macOS/Android this is very easy and needs no drivers at all; it is only Windows that requires special care, but fortunately I don't use Windows and thus don't need to care.