Repository navigation
usb: support the USB peripheral in ATmegaxxU2 and ATmegaxxU4 MCUs - #603
teknoman117 wants to merge 6 commits into
Conversation
- Per-core endpoint geometry: endpoint count, DPRAM size, maximum size and bank count per endpoint. CFGOK is only set when the configuration fits. Cores that leave these at zero keep the old at90usb162 limits. - 16 bit byte count (UEBCHX) for the 256 byte endpoints of the xxU4. - VBUS pad: AVR_IOCTL_USB_VBUS drives USBSTA.VBUS and VBUSTI when OTGPADE is set, a part with a VBUS pad only attaches with VBUS present. - USB_GEN and USB_COM are level triggered: enabling an interrupt whose flag is already set fires it. - Start of frame every 1ms after a bus reset, with frame number. - UERST, EPEN, RSTDT, UENUM and read-modify-write of STALLRQ/STALLRQC behave as in the datasheets, UDINT/USBINT bits are clear only. - Host ioctls NAK while detached or on unconfigured endpoints, refuse endpoints the part does not have, truncate oversized packets and report STALL on the endpoint that was accessed.
|
I pulled and built this and everything looks good. But some explanation is needed: what does it actually do and what is the interaction with with previous USB support? I never touched the old stuff apart from making it still build, but my belief is that it depended on a long-obsolete Linux kernel module to do something. My guess is that was rather like the simduino stuff and it would appear to the OS as an actual peripheral that could be seen and used. Looking quickly through your commits, I see nothing like that. Also, what might user-level documentation look like? I have been trying to improve that with Intro.html. Thanks, G. |
|
You are correct about vhci_usb not building on modern kernels. I'm currently working on a replacement built on USB/IP, which is in upstream Linux and will also allow it to work on Windows. As for how I actually tested all this, simavr separates the implementation of the usb peripheral from host integration. Changes to the model. References are to the ATmega16U4/32U4 datasheet (Atmel-7766J, 04/2016), written U4 below, and the ATmega8U2/16U2/32U2 datasheet (7799E, 09/2012), written U2. Endpoint memory: UECFG0X, UECFG1X, UESTA0X.CFGOK
Endpoint registers
Interrupts
Start of frame
VBUS, xxU4 only
Controller and PLL
Host-side IOCTLs
Not modelled
Cores
For docs, I've added a commit with a USB section in Intro.html, after "Other peripherals". It covers which parts have USB, that the program using libsimavr acts as the host, the IOCTLs with a short enumeration example, what isn't simulated, and where vhci stands. I've also documented each IOCTL in |
2b3892c to
0b685fc
Compare
|
Here's an (admittedly completely opus 5.5 generated) USB/IP replacement to vhci_usb: https://github.com/teknoman117/simavr/tree/usbip. To Use: |
|
Thank you for the detailed explanation, but I did not read it all. Reading more than a few lines of LLM prose feels to me like sitting through a corporate presentation. (Apologies in advance if it was not LLM output!) I have done some digging in code and datasheet and turned up a few points, Not part of the PR, but extra_board_usb/simusb.c seems incomplete: there is nothing to connect the simulation and the kernel module. I think the directory can be deleted. "I made a small test harness that does the same, but acts as avrdude. ..." That sounds like something that would be good to have in the examples tree. So would a program showing USB/IP integration. "USB_GEN and USB_COM are level triggered." Plausible, but I do not see it in the datasheet, which just seems vague, and below the usual standard of AVR documentation. If correct, the "sticky" bit should be set in the two Simavr avr_int_vector_t structs, and there should be calls to avr_clear_interrupt() in avr_usb.c. b38a9a8 makes atmegausb162.c and atmega32u2.c almost identical. Confusingly, atmegausb162.c already defines a core called "at90usb162", not "atmegausb162", but Microchip considers these to be three different parts. A search turns up "AVR 530: Migrating from AT90USB162/82 to ATmega16U2/8U2" which suggests the identification is wrong, and lists some relevant differences in peripherals. There are some small changes that I would like so see berfore or during merge: squash c120683 into the previous commit, but also change it to a simple dependency and change the last line of the avr-gcc command in Makefile.common to: I recently met a very similar problem and that seems a general solution. Also, I think it is not necessary to test each memory variant and would remove some firmware files and comment-out (but keep) their table entries. The tests directory is already looking cluttered. On documentation: I think you added too much to Intro.html, but it would be useful as a separate USB guide. It seems USB is very like the other communication peripherals: some emulated register bits and a way for the host program to send and receive. |
|
I'll start working on those changes.
No, you had it right. Apologies. Everything after "Changes to the model" was LLM generated.
The Do you want me to merge my USB/IP tree into this PR as well? I will also bundle the avrdude test harness I made. I was trying to keep the overall PR length somewhat under control. I'm already well over what I'd accept at work 😓. If so, would you like me to just nuke the In general I'm trying to ensure the CI/CD pipeline for ChibiOS's AVR port is able to cover the USB peripheral for supported microcontrollers. I only have hardware examples of the ATmega32u4 in the form of an old Arduino Micro floating around my parts bin. Testing has admittedly only been end-to-end. Basically, does code I know works on the real hardware run correctly on the emulated hardware - test images built on the ChibiOS AVR port, the ATmega32u4 Arduino Bootloader (Catarina), and The ATmega16u2 USB-to-UART adapter flash dump from the Arduino Uno Rev. 3 |
Move the xxU2 and xxU4 cores to sim_megaxu2.h and sim_megaxu4.h templates; within each family the cores simavr builds only differ in memory sizes: - at90usb82, at90usb162, atmega8u2, atmega16u2, atmega32u2: 5 endpoints, 176 bytes of DPRAM. - atmega16u4, atmega32u4: 7 endpoints, 832 bytes of DPRAM, 256 byte EP1, VBUS pad. The ATmega8U2/16U2 add WDTCKD and ACMUX to the AT90USB82/162 they replace (Atmel AVR530); simavr models neither, which the template notes. The at90usb162 now honours PRR0.PRSPI. avr/iousb82.h lacks the signature bytes, sim_usb82.c provides them.
The %.axf rule compiles all its prerequisites, so a firmware could not depend on a header without the header being handed to avr-gcc. Filter headers out, so that they can be listed as dependencies.
A bare metal device firmware probes endpoint configurations, enumerates and echoes bulk data. The host side checks attach/VBUS handling, control transfers, STALL, the CFGOK results and the echo, plus each core's memory sizes and signature. The parts of a family only differ in memory sizes, so firmware is built for the at90usb162, atmega32u2 and atmega32u4 only. The table entries for the other parts are kept, commented out.
doc/USB.html describes which parts are simulated, how the program using libsimavr acts as the host through the AVR_IOCTL_USB_* calls, with a short enumeration fragment, what is not simulated, and the state of the usb-vhci bridge in examples/extra_board_usb. Intro.html gets a short entry pointing to it. avr_usb.h documents each IOCTL's parameter, return values and the bulk IN zero length quirk, which was only discoverable by reading avr_usb.c.
The two vectors have no flag of their own, and the UDINT, USBINT and UEINTX flags are only ever cleared by software. They are the second type in the datasheet's "Reset and Interrupt Handling" section (U4 §4.8, U2 §6.8): they trigger for as long as the condition is present. Instead of raising the vectors again after every register write, they are now declared raise_sticky, raised while an enabled flag is set and cleared with avr_clear_sticky_interrupt() when none is.
0b685fc to
61af412
Compare
|
Also, just for clarification, how would you like me to include the Arduino Micro / Leonardo + avrdude emulation harness and/or the atmega16u2 usb-to-serial harness? As an example? As a test? Both? If any, how would you like me to bundle the firmware file for those? I see simduino has a hex file for the bootloader already. I believe the Caterina bootloader for 32u4 is the MIT license (inherits LUFA's license) and the atmega16u2 usb-to-serial is definitely MIT license. |
|
Your comment about PR size makes sense and any example code would probably not work without #604. It sounds as if you are still working on the application, so it might be a mistake to take an early copy. Assuming it is accessible, maybe just add a link with any documentation. Thanks, G. |
|
@gatk555 Here's the tree for the USB/IP work: https://github.com/teknoman117/simavr/tree/usbip. Removes the VHCI interface, replaces with USB/IP. See:
Example |
Implement support for the usb cores in the ATmegaxxU2 and ATmegaxxU4 MCUs. Also provide automated tests for USB cores.
In combination with #604 I am able to boot the Arduino Micro and Arduino Leonardo's USB bootloader under simavr.
Closes #467.