Arduino USB Serial firmware from scratch

I have need to change the USB descriptors of an Arduino Uno R3 acting as a peripheral to another device. This post describes how I built a USB Serial firmware for the ATmega16U2 on an Arduino Uno R3, using Atmel Studio 7 and its LUFA Library extension. It can be flashed using the built-in DFU firmware and Atmel’s FLIP tool.

Source files that perform the actual USB/serial proxying are derived from USB to Serial Converter example project for the at90usb1287 (File -> New -> Example Project…). I suggest creating a project based on that example and copying the files over. I have also borrowed code from the official source code at GitHub to enable additional functionality such as allowing a sketch to be uploaded from the Arduino IDE.


Install LUFA Library extension if not already installed (Tools -> Extensions and Updates…).


Create a new project for the ATmega16U2 (File -> New -> Project…).



Use ASF Wizard (ASF -> ASF Wizard) to add LUFA modules and remove the Generic board support (driver) module.


Configure GCC symbols (Project -> Properties). Change BOARD to BOARD_UNO, and add F_CPU=16000000UL, and F_USB=16000000UL.


Copy over source files from the example project mentioned earlier. Resolve any build errors.

Flash (Tools -> Device Programming) the firmware using the FLIP tool.


Reboot the Arduino.


Arduino USB DFU firmware from scratch

The Device Firmware Upgrade (DFU) firmware for the ATmega16U2 on Arduino UNO R3 is used to flash the USB Serial firmware, among others, using Atmel’s FLIP tool.

This post documents how you can build from scratch DFU firmware using Atmel Studio 7 and its LUFA Library extension. You’ll need an ISP/ICSP programmer to program the ATmega16U2.

You can install the LUFA extension from the Extensions and Updates dialog (Tools -> Extensions and Updates).


Create a new project based on the DFU Bootloader example (File -> New -> Example Project…).


Change the compiler optimization setting to -Os in toolchain properties (Project -> Properties).


Build the solution and flash (Tools -> Device Programming) using an ISP/ICSP programmer connected to the ICSP2 header.



Unbricking a JTAGICE3

Atmel Studio 7 prompted me to upgrade a JTAGICE3 tool recently. I went ahead with the upgrade since I couldn’t use the tool without it, and I have done it with the JTAGICE mkII on several occasions. After the upgrade was successfully completed, I found the JTAGICE3 in a state that is generally referred as bricked.

I left it aside for a couple of weeks until I decided to visit AVRFREAKS, and found a solution.

You’ll need to put JTAGICE3 in bootloader mode. Short the pads highlighted in the image below, and plug it in.


Then, from Windows command line run

C:\Program Files (x86)\Atmel\Studio\7.0\atbackend>atfw -t jtagice3 -a "C:\Program Files (x86)\Atmel\Studio\7.0\tools\JTAGICE3\"

USB Descriptors of Arduino UNO

I’ve been studying the USB interface of Arduino UNO so that I can interface it to an embedded host. It appears as a serial port on Linux, OS X, and Windows 10, without need for custom drivers. The Arduino IDE can reprogram the device over the serial port. Makers also use it to output debug information.



Here’s the detailed device descriptor as seen on Linux with lsusb -v

Bus 001 Device 005: ID 2341:0043 Arduino SA Uno R3 (CDC ACM)
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            2 Communications
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0         8
  idVendor           0x2341 Arduino SA
  idProduct          0x0043 Uno R3 (CDC ACM)
  bcdDevice            0.01
  iManufacturer           1
  iProduct                2
  iSerial               220
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           62
    bNumInterfaces          2
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0xc0
      Self Powered
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         2 Communications
      bInterfaceSubClass      2 Abstract (modem)
      bInterfaceProtocol      1 AT-commands (v.25ter)
      iInterface              0
      CDC Header:
        bcdCDC               10.01
      CDC ACM:
        bmCapabilities       0x06
          sends break
          line coding and serial state
      CDC Union:
        bMasterInterface        0
        bSlaveInterface         1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval             255
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass        10 CDC Data
      bInterfaceSubClass      0 Unused
      bInterfaceProtocol      0
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x04  EP 4 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1

Interface descriptor with class Data Interface Class (bInterfaceClass=0x0A) is used for serial communications. Endpoint with bEndpointAddress 0x03 is used for input, and bEndpointAddress 0x04 for output.

Arduino Uno bootloader programming using JTAGICE mkII

Arduino Uno comes with an ATmega328 microcontroller. Like all AVR MCUs it can be programmed using an in-system programming interface (ISP or ICSP). This can be useful to upgrade the bootloader, or to completely replace it and use the full program space on the MCU.

I have a JTAGICE mkII at work that I use to program AVR32 MCUs. It supports  programming the Arduino Uno using the wiring shown below.

Screen Shot 2016-10-28 at 09.25.38.png

The ATmega16U2 that drives the USB to serial interface – within orange rectangle in the figure above – can also be reprogrammed using the ICSP2 header.

The Arduino can also be programmed using the more affordable JTAGICE3.

PCB Design Software

Altium Designer is the design software that I’ve been using on a regular basis because we’ve got a license at work. It doesn’t come with too many components but more can be downloaded online. Creating new components is pretty easy too. Components can contain embedded 3D models, which makes it easy to review pad alignment and such. The final PCB can be viewed in 3D too making it really easy to review mechanical constraints.


These are some useful keyboard shortcuts that come in handy in the PCB design view.

1, 2 or 3 – switch between board planning, 2D layout, and 3D views.
a – alignment pop-up.
ctrl+m – measure distance between two points.
ctrl-z – undo.
escape – exit current tool.
g – change grid resolution.
j – jump to a location.
l – view layer configuration.
p – place.
q – switch between imperial (mils) and international (mm) units.
shift-s – toggle (show/hide) information on other layers.
u – un-route net, connection, component, or room.

Altium provides powerful design rules creation and checking capabilities that come in handy to ensure manufacturability and assembly.

Circuit Maker from the makers of Altium is a community driven design software. Designs are stored online and available to all. It feels very much like Altium.

Eagle is the quintessential PCB design tool used by professionals and hobbyists. Small PCB designs can be done for free. It is useful to have to study open source designs such as the one for Arduino Uno. There’s a lot of information available about and for Eagle such as a wonderful series of tutorials from SparkFun.

Fritzing has become very popular among makers to represent breadboard views of circuits. It also comes with quite powerful PCB editing and verification capabilities. Designs can be exported for manufacturing.

gerbv is very useful to review Gerber format manufacturing files. I always review mine in gerbv before sending them off to the manufacturer.

Land Pattern Calculator page can be used to download PCB Library Expert for IPC. It makes calculating land patterns easy. Input the requested dimensions and tolerances, and it outputs the land pattern dimensions for different types of surface mount components.

123 Design is not a PCB design software, but I find it pretty handy to view and tweak 3D models of components.