* Create trait library. We'll need traits for both the USB host driver and USB device/interface drivers. Right now everything's pretty tied together with no clean separation, but aside from a couple painful points it shouldn't be *too* hard to separate. So far we've managed to avoid needing an allocator, but that's probably gonig to be impossible in the general sense. However, it may be possible to limit allocation to just the device driver level, which is more pleasing since it's more fungible. * Use trait library for SAMD21/51 host implementation. Add features for max devices/endpoints to save on memory. * Use trait library for boot protocol keyboard driver. This code currently lives in `device.rs` and is also a disaster. ** Parse configuration descriptors. * control/in/out_transfer probably shouldn't take a `&mut T`. This is pretty unsafe for functions that shouldn't be unsafe. Instead we should take a `&mut [u8]` and let callers be unsafe if they want 0-copy. This would also allow us to more easily use variable-length responses in the few cases those are used. * Use channel for interrupt -> task messages. Currently we use a static mut which holds the latest event. This was done for expediency to try and get somethnig working and this was working in Arduino. It's also massively wrong in the general case and overflowing with race conditions. A channel will allow us to deterministically walk events and make sure everything's ordered properly. * Clean up pipe descriptor stuff. There's a bunch of unsafe functions that can be made safe. * Some SVD patches needed for SAMD21/51. There's a lot of `unsafe` code where there shouldn't be, because the SVD files are lacking. * Stop passing millis function around. This is horrible, but currently necessary because there are places where we need to loop on a timer at it needs to be hardware-independent. If the USB host library can be made asynchronouse, we could instead pass a current timestamp around and use that for delays where necessary. As a last resort, there's a countdown timer trait in embedded-hal that may be useful. * Tighten up timings on requests. There are a few timer checks on USB requests, but not necessarily of the right duration nor subdivided correctly. For instance, the setup-with-data cycle has requirements on total duration as well as per-packet duration, but currently we're only using the total.