# Copyright 2019, Max Regan
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

#
# Tools
#

TOOL_PREFIX ?= arm-none-eabi-
CC			=  $(TOOL_PREFIX)gcc
CPP			=  $(TOOL_PREFIX)cpp
AS			=  $(TOOL_PREFIX)as
LD			=  $(TOOL_PREFIX)gcc
OBJCOPY		=  $(TOOL_PREFIX)objcopy
STM32FLASH	?= stm32flash

#
# Device Variables
#

DEVICE_TYPE    ?= stm32l031k6
DEVICE_FAMILY  =  stm32l031xx
DEVICE_LINE    =  stm32l0xx


#
# Filenames and paths
#

C_SOURCES   := $(shell find $(SOURCEDIR) -name '*.c')
S_SOURCES   := $(shell find $(SOURCEDIR) -name '*.s')
SPP_SOURCES := $(DEVICE_TYPE).S
SOURCES     =  $(C_SOURCES) $(S_SOURCES) $(SPP_SOURCES)

C_OBJS   := $(patsubst %.c,%.o,$(C_SOURCES))
S_OBJS   := $(patsubst %.s,%.o,$(S_SOURCES))
SPP_OBJS := $(patsubst %.S,%.o,$(SPP_SOURCES))
OBJS     =  $(C_OBJS) $(S_OBJS) $(SPP_OBJS)

LINKER_SCRIPT ?= $(DEVICE_TYPE).ld

OUTPUT_NAME ?= test
OUTPUT_BIN  ?= $(OUTPUT_NAME).bin
OUTPUT_ELF  ?= $(OUTPUT_NAME).elf

#
# Flags
#

DEVICE_DEFINE = $(subst XX,xx,$(shell echo $(DEVICE_FAMILY) | tr '[:lower:]' '[:upper:]'))

# C pedantism
CFLAGS =  -Wall -Wextra -Wpedantic
# Debug/optimization
CFLAGS += -Og -g3
# Architecture
CFLAGS += -mthumb -mcpu=cortex-m0plus
CFLAGS += -ffreestanding
# Defines
CFLAGS += -D$(DEVICE_DEFINE)
# Includes
CFLAGS += -I./lib/stm32/$(DEVICE_LINE)/Include
CFLAGS += -I./lib/CMSIS/Core/Include

# Startup Definitions
ASFLAGS += -D__STARTUP_CLEAR_BSS
ASFLAGS += -D__HEAP_SIZE=0 # No heap- let the linker decide it all

LDFLAGS += -nostdinc -lc -lnosys -Wl,--gc-sections -Wl,--print-memory-usage

#
# Default Target
#
.PHONY: build
build: $(OUTPUT_BIN)

#
# Build Logic
#

%.o: %.c
	@echo "CC $@"
	@$(CC) $(CFLAGS) -c $< -o $@

%.o: %.S
	@echo "AS $@"
	@$(CC) $(ASFLAGS) -c $< -o $@

$(OUTPUT_BIN): $(OUTPUT_ELF)
	@echo "OBJCOPY $@"
	@$(OBJCOPY) -O binary $(OUTPUT_ELF) $(OUTPUT_BIN)

$(OUTPUT_ELF): $(LINKER_SCRIPT) $(OBJS)
	@echo "LD $@"
	$(LD) $(LDFLAGS) -T $(LINKER_SCRIPT) -o $(OUTPUT_ELF) $(OBJS)

#
# Utilities
#

STM32FLASH_DEVICE = /dev/ttyUSB0

.PHONY: flash
flash: $(OUTPUT_BIN)
	@echo "FLASH $(OUTPUT_BIN)"
	@st-flash write $(OUTPUT_BIN) 0x8000000 2> /dev/null
#	stm32flash -w $(OUTPUT_BIN) $(STM32FLASH_DEVICE)


.PHONY: clean
clean:
	@echo "RM $(OBJS)"
	@rm -f $(OBJS) $(OUTPUT_BIN) $(OUTPUT_ELF)
