Through the steps, you will learn about:
- How USB works
- How I2C works
- How to read data from the Wii Classic Controller
- General electronics
- AVR programming
The entire project is provided as a ZIP file download below. Also see below for a flowchart of how the code will work.
Step 1: Using the AVR with V-USB
"V-USB is a software-only implementation of a low-speed USB device for Atmel’s AVR® microcontrollers, making it possible to build USB hardware with almost any AVR® microcontroller, not requiring any additional chip."
V-USB uses a set of hardware and some very special assembly programming techniques to bit-bang the non-return-to-zero (NRZ) binary code that USB uses to communicate. The files provided by V-USB will be compiled into our program in order to create a USB device with our ATmega328P
Please visit the download section of V-USB's website to obtain a copy of the latest version. In my project source code, it's already included.
To compile V-USB into your project...
- Make sure you've defined the processor and clock speed correctly (V-USB only supports certain clock speeds)
- Copy the folder "usbdrv" from the downloaded package into your project folder
- In your project manager or makefile, include "usbdrv.c" and "usbdrvasm.S", such that the object file that's generated will become linked into your project
- Inside the folder "usbdrv", there is a "usbconfig-prototype.h", copy that file into your main project directory, and rename it to "usbconfig.h"
- Edit "usbconfig.h", this will be explained in detail later
- Use "#include" statements to include "usbconfig.h" and then "usbdrv/usbdrv.h"
- Make sure that "usbdrv/usbdrv.h" is able to find "usbconfig.h", if it's not able to, use the use "-I" to your makefile or edit "usbdrv/usbdrv.h" to change the file path to "usbconfig.h" (to "../usbconfig.h")
- You must initialize V-USB, and then enable interrupts in the AVR
- It's almost a standard practice to fake disconnect, wait a few milliseconds, and reconnect to the computer, during starting the code. This makes sure your device and computer are in a "reset" state to start off.
A request handler function must be implemented, even if you don't perform real actions in it, you must implement it yourself. Look for "usbFunctionSetup" later.
- In our example, we need to use this function to handle two special requests, you'll see it later
- The gamepad is a HID device, a USB HID Report Descriptor must be written and stored in your code