########################################################################################################################
# Dependency directories
########################################################################################################################

CMSIS_DEVICE_DIR 	?= upstream/st-cmsis-f0
CMSIS_CORE_DIR 		?= upstream/cmsis-core
HAL_DIR				?= upstream/st-hal-f0
ST_USBD_DIR			?= upstream/st-usb-device
MUSL_DIR			?= upstream/musl

########################################################################################################################
# Sources
########################################################################################################################

C_SOURCES	:= 	src/main.c \
				src/stm32f0xx_it.c \
				src/stm32f0xx_hal_msp.c \
				src/usb_device.c \
				src/usbd_conf.c \
				src/usbd_desc.c \
				src/usbd_hid.c \
				src/system_stm32f0xx.c

C_SOURCES	+= 	$(MUSL_DIR)/src/string/memset.c \
				$(MUSL_DIR)/src/string/memcpy.c

C_SOURCES	+=  $(HAL_DIR)/Src/stm32f0xx_ll_usb.c \
				$(HAL_DIR)/Src/stm32f0xx_hal_adc.c \
				$(HAL_DIR)/Src/stm32f0xx_hal_adc_ex.c \
				$(HAL_DIR)/Src/stm32f0xx_hal_rcc.c \
				$(HAL_DIR)/Src/stm32f0xx_hal_rcc_ex.c \
				$(HAL_DIR)/Src/stm32f0xx_hal.c \
				$(HAL_DIR)/Src/stm32f0xx_hal_i2c.c \
				$(HAL_DIR)/Src/stm32f0xx_hal_i2c_ex.c \
				$(HAL_DIR)/Src/stm32f0xx_hal_gpio.c \
				$(HAL_DIR)/Src/stm32f0xx_hal_dma.c \
				$(HAL_DIR)/Src/stm32f0xx_hal_cortex.c \
				$(HAL_DIR)/Src/stm32f0xx_hal_pwr.c \
				$(HAL_DIR)/Src/stm32f0xx_hal_pwr_ex.c \
				$(HAL_DIR)/Src/stm32f0xx_hal_flash.c \
				$(HAL_DIR)/Src/stm32f0xx_hal_flash_ex.c \
				$(HAL_DIR)/Src/stm32f0xx_hal_exti.c \
				$(HAL_DIR)/Src/stm32f0xx_hal_tim.c \
				$(HAL_DIR)/Src/stm32f0xx_hal_tim_ex.c \
				$(HAL_DIR)/Src/stm32f0xx_hal_pcd.c \
				$(HAL_DIR)/Src/stm32f0xx_hal_pcd_ex.c

C_SOURCES 	+=  $(ST_USBD_DIR)/Core/Src/usbd_core.c \
				$(ST_USBD_DIR)/Core/Src/usbd_ctlreq.c \
				$(ST_USBD_DIR)/Core/Src/usbd_ioreq.c \

CXX_SOURCES			+=

########################################################################################################################
# Build parameters
########################################################################################################################

BUILDDIR 		?= build
BINARY 			:= minikbd.elf
STARTUP_FILE 	:= src/startup_stm32f072xb.s
LDSCRIPT 		:= STM32F072CBUx_FLASH.ld

ARCH_FLAGS	    := -mthumb -mcpu=cortex-m0 -mfloat-abi=soft
SYSTEM_FLAGS    += -nostdlib -ffreestanding -nostartfiles

CFLAGS	        := -O0 -g -std=gnu11
CFLAGS			+= -DUSE_HAL_DRIVER -DSTM32F072xB
CFLAGS          += -DSTM32F0 -DDEBUG=$(DEBUG)
# ST weirdness
CFLAGS			+= -DUSBD_CLASS_BOS_ENABLED=0

CFLAGS			+= -fno-common -ffunction-sections -fdata-sections

CFLAGS  		+= -I$(BUILDDIR) \
                   -Isrc \
                   -I$(CMSIS_DEVICE_DIR)/Include \
                   -I$(CMSIS_CORE_DIR) \
                   -I$(HAL_DIR)/Inc \
                   -I$(ST_USBD_DIR)/Core/Inc \
                   -I$(ST_USBD_DIR)/Class/HID/Inc \
				   -Imusl_include_shims
# for musl
CFLAGS			+= -Dhidden=

CFLAGS      	+= -Wall -Wextra -Wpedantic -Wshadow -Wimplicit-function-declaration -Wundef -Wno-unused-parameter
CFLAGS      	+= -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes

CFLAGS          += $(ARCH_FLAGS) $(SYSTEM_FLAGS)

LDFLAGS			+= $(ARCH_FLAGS) $(SYSTEM_FLAGS)

LIBS		    += -lgcc
LDFLAGS		    += -Wl,--gc-sections

LINKMEM_FLAGS ?= --trim-stubs=$(STARTUP_FILE:.s=.o) --trace-sections .isr_vector --highlight-subdirs $(BUILDDIR)

OBJS := $(addprefix $(BUILDDIR)/,$(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o))
OBJS += $(BUILDDIR)/$(STARTUP_FILE:.s=.o)

########################################################################################################################
# Build tools
########################################################################################################################

PREFIX		?= arm-none-eabi-

DEBUG		?= 1

CC			:= $(PREFIX)gcc
CXX			:= $(PREFIX)g++
LD			:= $(PREFIX)gcc
AR			:= $(PREFIX)ar
AS			:= $(PREFIX)as
SIZE		:= $(PREFIX)size
NM			:= $(PREFIX)nm
OBJCOPY		:= $(PREFIX)objcopy
OBJDUMP		:= $(PREFIX)objdump
GDB			:= $(PREFIX)gdb

HOST_CC				?= $(HOST_PREFIX)gcc
HOST_CXX			?= $(HOST_PREFIX)g++
HOST_LD				?= $(HOST_PREFIX)gcc
HOST_AR				?= $(HOST_PREFIX)ar
HOST_AS				?= $(HOST_PREFIX)as
HOST_OBJCOPY		?= $(HOST_PREFIX)objcopy
HOST_OBJDUMP		?= $(HOST_PREFIX)objdump

PYTHON3 ?= python3
DOT		?= dot

########################################################################################################################
# Rules
########################################################################################################################

all: $(BUILDDIR)/$(BINARY:.elf=.bin)

.PHONY: binsize
binsize: $(BUILDDIR)/$(BINARY) $(BUILDDIR)/$(BINARY:.elf=-symbol-sizes.pdf) 
	@echo
	@$(LD) -T$(LDSCRIPT) $(LDFLAGS) -Wl,--print-memory-usage -o /dev/null $(OBJS) $(LIBS)
	@echo
	@echo "▐▬▬▬▌ SyMbOL sIzE HiGhScORe LiSt ▐▬▬▬▌"
	@echo
	$(NM) --print-size --size-sort --radix=d $< | tail -n 20

$(BUILDDIR)/generated: ; mkdir -p $@

.PRECIOUS: $(BUILDDIR)/$(BINARY) 
$(BUILDDIR)/$(BINARY) $(BUILDDIR)/$(BINARY:.elf=.map) &: $(OBJS)
	$(LD) -T$(LDSCRIPT) $(LDFLAGS) -o $@ -Wl,-Map=$(BUILDDIR)/$(BINARY:.elf=.map) $^ $(LIBS)

FORCE:

build/$(BINARY:.elf=-symbol-sizes.dot): $(OBJS) FORCE
	@$(PYTHON3) tools/linkmem.py $(LINKMEM_FLAGS) $(LD) -T$(LDSCRIPT) $(LDFLAGS) $(OBJS) $(LIBS) > $@

%.pdf: %.dot
	@$(DOT) -T pdf $< -o $@

%.dot: %.elf
	r2 -a arm -qc 'aa;agRd' $< 2>/dev/null >$@

%.bin: %.elf
	$(OBJCOPY) -O binary $^ $@

$(BUILDDIR)/src/%.o: src/%.s
	mkdir -p $(@D)
	$(CC) $(COMMON_CFLAGS) $(CFLAGS) $(INT_CFLAGS) -o $@ -c $<

$(BUILDDIR)/src/%.o: src/%.c
	mkdir -p $(@D)
	$(CC) $(COMMON_CFLAGS) $(CFLAGS) $(INT_CFLAGS) -o $@ -c $<

$(BUILDDIR)/src/%.o: src/%.cpp
	mkdir -p $(@D)
	$(CXX) $(CXXFLAGS) -o $@ -c $<

$(BUILDDIR)/generated/%.o: $(BUILDDIR)/generated/%.c
	mkdir -p $(@D)
	$(CC) $(COMMON_CFLAGS) $(CFLAGS) $(INT_CFLAGS) -o $@ -c $<

$(BUILDDIR)/%.o: %.c
	mkdir -p $(@D)
	$(CC) $(COMMON_CFLAGS) $(CFLAGS) $(EXT_CFLAGS) -o $@ -c $<

.PHONY: flash
flash: $(BUILDDIR)/$(BINARY:.elf=.bin)
	dfu-util -a 0 -s 0x08000000 -D $^

clean:
	rm -rf $(BUILDDIR)/src
	rm -rf $(BUILDDIR)/generated
	rm -f $(BUILDDIR)/$(BINARY)
	rm -f $(BUILDDIR)/$(BINARY:.elf=.map)
	rm -f $(BUILDDIR)/$(BINARY:.elf=-symbol-sizes.dot)
	rm -f $(BUILDDIR)/$(BINARY:.elf=-symbol-sizes.pdf)
	rm -f $(BUILDDIR)/tools/freq_meas_test

mrproper: clean
	rm -rf build

.PHONY: clean mrproper

-include $(OBJS:.o=.d)