aboutsummaryrefslogtreecommitdiff
path: root/Makefile
blob: e05f490e0dc588e4881994fcdac255eba1c03ad7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
include config.mk

CC ?= gcc
AVR_CC ?= avr-gcc
AVR_SIZE ?= avr-size
GDB ?= avr-gdb
OBJCOPY ?= avr-objcopy
AVRDUDE ?= avrdude
QEMU ?= qemu-system-avr

REAL_ELF = build/altimeter.elf

# options for native (i.e. unit test)
UNITY_SRC ?= unity/src
UNITY_O = $(UNITY_SRC)/unity.o
CFLAGS += -Wall -Wextra -I$(UNITY_SRC)
LDFLAGS += -lm

# options for cross-compile
MCU ?= atmega32u4
SIM_MCU ?= atmega2560

# Compiler flags for cross-compile
AVR_COMMON_CFLAGS += -Wall -Wextra -DF_CPU=16000000UL
AVR_CFLAGS += $(AVR_COMMON_CFLAGS) -mmcu=$(MCU) -O3
SIM_CFLAGS += $(AVR_COMMON_CFLAGS) -mmcu=$(SIM_MCU) -g3 -gdwarf-2 -DWDT_DISABLE

# Linker flags for cross-compile
AVR_COMMON_LDFLAGS += -Wl,-u,vfprintf -lprintf_flt
AVR_LDFLAGS += $(AVR_COMMON_LDFLAGS) -mmcu=$(MCU)
SIM_LDFLAGS += $(AVR_COMMON_LDFLAGS) -mmcu=$(SIM_MCU)

$(shell mkdir -p build/{real,sim,native})

all: build/altimeter_sim.elf build/altimeter.hex test size

# Run the sim build software in qemu, halted ready for `make gdb` to attach and
# continue. Note that sim build mocks out some hardware components
emu: build/altimeter_sim.elf
	$(QEMU) -s -S -nographic -machine mega2560 -bios $<

# Attach GDB session to qemu instance started with `make emu`
gdb:
	$(GDB) -ex "target remote :1234"
# Flash AVR software to microcontroller with AVRdude
flash: build/altimeter.hex
	$(AVRDUDE) -F -V -c avr109 -p $(MCU) -P $(PORT) -b 115200 -U flash:w:$<

clean:
	rm -rf build/ $(UNITY_O)

test: \
	$(UNITY_O) \
	build/native/test_util.o \
	build/native/util.o
	$(CC) $(LDFLAGS) -o $@ $^
	./$@

# ELF for real hardware. No mock/sim hardware included (except barometer,
# haven't written that code yet)
build/altimeter.elf: \
	build/real/barometer_sim.o \
	build/real/display_sim.o \
	build/real/altimeter.o \
	build/real/util.o
	$(AVR_CC) $(AVR_LDFLAGS) -o $@ $^

size:
	[ -f "$(REAL_ELF)" ] && $(AVR_SIZE) -C --mcu="$(MCU)" "$(REAL_ELF)"

# ELF for simulator/emu. Note that whever I/O is required, the *_sim.{o,c}
# versions of each component will provide a mocked interface. This allows for
# operation in QEMU (see `emu` recipe) without requring SPI, I²C and
# peripherals to be emulated. Useful for UI testing and development etc.
build/altimeter_sim.elf: \
	build/sim/barometer_sim.o \
	build/sim/display_sim.o \
	build/sim/altimeter.o \
	build/sim/util.o
	$(AVR_CC) $(SIM_LDFLAGS) -o $@ $^

build/sim/%.o: %.c
	$(AVR_CC) $(SIM_CFLAGS) -c -o $@ $^

build/real/%.o: %.c
	$(AVR_CC) $(AVR_CFLAGS) -c -o $@ $^

build/native/%.o: %.c
	$(CC) $(CFLAGS) -c -o $@ $^

build/%.hex: build/%.elf
	$(OBJCOPY) -O ihex -R .eeprom $< $@

.PHONY: all emu gdb flash clean test size