Playing with AVR devices
Apr. 27th, 2014 11:20 amI wanted to play a little with Arduino type devices. Why? Why not :-) Something to play with...
I got a MattairTech MT-DB-U4. What I didn't realise, at the time, was that different boards have slightly different libraries and code bases. MattairTech had provided routines so the standard Arduino development environment works. And, indeed, I was able to create simple sketches and upload them to the device and it worked.
But I don't like GUI based IDEs. I want my command line :-)
So I set about trying to work out what was needed. I did an strace of the (java) app and looked at the exec calls. Fortunately I turned out to be pretty self-contained. In particular it rebuilds the libraries each time. Which appears to be enough.
As proof of concept I tried to compile the code from http://www.pjrc.com/teensy/benchmark_usb_serial_receive.html
I was able to convert this into a Makefile. And it worked first time!
# Makefile for MattairTech MT-DB-U4 using the Arduino CLI tools and
# the MattairTech provided files MattairTech_Arduino_1.0.5.1.zip from
# http://www.mattairtech.com/index.php/development-boards/atmega32u4-usb-development-board-arduino-compatible.html
# http://arduino.cc/en/Main/Software
AVRTOOLS=$(HOME)/bin/arduino-1.0.5/hardware/tools/avr/bin
MTBASE=$(HOME)/sketchbook/hardware/MattairTech/cores
# This is 16Mhz and so should be run at 5V
# Should only need changing if you want a different speed
CFLAGS=-c -g -Os -w -ffunction-sections -fdata-sections -mmcu=atmega32u4 -DF_CPU=16000000L -DUSB_VID=0x16D0 -DUSB_PID=0x0856 -DARDUINO=105 -I$(MTBASE)/MattairTech -I$(MTBASE)/../variants/mtdbu4
CPPFLAGS=-fno-exceptions $(CFLAGS)
# This structure works for a single source file. More complicated
# builds may need a bit more work
MAINFILE=Benchmark_USB_Receive_Standard
SOURCE=$(MAINFILE).cpp
OBJECTS=$(MAINFILE).o
TARGET=$(MAINFILE).hex
$(TARGET): $(OBJECTS) lib/core.a
@$(AVRTOOLS)/avr-gcc -Os -Wl,--gc-sections -mmcu=atmega32u4 -o $(MAINFILE).elf $(OBJECTS) lib/core.a -L. -lm
@$(AVRTOOLS)/avr-objcopy -O ihex -R .eeprom $(MAINFILE).elf $(TARGET)
@$(AVRTOOLS)/avr-size $(TARGET)
$(OBJECTS): $(SOURCE)
@$(AVRTOOLS)/avr-g++ $(CPPFLAGS) $< -o $@
### This should now be constant and not need changing
LIBSRC=$(MTBASE)/MattairTech
LIBCSRC=wiring_digital.c \
LUFA/HIDParser.c \
LUFA/HostStandardReq.c \
LUFA/Events.c \
LUFA/ConfigDescriptors.c \
LUFA/USBInterrupt_AVR8.c \
LUFA/Device_AVR8.c \
LUFA/Descriptors.c \
LUFA/Template/Template_Endpoint_Control_R.c \
LUFA/Template/Template_Endpoint_Control_W.c \
LUFA/Template/Template_Pipe_RW.c \
LUFA/Template/Template_Endpoint_RW.c \
LUFA/EndpointStream_AVR8.c \
LUFA/USBController_AVR8.c \
LUFA/usb_cdc_hid.c \
LUFA/USBTask.c \
LUFA/DeviceStandardReq.c \
LUFA/HIDClassDevice.c \
LUFA/Endpoint_AVR8.c \
wiring.c \
avr-libc/realloc.c \
avr-libc/malloc.c \
wiring_pulse.c \
wiring_shift.c \
wiring_analog.c \
WInterrupts.c
LIBCPPSRC=new.cpp \
Print.cpp \
usb_api.cpp \
WString.cpp \
WMath.cpp \
main.cpp \
Stream.cpp \
Tone.cpp \
IPAddress.cpp \
HardwareSerial.cpp
# We recompile this each time just in case frequencies or whatever change
.PHONY: lib/core.a
lib/core.a:
@mkdir lib 2>/dev/null || /bin/true
@/bin/rm -f lib/* || /bin/true
@for a in $(LIBCSRC); do echo Compiling $$a ; $(AVRTOOLS)/avr-gcc $(CFLAGS) $(MTBASE)/MattairTech/$$a -o lib/`basename $$a .c`.o; done
@for a in $(LIBCPPSRC); do echo Compiling $$a ; $(AVRTOOLS)/avr-g++ $(CPPFLAGS) $(MTBASE)/MattairTech/$$a -o lib/`basename $$a .cpp`.o; done
@$(AVRTOOLS)/avr-ar rcs lib/core.a lib/*.o
clean:
rm -rf *.o *.elf lib
I got a MattairTech MT-DB-U4. What I didn't realise, at the time, was that different boards have slightly different libraries and code bases. MattairTech had provided routines so the standard Arduino development environment works. And, indeed, I was able to create simple sketches and upload them to the device and it worked.
But I don't like GUI based IDEs. I want my command line :-)
So I set about trying to work out what was needed. I did an strace of the (java) app and looked at the exec calls. Fortunately I turned out to be pretty self-contained. In particular it rebuilds the libraries each time. Which appears to be enough.
As proof of concept I tried to compile the code from http://www.pjrc.com/teensy/benchmark_usb_serial_receive.html
I was able to convert this into a Makefile. And it worked first time!
# Makefile for MattairTech MT-DB-U4 using the Arduino CLI tools and
# the MattairTech provided files MattairTech_Arduino_1.0.5.1.zip from
# http://www.mattairtech.com/index.php/development-boards/atmega32u4-usb-development-board-arduino-compatible.html
# http://arduino.cc/en/Main/Software
AVRTOOLS=$(HOME)/bin/arduino-1.0.5/hardware/tools/avr/bin
MTBASE=$(HOME)/sketchbook/hardware/MattairTech/cores
# This is 16Mhz and so should be run at 5V
# Should only need changing if you want a different speed
CFLAGS=-c -g -Os -w -ffunction-sections -fdata-sections -mmcu=atmega32u4 -DF_CPU=16000000L -DUSB_VID=0x16D0 -DUSB_PID=0x0856 -DARDUINO=105 -I$(MTBASE)/MattairTech -I$(MTBASE)/../variants/mtdbu4
CPPFLAGS=-fno-exceptions $(CFLAGS)
# This structure works for a single source file. More complicated
# builds may need a bit more work
MAINFILE=Benchmark_USB_Receive_Standard
SOURCE=$(MAINFILE).cpp
OBJECTS=$(MAINFILE).o
TARGET=$(MAINFILE).hex
$(TARGET): $(OBJECTS) lib/core.a
@$(AVRTOOLS)/avr-gcc -Os -Wl,--gc-sections -mmcu=atmega32u4 -o $(MAINFILE).elf $(OBJECTS) lib/core.a -L. -lm
@$(AVRTOOLS)/avr-objcopy -O ihex -R .eeprom $(MAINFILE).elf $(TARGET)
@$(AVRTOOLS)/avr-size $(TARGET)
$(OBJECTS): $(SOURCE)
@$(AVRTOOLS)/avr-g++ $(CPPFLAGS) $< -o $@
### This should now be constant and not need changing
LIBSRC=$(MTBASE)/MattairTech
LIBCSRC=wiring_digital.c \
LUFA/HIDParser.c \
LUFA/HostStandardReq.c \
LUFA/Events.c \
LUFA/ConfigDescriptors.c \
LUFA/USBInterrupt_AVR8.c \
LUFA/Device_AVR8.c \
LUFA/Descriptors.c \
LUFA/Template/Template_Endpoint_Control_R.c \
LUFA/Template/Template_Endpoint_Control_W.c \
LUFA/Template/Template_Pipe_RW.c \
LUFA/Template/Template_Endpoint_RW.c \
LUFA/EndpointStream_AVR8.c \
LUFA/USBController_AVR8.c \
LUFA/usb_cdc_hid.c \
LUFA/USBTask.c \
LUFA/DeviceStandardReq.c \
LUFA/HIDClassDevice.c \
LUFA/Endpoint_AVR8.c \
wiring.c \
avr-libc/realloc.c \
avr-libc/malloc.c \
wiring_pulse.c \
wiring_shift.c \
wiring_analog.c \
WInterrupts.c
LIBCPPSRC=new.cpp \
Print.cpp \
usb_api.cpp \
WString.cpp \
WMath.cpp \
main.cpp \
Stream.cpp \
Tone.cpp \
IPAddress.cpp \
HardwareSerial.cpp
# We recompile this each time just in case frequencies or whatever change
.PHONY: lib/core.a
lib/core.a:
@mkdir lib 2>/dev/null || /bin/true
@/bin/rm -f lib/* || /bin/true
@for a in $(LIBCSRC); do echo Compiling $$a ; $(AVRTOOLS)/avr-gcc $(CFLAGS) $(MTBASE)/MattairTech/$$a -o lib/`basename $$a .c`.o; done
@for a in $(LIBCPPSRC); do echo Compiling $$a ; $(AVRTOOLS)/avr-g++ $(CPPFLAGS) $(MTBASE)/MattairTech/$$a -o lib/`basename $$a .cpp`.o; done
@$(AVRTOOLS)/avr-ar rcs lib/core.a lib/*.o
clean:
rm -rf *.o *.elf lib