Friday 19 February 2016

OpenBSD, ATmega328 and Pololu USB AVR Programmer

This is what I have been poking around with lately: programming an atmega MCU without IDE, and minimum Arduino dependencies.  That's just the way I like it.  



Bought some parts from www.RobotShop.ca:

--Pololu USB AVR Programmer.
http://www.robotshop.com/ca/en/pololu-usb-avr-programmer.html
So far, happy with this little device.  I just wish I could figure out a way to program the MCU without a crystal. 

--ATmega328.
http://www.robotshop.com/ca/en/atmega328-arduino-uno-optiboot-bootloader.html.

I clearly prefer to do my stuff without IDE.  And doing this with OpenBSD is quite satisfactory.  There is actually a port of Arduino (http://openports.se/devel/arduino) which I also use and which is also without IDE, but I wanted to go a little further.  It's a nice learning experience.

So here is the Makefile, a file I borrowed here http://canthack.org/2010/12/programming-the-arduino-in-pure-c/#comment-57224/index.html (Programming Arduino in pure C).  Modified for my needs and adapted to recent version of OpenBSD. i.e. SUDO=doas...

AVRDUDE=avrdude -B3 #-V
OBJCOPY=avr-objcopy
CC=avr-gcc
RM=rm -f

MCU=atmega328p
F_CPU=16000000UL
BIN_FORMAT=ihex
PORT=/dev/cuaU0
BAUD=115200
PROTOCOL=avrispv2
CFLAGS=-Wall -Os -DF_CPU=$(F_CPU) -mmcu=$(MCU)
PROG=${.CURDIR:C/.*\///g}
SUDO=doas

.SUFFIXES: .elf .hex

.c.elf:
    $(CC) $(CFLAGS) -o $@ $<

.elf.hex:
    $(OBJCOPY) -O $(BIN_FORMAT) -R .eeprom $< $@

.PHONY: all
all: ${PROG}.hex

${PROG}.hex: ${PROG}.elf

${PROG}.elf: ${PROG}.c

.PHONY: clean
clean:
    $(RM) ${PROG}.elf ${PROG}.hex

.PHONY: upload
upload: ${PROG}.hex
    ${SUDO} $(AVRDUDE) -c $(PROTOCOL) -p $(MCU) -P $(PORT) \
        -b $(BAUD) -U flash:w:${PROG}.hex


A cool little C program to test things out:

#include <avr/io.h>              
#include <util/delay.h>          

const int sle=100;
int main(void) {
    DDRB |= 0b00111100;
    int i = 0;
    while(1){
        for(i = 5; i > 1; --i){
            PORTB = (1 << i);
            _delay_ms(sle);   
        }
        for(i = 2; i < 6; ++i){
            PORTB = (1 << i);
            _delay_ms(sle);   
        }
    }
}


The mandatory make && make upload output with limited verbosity...

 marst@milkway.my.domain:21:48:16
/home/marst/documents/programming/c/avr/blinkLED:
$>make && make upload
avr-gcc -Wall -Os -DF_CPU=16000000UL -mmcu=atmega328p -o blinkLED.elf
avr-objcopy -O ihex -R .eeprom blinkLED.elf blinkLED.hex
doas avrdude -B3  -c avrispv2  -p atmega328p -P /dev/cuaU0  -b 115200

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.

avrdude: Device signature = 0x1e950f
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "blinkLED.hex"
avrdude: input file blinkLED.hex auto detected as Intel Hex
avrdude: writing flash (310 bytes):

Writing | ################################################## | 100% 0.

avrdude: 310 bytes of flash written
avrdude: verifying flash memory against blinkLED.hex:
avrdude: load data flash data from input file blinkLED.hex:
avrdude: input file blinkLED.hex auto detected as Intel Hex
avrdude: input file blinkLED.hex contains 310 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.

avrdude: verifying ...
avrdude: 310 bytes of flash verified

avrdude: safemode: Fuses OK

avrdude done.  Thank you.