jamie.lentin.co.uk

Minimus AVR USB and Minimus 32 AVR USB

They are small breakout boards for Atmel AT90USB162 and ATmega32U2 chips, similar to the ever popular Arduinos. The board itself contains the chip & crystal, a few LEDs and buttons and a USB plug. Atmel have nicely put a bootloader on the chip so we can use it without an external programmer.

The difference between the 2 models is the SoC. The rest of the board layout is the same.

Hardware

The board comes with most pins on the chip broken out along either side, at a standard 0.1" pitch. I'd recommend soldering pin headers onto the board pointing downwards, so you can insert it into breadboards and sockets in stripboard.

The labelling on the boards can be hard to read, and there is no labelling as to how the LEDs and switch are wired. To the chip the board looks like this:

    VCC PC4 PC5 RST PC6 PC7 PB7 PB6 PB5 PB4 PB3 PB2

U                                              PWR
S P
B O                          RST - RST     A - PD6
  R
  T                          HWB - PD7     B - PD5

    PC2 PD0 PD1 PD2 PD3 PD4 PD5 PD6 PD7 PB0 PB1 GND

i.e. PD5 & PD6 are also the on board LEDS, PD7 is the HWB button.

Programming under Linux

Setup

To program under linux requires 2 things, avr-gcc and dfu-programmer:

aptitude install avr-gcc avr-libc dfu-programmer

NB: dfu-programmer should be at least version 0.5.2 to support the atmega32u2, this needs at least 0.5.4-1 if you are using the Debian package, at the time of writing only in testing/unstable.

USB is basically done in software, so if you want to emulate something USB-ish you will need a library, e.g. LUFA.

Introduction to coding for the AVR

In the diagram above you'll see each pin referred to as something like PD7. This means bit 7 of port D. Each port is controlled by a set of 8-bit global variables, each bit within referencing a different pin.

DDRx
1 - output mode, 0 - input mode
PORTx
If output, 1 - connected to VCC, 0 - connected to ground. If input, enables pull-up resistor
PINx
If input, shows whether pin is currently high or low.

That was very brief. This longer guide may prove useful. What on earth is a pull-up resistor? Look through this.

Here is a small example program that uses both LEDs and the button. Press the button and the red LED turns on, let go and the blue LED comes back on:

#include <avr/io.h>

int main(void) {
  DDRD = 0b01100000; /* LED Ports are in output mode */
  PORTD = 0b10000000; /* Enable pull-up on PD7 */
  while(1) {
    if(PIND & (1<<PD7)) {
        PORTD |= 1<<PD6; /* Red off */
        PORTD &= ~(1<<PD5); /* Blue on */
    } else {
        PORTD |= 1<<PD5; /* Blue off */
        PORTD &= ~(1<<PD6); /* Red on */
    }
  }
  return 0;
}

Compiling & uploading code

Firstly the board needs to be ready to accept new code. To do this, hold down HWB, press and let go of RESET, let go of HWB. Try running lsusb, you should see one of the following:

Bus 002 Device 006: ID 03eb:2ffa Atmel Corp. # Minimus
Bus 001 Device 041: ID 03eb:2ff0 Atmel Corp. # Minimus 32

To write to this, your user needs access to /dev/bus/usb/001/041 (or the relevant path to where your Minimus is attached to the USB bus). The easiest thing to do is add a udev rule like this, to allow any user in "plugdev" access:

# cat /etc/udev/rules.d/minimus.rules
SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="03eb", ATTR{idProduct}=="*", GROUP="plugdev"

We are ready to program. I have created a very simple program and uploaded it to github. To use this:

$ git clone git://github.com/lentinj/port_test.git
$ cd port_test
$ make hex # Make a hex file
$ make upload # Upload it to a minimus waiting for new code