# Ghost Hand firmware : ATtiny1616 @ 5 MHz (OSC20M / 4), avr-gcc + avr-libc
#
#   make              build build/ghost-hand.elf/.hex and print the size
#   make test         host-side learner tests (plain gcc)
#   make flash        program over UPDI with pymcuprog (serial UPDI adapter)
#   make flash-avrdude  same with avrdude -c serialupdi
#   make fuses        write the fuses listed below
#
# Toolchain: uses avr-gcc on PATH if it knows the attiny1616, otherwise the
# user-space Microchip toolchain + ATtiny DFP unpacked in .toolchain/ (see README).

PORT     ?= /dev/ttyUSB0
MCU      := attiny1616
TARGET   := ghost-hand
BUILD    := build
SRC      := $(wildcard src/*.c)
OBJ      := $(patsubst src/%.c,$(BUILD)/%.o,$(SRC))

TC       := .toolchain/avr8-gnu-toolchain-linux_x86_64/bin
DFP      := .toolchain/dfp
ifneq ($(wildcard $(TC)/avr-gcc),)
  CC      := $(TC)/avr-gcc
  OBJCOPY := $(TC)/avr-objcopy
  SIZE    := $(TC)/avr-size
  DEVFLAGS := -B $(DFP)/gcc/dev/$(MCU) -isystem $(DFP)/include
else
  CC      := avr-gcc
  OBJCOPY := avr-objcopy
  SIZE    := avr-size
  DEVFLAGS :=
endif

CFLAGS   := -mmcu=$(MCU) $(DEVFLAGS) -DF_CPU=5000000UL -Os -std=gnu11 \
            -Wall -Wextra -Wno-unused-parameter -ffunction-sections -fdata-sections \
            -fshort-enums -flto
LDFLAGS  := -mmcu=$(MCU) $(DEVFLAGS) -Wl,--gc-sections -flto -Os

# Fuses (ATtiny1614/16/17 datasheet 6.10.3 Fuse Summary)
#   WDTCFG  (0) 0x00  watchdog off at reset, firmware enables it (1 s) while awake
#   BODCFG  (1) 0x44  BOD 2.6 V (LVL=2), enabled in active, disabled in sleep (saves ~1 uA)
#   OSCCFG  (2) 0x02  FREQSEL 20 MHz (the firmware divides by 4 -> 5 MHz, by 2 -> 10 MHz)
#   TCD0CFG (4) 0x00
#   SYSCFG0 (5) 0xC5  CRCSRC none, RSTPINCFG UPDI, EESAVE=1 (keep the learnt faucet across reflash)
#   SYSCFG1 (6) 0x07  64 ms start-up
#   APPEND  (7) 0x00, BOOTEND (8) 0x00  no boot section
FUSES    := 0:0x00 1:0x44 2:0x02 4:0x00 5:0xC5 6:0x07 7:0x00 8:0x00

.PHONY: all size test flash flash-avrdude fuses fuses-avrdude clean

all: $(BUILD)/$(TARGET).hex size

$(BUILD)/%.o: src/%.c src/*.h | $(BUILD)
	$(CC) $(CFLAGS) -c $< -o $@

$(BUILD)/$(TARGET).elf: $(OBJ)
	$(CC) $(LDFLAGS) $^ -o $@ -Wl,-Map,$(BUILD)/$(TARGET).map

$(BUILD)/$(TARGET).hex: $(BUILD)/$(TARGET).elf
	$(OBJCOPY) -O ihex -R .eeprom -R .fuse -R .lock -R .signature $< $@

$(BUILD):
	mkdir -p $@

size: $(BUILD)/$(TARGET).elf
	$(SIZE) $<
	@echo "ATtiny1616: 16384 B flash, 2048 B SRAM, 256 B EEPROM"

test:
	$(MAKE) -C test

flash: $(BUILD)/$(TARGET).hex
	pymcuprog write -t uart -u $(PORT) -d $(MCU) -f $< --erase --verify

flash-avrdude: $(BUILD)/$(TARGET).hex
	avrdude -c serialupdi -P $(PORT) -p t1616 -U flash:w:$<:i

fuses:
	pymcuprog write -t uart -u $(PORT) -d $(MCU) -m fuses -o 0 -l 0x00 0x44 0x02
	pymcuprog write -t uart -u $(PORT) -d $(MCU) -m fuses -o 4 -l 0x00 0xC5 0x07 0x00 0x00

fuses-avrdude:
	avrdude -c serialupdi -P $(PORT) -p t1616 -U wdtcfg:w:0x00:m -U bodcfg:w:0x44:m \
	  -U osccfg:w:0x02:m -U syscfg0:w:0xC5:m -U syscfg1:w:0x07:m -U append:w:0x00:m -U bootend:w:0x00:m

clean:
	rm -rf $(BUILD)
	$(MAKE) -C test clean
