Closed bombasticbob closed 7 years ago
also see #23 - USB bootloader
work in progress still, having trouble with the 'convoluted' way in which the existing USB support works. It may have to be completely re-written. Docs for the USB hardware aren't much help, and sample code is cryptic and difficult to follow. In short, it's a MESS.
'usb device' sample code (for cdc) when built with Atmel Studio goes into a boot loop. not sure why. It doesn't matter if USB is plugged in.
USB header file incorrectly specifies transaction complete vector as '127', while ATMel Studio headers specify it as '126'. Modified working code to re-define USB_TRNCOMPL_xxx constants for 64a1u and 128a1u (will probably leave 'as-is' for now).
currently work-in-progress. will upload working 'core' code as soon as it is available.
code is partially working, with respect to receiving and sending packets and the memory management associated with it. Some fixes went into place to address serialization of output following a command on the control chanel; i.e., all output must now be sent before another packet will be handled on the control channel. At this point the various functions work up to the point where the actual device (i.e. CDC or HID) is sending its descriptor information, at which point it's "just plain wrong" and so needs to be addressed at that level. Several packet types not specified in the atmega code seem to be involved in this problem, including a type '6' i.e. 'DEVICE QUALIFIER' which has no constant definition for it.
A careful analysis of the USB protocol is in order, including ATmel sample code as well as open source USB implementations, with respect to this implementation. Otherwise, the device ID is being assigned correctly and traffic is happening in both directions on the control channel.
worth pointing out: the ISR handles all of the traffic, and callbacks are made in the context of an ISR. It may be necessary (at some point) to have some kind of scheduled event callback, or else use the 1ms 'heartbeat' for that purpose. So you would have to queue up a callback, in other words. Since the packet could be removed from the input queue and (essentially) attached to a callback, this isn't really a problem, just an architecture. The assignment of the USB ADDRESS is already handled by assigning a global variable to the new address, and waiting for the next packet to be sent on the control channel. After it's sent, it's safe to change the USB ADDRESS, and the assignment is made within the 'check for sent packets' handler.
All of this attempts to preserve the asynchronous nature of packet send/receive and the need to wait for send complete before handling another control request. Regular I/O, of course, would be handled asynchronously.
so far USB appears to be 'working' for getting the endpoints recognized by the OS. Linux sees the endpoint now and generates an 'ACM' tty device.
However, sending data from the xmega side is not working, and receiving only gets EVERY OTHER PACKET for some reason [even though I can see the packets on a sniffer].
NOTE: need to re-factor the API used by CDC.c and HID.c . Possibly add device implementation for MIDI and anything else I can think of.
'HEAD' has USB "working" for the moment, for basic kinds of things. CDC driver still not working properly for writing - apparently the protocol requires some additional things, maybe with the interrupt endpoint, and handling for the interrupt endpoint doesn't seem to work at all. What IS working is the control endpoint and some of the basic I/O features.
A lot of code refactoring has been done to break away from the 'atmega'-ness, and support a more asynchronous way of doing things. Callbacks that return the correct information, instead of hackish callbacks that require you to "unsend" a packet JUST because you want to know how bit it is, have been replaced with callbacks that actually tell you "the packet is THIS long" or "I have THIS many endpoints".
An implementor's guide will most likely follow, in the wiki.
The good news is that the idiosyncracies of the xmega implementation are (essentially) being "worked out". My plan is to get CDC to work 'as advertised', THEN focus on porting the 'catarina' bootloader for atmega 32u4 to work with the xmega 128a1u [including the same protocols]. Following that, I'll work on the 128a4u, possibly a similar config to the 64d4 [since its peripherals and layout are similar as well].
This project has been difficult, frought with poor documentation and spaghetti sample code from ATmel. I have been told that their engineers ONLY work on the sample code in their spare time, which is why it looks "that way" and lacks proper documentation for making your OWN version. MY goal with this project is to document it well enough that ANYONE can look at MY code and make their own implementation without much difficulty.
Most recent commit implements CDC successfully. A number of potential problems remain, particularly the fact that some of the code might be totally unnecessary, and other parts have way too much debug stuff going on. The code needs refactoring, and of course HID needs to be implemented. As problems are corrected, this should clean up nicely. Need to bump the IDE revision to include this code after fully testing it on multiple CPUs.
CDC seems to be reasonably reliable as long as you don't flood the device with single-byte OUT transactions (see #33). HID still needs implementation. I will close this issue and make that one a separate issue.
there is USB support in the core. It needs to be working for the 128A1U.