Arduino UNO Big Joystick HID firmware

I've extended the joystick firmware to present a much larger joystick to the host PC. The new firmware has:
  • 8 analog axis supporting values from -32768 to 32767.
  • 40 buttons
This should be handy for building large control systems like the flight controls for a flight simulator, Firefly console, Viper console, or other large control system.

Background

A little background for anyone new to creating USB devices with the Arduino UNO or MEGA2560.

The USB interface on the UNO and MEGA2560 boards is implemented in a small AVR. For R1 and R2 boards that AVR is an Atmega8U2, and for R3 boards it is an Atmega16U2. These chips are programmed with firmware that presents a USB Serial interface to the host PC, and they connect to the Arduino's main Atmega MCU via its TTL Serial port (digital pins 0 and 1).

The 8U2 and 16U2 can be reprogrammed using DFU (Device Firmware Upgrade mode). This means that the USB Serial firmware can be replaced with other USB firmware to turn the Arduino all sorts of USB devices, like a mouse, a keyboard, a joystick, or a MIDI device.

More info on DFU mode:

Big Joystick Firmware


Serial Report Format

Byte Type Description
0,1 int16_t Analog Axis 0 (X) value. -32768 to 32787
2,3 int16_t Analog Axis 1 (Y) value. -32768 to 32787
4,5 int16_t Analog Axis 2 value. -32768 to 32787
6,7 int16_t Analog Axis 3 value. -32768 to 32787
8,9 int16_t Analog Axis 4 value. -32768 to 32787
10,11 int16_t Analog Axis 5 value. -32768 to 32787
12,13 int16_t Analog Axis 6 value. -32768 to 32787
14,15 int16_t Analog Axis 7 value. -32768 to 32787
16 uint8_t Buttons 0-7. Bit 0 = button 0, bit 7 = button 7
17 uint8_t Buttons 8-15. Bit 0 = button 8, bit 7 = button 15
18 uint8_t Buttons 16-23. Bit 0 = button 16, bit 7 = button 23
19 uint8_t Buttons 24-31. Bit 0 = button 24, bit 7 = button 31
20 uint8_t Buttons 32-39. Bit 0 = button 32, bit 7 = button 40

This table describes the format of the 21 byte report that the Arduino sends to the 8U2/16U2. This allows the Arduino to emulate a large joystick, sending axis positions and the value of 40 buttons to the Host PC.

HID Descriptor


This is the HID descriptor for the joystick. You can learn more about them from the USB HID Usage Tables.
 
 
 
0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x04, /* Usage (Joystick) */

0xa1, 0x01, /* Collection (Application) */
0x09, 0x01, /* Usage (Pointer) */

/* 8 axes, signed 16 bit resolution, range -32768 to 32767 (16 bytes) */
0xa1, 0x00, /* Collection (Physical) */
0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x30, /* Usage (X) */
0x09, 0x31, /* Usage (Y) */
0x09, 0x32, /* Usage (Analog1) */
0x09, 0x33, /* Usage (Analog2) */
0x09, 0x34, /* Usage (Analog3) */
0x09, 0x35, /* Usage (Analog4) */
0x09, 0x36, /* Usage (Analog5) */
0x09, 0x37, /* Usage (Analog6) */
0x16, 0x00, 0x80, /* Logical Minimum (-32768) */
0x26, 0xff, 0x7f, /* Logical Maximum (32767) */
0x75, 16, /* Report Size (16) */
0x95, 8, /* Report Count (8) */
0x81, 0x82, /* Input (Data, Variable, Absolute, Volatile) */
0xc0, /* End Collection */

/* 40 buttons, value 0=off, 1=on (5 bytes) */
0x05, 0x09, /* Usage Page (Button) */
0x19, 1, /* Usage Minimum (Button 1) */
0x29, 40, /* Usage Maximum (Button 40) */
0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */
0x75, 1, /* Report Size (1) */
0x95, 40, /* Report Count (40) */
0x81, 0x02, /* Input (Data, Variable, Absolute) */
0xc0 /* End Collection */

Example Sketch


Here's a sketch demonstrating how to send joystick data to the host.

    /* Arduino USB Joystick HID demo */
/* Author: Darran Hunt
* Released into the public domain.
*/
#define NUM_BUTTONS 40
#define NUM_AXES 8 // 8 axes, X, Y, Z, etc
    typedef struct joyReport_t {
int16_t axis[NUM_AXES];
uint8_t button[(NUM_BUTTONS+7)/8]; // 8 buttons per byte
} joyReport_t;
joyReport_t joyReport;
void setup()
{
Serial.begin(115200);
delay(200);
for (uint8_t ind=0; ind<8; ind++) {
joyReport.axis[ind] = ind*1000;
}
for (uint8_t ind=0; ind<sizeof(joyReport.button); ind++) {
joyReport.button[ind] = 0;
}
}
// Send an HID report to the USB interface
void sendJoyReport(struct joyReport_t *report)
{
Serial.write((uint8_t *)report, sizeof(joyReport_t));
}
// turn a button on
void setButton(joyReport_t *joy, uint8_t button)
{
uint8_t index = button/8;
uint8_t bit = button - 8*index;
joy->button[index] |= 1 << bit;
}
// turn a button off
void clearButton(joyReport_t *joy, uint8_t button)
{
uint8_t index = button/8;
uint8_t bit = button - 8*index;
joy->button[index] &= ~(1 << bit);
}
uint8_t button=0; // current button
bool press = true; // turn buttons on?
    /* Turn each button on in sequence 1 - 40, then off 1 - 40
* add values to each axis each loop
*/
void loop()
{
// Turn on a different button each time
if (press) {
setButton(&joyReport, button);
} else {
clearButton(&joyReport, button);
}
/* Move all of the axes */ for (uint8_t ind=0; ind<8; ind++) { joyReport.axis[ind] += 10 * (ind+1); } sendJoyReport(&joyReport); button++; if (button >= 40) { button = 0; press = !press; } delay(100); }

Upload the sketch to the Arduino first, then flash Arduino-big-joystick.hex to the 8U2/16U2. Unplug the Arduino and plug it back in, and will look like a joystick to the host and the host will receive the joystick updates from the sketch.

If you want to upload another sketch, flash Arduino-usbserial.hex to the 8U2/16U2 first, unplug the Arduino and plug it back in. You can now upload the sketch.

Downloads


Demo sketch, joystick firmware, usbserial firmware.

Download file "big_joystick_demo.ino"
Download file "Arduino-big-joystick.hex"
Download file "Arduino-usbserial.hex"

Here's a python test application for checking that your Arduino joystick is behaving correctly. It requires pygame and ocempgui.

Download file "joy.py"

Source code is available on Github. See my earlier blog posts for directions on how to build the firmware.

Loading the firmware


For the Atmega8u2 (UNO R1, R2, MEGA2560 R1, R2):
  • Put the UNO into DFU mode.
  • dfu-prgrammer at90usb82 erase
  • dfu-programmer at90usb82 flash --debug 1 Arduino-big-joystick.hex
  • dfu-programmer at90usb82 reset
  • Unplug the UNO's USB cable for a few seconds and plug it back in
For the ATMEGA16U2 (UNO R3, MEGA2560 R3)
  • Put the UNO into DFU mode.
  • dfu-prgrammer atmega16u2 erase
  • dfu-programmer atmega16u2 flash --debug 1 Arduino-big-joystick.hex
  • dfu-programmer atmega16u2 reset
  • Unplug the UNO's USB cable for a few seconds and plug it back in
Use the same steps to to load Arduino-usbserial.hex when you want to restore the normal functionality to your UNO (e.g. to load a new sketch).

Note: You will need version 0.5.5 of dfu-programmer to program the ATMEGA16U2. Get the latest version here.

80 comments

Building Arduino Atmega8u2 firmware on Linux

I've had a few questions about how to build the HID firmware for the atmega8u2 under linux. Here's a guide for getting the avr tools installed to be able to build the firmware. I've tested this on Ubuntu 10.04.

Build and install binutils for the AVR

Build and install libgmp (needed for gcc-4.5.3)

Install libmpfr and libmpc (needed for gcc-4.5.3)

  • sudo apt-get install libmpfr-dev
  • sudo apt-get install libmpc-dev

Build and install gcc-4.5.3 for AVR

Build and install avr-libc

Do a test build of Arduino-usbserial

The Arduino-usbserial firmware is the default firmware that the UNO comes installed with on its atmega8u2. It implements a serial interface over USB. Build this firmware to check that your avr-gcc toolchain and avr-libc are working.
  • cd Arduino/hardware/arduino/firmwares/arduino-usbserial
  • edit the makefile and make sure that MCU = atmega8u2 and ARDUINO_PID = 0x0001
  • make
  • You should have an newly built Arduino-usbserial.hex file.

13 comments

Arduino UNO Joystick HID firmware

I've built a basic two button analog joystick driver for the UNO that turns the UNO into a USB joystick. This is based on the joystick demo from the LUFA project which defines X and Y analog input ranging from -100 to +100 and two buttons.

I've defined a serial protocol for sending joystick commands with the following format:
Byte Type Description
0 int8_t X value, -100 to 100
1 int8_t Y value, -100 to 100
2 uint8_t Buttons. Bit 0 = button 1, Bit 1 = button 2
3 uint8_t reserved. Set to 0 for now.

Here is the firmware, source, and sample sketch. The firmware works on both the UNO and the Mega2560.

Download file "Arduino-joystick-0.1.hex"
Download file "arduino-joystick-0.1.tar.gz"
Download file "joystick_usb_demo.pde"

Upload the sketch, then load the hex file using DFU mode as described in my earlier posts (dfu-programmer for Linux/OSX or flip for Windows). Unplug the board and plug it back in and your PC should now recognise an Arduino joystick and start receiving input from the sketch.

Note you'll need to reload the USB Serial firmware via DFU mode whenever you want to change your sketch.
Download file "Arduino-usbserial.hex"
Download file "Arduino-usbserial-mega2560.hex"

Here's a summary of how I created the firmware.
  1. I started with a copy of the arduino-mouse source code, and renamed Arduino-mouse.c to Arduino-joystick.c and Arduino-mouse.h to Arduino-joystick.h. I could have started with the USB Serial driver but the mouse HID driver was already close to what was needed for the joystick code.
  2. I copied in Descriptors.c and Descriptors.h from the LUFA joystick demo (Demos/Device/ClassDriver/Joystick available from the LUFA100807 source from the LUFA Project).
  3. I modified Descriptors.c to change the ManufacturerString to "Arduino" and the ProductString to "Arduino Joystick".
  4. I added a USB_JoystickReport_Data_t data structure typedef to Arduino-joystick.h (based on the definition from the LUFA demo's joystick.h header).
  5. I replaced all references to "MouseReport" in Arduino-joystick.c with "JoystickReport".
  6. I changed the CALLBACK_HID_Device_CreateHIDReport so that it checks the amount of serial data received and whenever there is a full report available (i.e. 4 bytes) it copies it into a global joystick report variable. The function always sends the global joystick report to the PC host, so the effect is that it always sends the most recent report to the host. If there is no new report then the last one received is sent again.
  7. I changed the main loop to only call the HID and USB handlers (since the report handling is now taken care of in the CALLBACK_HID_Device_CreateHIDReport function).
  8. I also bumped the serial baud rate from 9600 up to 115200 to let the UNO send joystick updates as quickly as possible.
  9. And finally I added code to turn on the TX led when a report is received from the serial port (i.e. from the UNO) and to turn it off again after a small amount of time. This means the TX led will flash whenever the UNO sends a joystick command.



46 comments

Arduino UNO Keyboard HID version 0.3

I've updated the Keyboard firmware to support key usage codes greater than 101. The maximum code is now 231 so you can send all of the key usage codes defined in HID Usage Tables (e.g. 128 Volume Up and 129 Volume Down).

A big thank you to Feiltom for discovering the problem and the cause - the keyboard report descriptor was limiting the maximum key code to 101.

Download file "Arduino-keyboard-0.3.hex"
Download file "Arduino-keyboard-0.3-mega2560.hex"
Download file "arduino-keyboard-0.3.tar.gz"
Download file "kbd_usb_demo.pde"

86 comments

Arduino UNO MIDI USB version 0.2

I've added MIDI IN support to the USB MIDI driver so now the UNO can send and receive MIDI messages from the host PC. The format of the data is the same as that described in the earlier post for the MIDI firmware.

The example sketch shows how to send and receive MIDI message.

Download file "Arduino-usbmidi-0.2.hex"
Download file "Arduino-usbmidi-0.2-mega2560.hex"
Download file "midi_usb_demo.pde"
Download file "arduino-usbmidi-0.2.tar.gz"

12 comments

Arduino PS2 to USB Keyboard

My April Fools joke hit a roadblock when I discovered that my coworker was using an old PS2 keyboard rather than a USB one. I had to work out a solution for that. A bit of googling turned up this on the Arduino site: PS2Keyboard. So basically I just needed to find a PS2 connector and to wire up an interrupt line and a data line and then the Arduino can read the PS2 key presses. I took the example library from PS2KeyboardExt2 since it was a bit more advanced than the PS2Keyboard library, and I modified it to map the PS2 key scancodes onto USB Keyboard HID Key Usage codes, and added a function to return a USB HID Keyboard Report.

It took a few hours to get the job done, tested with a USB to PS2 adaptor attached to my keyboard. Everything seems to be working except for NUMLOCK key changes but hopefully my coworker won't notice that.

Here's the PS2KeyboardUSB library files and the sketch:
Download file "PS2KeyboardUSB.h"
Download file "PS2KeyboardUSB.cpp"
Download file "kbd_april_fools.pde"

The project could be used to make a nice PS2 to USB keyboard adaptor.

I installed the project on my coworker's docking station Friday morning (April 1st) while he was distracted by an accomplice. We're all waiting to see if he notices it or just slowly goes mad.

9 comments

Arduino USB Keyboard Passthrough

I decided to make use of the Keyboard HID driver in a proof-of-concept project. The project: connect a USB keyboard to the Arduino and have the Arduino transparently pass the key presses to the host PC. Not all that exciting, but its the first step on my actual project which is a bit of April Fools payback for a coworker.

Some brief background; two weeks ago I was happily working on my laptop at work using the USB keyboard attached to the docking station. I pulled up a form and looked at the keyboard to find the first key I wanted to press, a "n", hit it, and in the form a "m" appeared. Hmm. I deleted it and tried again hitting the "n" key - and another "m" appeared! Confused I hit the "m" key and an "n" appeared. Arg!. I compared the keyboard's "n" and "m" keys to the laptop keyboard and discovered the cause - some prankster had switched the physical "n" and "m" keys on my keyboard. I'd been touch-typing all day without noticing the switch, it was only when I looked for the key that I discovered it. It was easy to work out who the culprit was, especially after he pulled the same stunt on a few more coworkers (let's call him Tony).

How does this relate to the Arduino? Basically I thought if I could get the Keyboard HID driver working so the Arduino looked like a keyboard to the host PC, and if I could also connect a USB keyboard to the Arduino, then I could install the Arduino between my coworkers keyboard and his PC while he was at lunch and indulge in some subtle or not so subtle payback. Hopefully on April 1st. For example, I could physically swap the "n" and "m" keys on his keyboard and have the Arduino also swap the "n" and "m" keys as he types them. Then when Tony touch-types his "n" and "m" key presses will be swapped, but when he looks at the keyboard and hits the "n" and "m" the correct key press will be sent to the host PC. Or, I could have the Arduino substitute every 50th key press with a nearby key, e.g. hitting "d" sends a "f" or an "s" instead. You get the idea.

Arduino plus USB Host ShieldI purchased a USB Host shield from Sparkfun. This will provide the interface to the USB keyboard. I downloaded the library from Circuits At Home and wrote a sketch based on the examples they provide. The sketch waits for input from the keyboard and then sends it to the host via the serial port. I loaded the sketch, flashed the Keyboard HID firmware to the atmega8u2, unplugged the USB cable, plugged a USB keyboard into the USB Host Shield, and plugged the UNO back in to my PC. It works! Its as if the Arduino is not even there, the keyboard works perfectly normally, no lag, key repeats work, numlock, capslock, scroll lock, all working really well.

I did have to cheat a little and handle the keyboard LED status in the sketch rather than taking the status from the host PC. I still need to debug that feature in the Keyboard HID driver.

Here's the keyboard pass-through sketch:
Download file "kbd_usb_passthrough.pde"

You'll need to use DFU mode to flash Arduino-keyboard-0.2.hex to the UNO's atmega8u2. See my earlier posts for the hex file and steps to follow to flash it to your board.

30 comments

Arduino UNO USB MIDI firmware

I've put together a basic USB MIDI driver for the UNO's atmega8u2. I've tested it using the demo sketch below with GarageBand and it seems to be working well. By flashing this firmware onto your UNO's atmega8u2 you can turn the UNO into a USB MIDI device. See my earlier posts on how to load the firmware via DFU mode.

The MIDI driver expects to receive a serial message with the following format:
Byte Description
0 Command: E.g. 0x90 Note On, 0x80 Note Off.
1 Channel: 1 to 16
2 MIDI data byte 2. Depends on Command, for 0x80 and 0x90 this is the Pitch values 1-127
3 MIDI data byte 3. Depends on Command, for 0x80 and 0x90 this is the Velocity values 1-127

The serial port should be configured for 115200 baud.

Here's the firmware files, source, and example sketch to send 5 notes to the host.

Download file "Arduino-usbmidi-0.1.hex"
Download file "Arduino-usbmidi-0.1-mega2560.hex"
Download file "arduino-usbmidi-0.1.tar.gz"
Download file "midi_usb_demo.pde"

More detail on the MIDI messages can be found here at www.midi.org.

More detail on the MIDI USB interface standard can be found in the MIDI 1.0 Specification.

You can download a copy the USB Serial firmware here: Arduino USB Serial firmware. You'll need to replace the MIDI firmware with this whenever you want to upload a new sketch. Flash this by putting the board in to DFU mode and using dfu-programmer or flip.


18 comments

Arduino UNO Mouse HID

I've created a Mouse HID driver for the UNO's atmega8u2. It makes the Arduino appear to be a USB mouse device, and lets it move the mouse and send button presses on a host PC.

The driver implements a serial protocol that expects to receive 4 bytes from the UNO's main processor. The format is a follows:
Byte Description
0 Button states: 0 off, 1 on
Bit 0 - Mouse Button 1
Bit 1 - Mouse Button 2
Bit 2 - Mouse Button 3
1 X movement: int8_t range -127 to +128
2 Y movement: int8_t range -127 to +128
3 Wheel movement: Not implemented, will be added soon.

Here's the firmware, source, and an example sketch that moves the mouse in a clockwise square every 5 seconds. See the earlier posts about how to load the firmware using DFU mode, and how to build the firmware.


Download file "Arduino-mouse-0.1.hex"
Download file "Arduino-mouse-0.1-mega2560.hex"
Download file "arduino-mouse-0.1.tar.gz"
Download file "mouse_usb_demo.pde"



37 comments

Arduino UNO Keyboard HID version 0.2

I've updated the keyboard driver so it no longer needs delays in the sketch when sending keys. Here's the updated firmware, source, and an example sketch to send "hello world" via the keyboard.

Download file "Arduino-keyboard-0.2.hex"
Download file "arduino-keyboard-0.2.tgz"
Download file "kbd_usb_demo.pde"

And firmware built for the Arduino Mega2560 but not tested (I don't have a board to test on, but it should work). If you do try it out let me know how it goes.

Download file "Arduino-keyboard-mega2560.hex"

10 comments

Arduino UNO Keyboard HID part 2

Part 1 covered getting the avr tools setup and building the Arduino usbserial firmware. Part 2 covers flashing the firmware to the UNO's atmega8u2 and putting together firmware for a Keyboard HID driver.

Updating the UNO's atmega8u2 USB firmware

To do this the atmega8u2 needs to be put into DFU mode. There is a description of how to do this without soldering on the Arduino forums here: msg374201. Note that you can't brick your UNO doing this, it will always support DFU mode so you can recover by flashing it with a working Arduino-usbserial.hex file.
  • Put the UNO into DFU mode.
  • dfu-prgrammer at90usb82 erase
  • dfu-programmer at90usb82 flash --debug 1 Arduino-usbserial.hex
  • dfu-programmer at90usb82 reset
  • Unplug the UNO's USB cable for a few seconds and plug it back in
  • Check that you can still upload a sketch. If you can't upload the sketch (e.g. the usb device hasn't shown up), then put the UNO back into DFU mode and repeat the above procedure using the prebuilt Arduino-usbserial-uno.hex file that is in the Arduino-usbserial directory.
Note you can also flash the firmware by running "make dfu" in the arduino-usbserial directory after you put the UNO into DFU mode.

Creating Keyboard HID firmware

This has been made extremely easy by the excellent work done by Dean Camera with his AVR USB stack LUFA and the excellent demo's he provides which are full drivers for a large collection of USB devices. And, of course, the efforts of the Arduino team and contributors that have made it such an easy platform to develop on.

I put together the Keyboard HID firmware by starting with the Arduino-usbserial source code, adding in the LUFA keyboard HID demo code, and implementing a simple serial protocol to allow communication with the keyboard firmware from the UNO's main processor.

The source code is in the following locations:
  • Arduino/hardware/arduino/firmwares/arduino-usbserial
  • LUFA 100807/Demos/Device/ClassDriver/Keyboard
I've defined a very simple serial protocol between the keyboard firmware and the UNO's main processor. The keyboard firmware expects to receive 8 bytes formatted as a Keyboard HID report. The format is as follows:

Byte Contents
0 Modifier keys:
Bit 0 - Left CTRL
Bit 1 - Left SHIFT
Bit 2 - Left ALT
Bit 3 - Left GUI
Bit 4 - Right CTRL
Bit 5 - Right SHIFT
Bit 6 - Right ALT
Bit 7 - Right GUI
1 Not used
2 - 7 HID active key usage codes. This represents up to 6 keys currently being pressed.

The Key Usage codes are documented in chapter 10 of the HID Usage Tables. The letters 'a' to 'z' are codes 4 to 29, and you can indicate upper case by setting the left SHIFT or right SHIFT bit in byte 0 of the report.

The keyboard firmware sends back 1 byte every time it receives 8 bytes. This byte represents the LED status for the keyboard: Bit 0 - NUMLOCK, Bit 1 - CAPSLOCK, Bit 2 SCROLL LOCK. Note this isn't currently working and I haven't worked out why yet. I'll update the page when its fixed.

Example code to send an 'a':

uint8_t keyNone[8] = { 0, 0, 0, 0, 0, 0, 0 };
uint8_t keyA[8] = { 0, 0, 4, 0, 0, 0, 0 };

void setup()
{
Serial.begin(9600);
delay(2000);
}

void loop()
{
uint8_t ledStatus;

/* Send an 'a' every second */
Serial.write(keyA, 8);
ledStatus = Serial.read();
delay(100); // Give the host time to read the key
Serial.write(keyNone, 8);
delay(1000);
}
There is plenty of room for improvement in the keyboard firmware. I'll work on a version that doesn't need the delay(100) to give the host time to read the key. There is some difficulty because of the size of the firmware - its 4040 bytes which is almost at the 4096 byte limit which makes it challenging to add features.

You can download the Keyboard HID firmware source here: arduino-keyboard.tar.gz and the firmware here: Arduino-keyboard.hex

Download file "arduino-keyboard.tar.gz"
Download file "Arduino-keyboard.hex"

21 comments

Arduino UNO Keyboard HID Part 1

I received my Arduino UNO from Sparkfun on Thursday, and I've been blown away by how easy it is to use. I've created Keyboard HID firmware for the UNO's atmega8u2 so I thought I'd document how to do that here. The same approach should work for other device types, e.g. mouse, joystick, etc.

The first step was getting everything needed to build the standard Arduino USB Serial firmware. I'm running on OSX, so the initial setup is specific to that OS.

Set up an AVR build environment

  • Install avr-binutils. I've got macports installed so this is as simple as running the command "sudo port install avr-binutils". You can install macports from The MacPorts Project.
  • Build and install avr-gcc. For this I downloaded gcc-4.5.2 from gcc.gnu.org. To build gcc you'll need to have XCode installed (from developer.apple.com). Do the following to build avr-gcc:
    • sudo port install gmp
    • sudo port install mpfr
    • sudo port install libmpc
    • export PATH=/opt/local/bin:/opt/local/sbin:$PATH
    • tar xjf gcc-4.5.2.tar.bz2
    • cd gcc-4.5.2
    • mkdir build
    • cd build
    • CFLAGS="-g -O2 -I/opt/local/include" LDFLAGS="-L/opt/local/lib" ../configure --prefix=/opt/local --target=avr --with-gcc --with-gnu-as --enable-languages=c,c++ --disable-nls --disable-libssp --with-dwarf2
    • make
    • sudo make install
    • cd ../..
  • Build and install avr-libc.
    • Download the latest avr-libc source from the AVR-Libc Project, e.g. avr-libc-1.7.1.tar.bz2
    • tar xjf avr-libc-1.7.1.tar.bz2
    • cd avr-libc-1.7.1
    • mkdir build
    • cd build
    • CFLAGS=-Os ../configure --prefix=/opt/local --build=`../config.guess` --host=avr
    • make
    • sudo make install
    • cd ../..

Get the Arduino and LUFA source

The Arduino source has the firmware source code for the UNO's atmega8u2 processor. Its based on the LUFA USB library project which provides source code for AVR USB drivers.
  • If you don't have git installed, use macports to install it now: "sudo port install git".
  • Get a copy of the Arduino source code:
    • git clone git://github.com/arduino/Arduino.git
  • Download a copy of LUFA 100807, unzip it and copy the LUFA subdirectory to the Arduino source tree:

Build and install dfu-programmer

The atmega8u2 is provided with DFU boot code that lets you load new firmware to it via USB. The dfu-programmer application lets you update the firmware in the atmega8u2 when its put into DFU mode.
  • Install libusb-compat: sudo port install libusb-compat
  • Download the latest dfu-programmer package from Sourceforge (e.g. 0.5.4) and do the following:
    • tar xzf dfu-programmer-0.5.4.tar.gz
    • cd dfu-programmer-0.5.4
    • ./configure
    • make
    • sudo make install
    • cd ..

Do a test build of Arduino-usbserial

The Arduino-usbserial firmware is the default firmware that the UNO comes installed with on its atmega8u2. It implements a serial interface over USB. Build this firmware to check that your avr-gcc toolchain and avr-libc are working.
  • cd Arduino/hardware/arduino/firmwares/arduino-usbserial
  • edit the makefile and make sure that MCU = atmega8u2 and ARDUINO_PID = 0x0001
  • make
  • You should have an newly built Arduino-usbserial.hex file.
Next time: Flashing Arduino-usbserial.hex to your UNO, and how to make your own Keyboard HID USB firmware.


24 comments