BINARY = wc12h_f1

#LDSCRIPT = wclock24h-F103/stm32f103c8_flash.ld
LDSCRIPT = stm32f103c8.ld

#DEFS += -DDEBUG
DEFS += -DUSE_STDPERIPH_DRIVER
DEFS += -DHSE_VALUE=8000000
DEFS += -DWCLOCK24H=0

DEFS += -DSTM32F1
DEFS += -DSTM32F10X
DEFS += -DSTM32F103
DEFS += -DSTM32F103C8
DEFS += -DSTM32F10X_MD

FP_FLAGS        ?= -msoft-float -mfloat-abi=soft
ARCH_FLAGS      = -mthumb -mcpu=cortex-m3 $(FP_FLAGS) -mfix-cortex-m3-ldrd

# Be silent per default, but 'make V=1' will show all compiler calls.
ifneq ($(V),1)
Q		:= @
NULL		:= 2>/dev/null
endif

###############################################################################
# Executables

PREFIX		?= arm-none-eabi

CC		:= $(PREFIX)-gcc
CXX		:= $(PREFIX)-g++
LD		:= $(PREFIX)-gcc
AR		:= $(PREFIX)-ar
AS		:= $(PREFIX)-as
OBJCOPY		:= $(PREFIX)-objcopy
OBJDUMP		:= $(PREFIX)-objdump
GDB		:= $(PREFIX)-gdb
SIZE		:= $(PREFIX)-size
STFLASH		= $(shell which st-flash)

###############################################################################
# Source files

# Program
SRCS		= src/main.c
SRCS		+= $(wildcard src/*/*.c)
HDRS		= $(wildcard src/*.h)
HDRS		+= $(wildcard src/*/*.h)
# libs for F4
#F4SRCS	+= src/startup_stm32f4xx.S
#F4SRCS	+= src/system_stm32f4xx.c
#F4SRCS	+= $(wildcard SPL/src/*.c)
#F4HDRS	+= $(wildcard inc/*.h)
#F4HDRS	+= $(wildcard cmsis/*.h)
#F4HDRS	+= $(wildcard SPL/inc/*.h)
# libs for F1
F1SRCS	+= wclock24h-F103/src/startup_stm32f10x_md.S
F1SRCS	+= wclock24h-F103/src/system_stm32f10x.c
F1SRCS	+= $(wildcard wclock24h-F103/SPL/src/*.c)

F1HDRS	+= $(wildcard wclock24h-F103/inc/*.h)
F1HDRS	+= $(wildcard wclock24h-F103/cmsis/*.h)
F1HDRS	+= $(wildcard wclock24h-F103/SPL/inc/*.h)

OBJS = $(patsubst %.c,%.o,$(SRCS))
F1OBJS =  $(patsubst %.S,%.o,$(F1SRCS:.c=.o))
#F4OBJS =  $(patsubst %.S,%.o,$(F4SRCS:.c=.o))

INC_DIRS = $(sort $(foreach f,$(HDRS),-I$(dir $(f))))
F1INC_DIRS = $(sort $(foreach f,$(F1HDRS),-I$(dir $(f))))
#F4INC_DIRS = $(sort $(foreach f,$(F4HDRS),-I$(dir $(f))))

OBJFILES = $(OBJS) $(F1OBJS)
DEPFILES = $(OBJS:.o=.d) $(F1OBJS:.o=.d)

###############################################################################
# C flags

CFLAGS		+= -O2 -g
CFLAGS		+= -Wextra -Wshadow -Wimplicit-function-declaration
#CFLAGS		+= -Wredundant-decls
CFLAGS		+= -Wmissing-prototypes -Wstrict-prototypes
CFLAGS		+= -fno-common -ffunction-sections -fdata-sections -fno-strict-aliasing

###############################################################################
# C preprocessor flags

CPPFLAGS	+= -MD
CPPFLAGS	+= -Wundef
CPPFLAGS	+= $(DEFS)
CPPFLAGS	+= $(F1INC_DIRS)

###############################################################################
# Linker flags

LDFLAGS		+= --static -nostartfiles
LDFLAGS		+= -T$(LDSCRIPT)
LDFLAGS		+= -Wl,-Map=$(*).map
LDFLAGS		+= -Wl,--gc-sections
LDFLAGS		+= $(LDLIBS) -L.
ifeq ($(V),99)
LDFLAGS		+= -Wl,--print-gc-sections
endif

###############################################################################
# Used libraries

#LDLIBS		+= -Wl,--start-group -lc -lgcc -lnosys -lf10x_md -Wl,--end-group

###############################################################################
# Hacks for working newlib
CFLAGS += --specs=nano.specs -fshort-wchar
LDFLAGS += --specs=nano.specs -lc_nano -lnosys
ifneq ($(findstring sbrk.c,$(SRCS)),sbrk.c)
SRCS += src/stubs/sbrk.c
OBJS += src/stubs/sbrk.c
endif

###############################################################################
###############################################################################
###############################################################################

.SUFFIXES: .elf .bin .hex .srec .list .map .images
.SECONDEXPANSION:
.SECONDARY:

all: clean images

###############################################################################
# stubs: files which are needed, but are not provided

STUBS = stm32f103c8.ld stm32f401re.ld stm32f411re.ld src/stubs/sbrk.c

stm32f103c8.ld:
	@printf "  GENSTUB $@\n"
	$(Q)echo "ENTRY(Reset_Handler)" > $@
	$(Q)echo "INCLUDE wclock24h-F103/stm32f103c8_flash.ld" > $@

stm32f401re.ld:
	@printf "  GENSTUB $@\n"
	$(Q)echo "ENTRY(Reset_Handler)" > $@
	$(Q)echo "INCLUDE stm32f401re_flash.ld" > $@

stm32f411re.ld:
	@printf "  GENSTUB $@\n"
	$(Q)echo "ENTRY(Reset_Handler)" > $@
	$(Q)echo "INCLUDE stm32f411re_flash.ld" > $@

src/stubs/sbrk.c:
	@printf "  GENSTUB $@.c\n"
	$(Q)mkdir -p src/stubs
	$(Q)echo "typedef char* caddr_t;" > $@
	$(Q)echo "caddr_t _sbrk(int incr) {" >> $@
	$(Q)echo "  extern char __end__;      /* Defined by the linker */" >> $@
	$(Q)echo "  extern char __HeapLimit;  /* Defined by the linker */" >> $@
	$(Q)echo "  static char *heap_end;" >> $@
	$(Q)echo "  char *prev_heap_end;" >> $@
	$(Q)echo >> $@
	$(Q)echo "  if (heap_end == 0) { heap_end = &__end__; }" >> $@
	$(Q)echo >> $@
	$(Q)echo "  prev_heap_end = heap_end;" >> $@
	$(Q)echo >> $@
	$(Q)echo "  if (heap_end + incr > &__HeapLimit) {" >> $@
	$(Q)echo "    return (caddr_t) -1; // signal error" >> $@
	$(Q)echo "  }" >> $@
	$(Q)echo >> $@
	$(Q)echo "  heap_end += incr;" >> $@
	$(Q)echo "  return (caddr_t) prev_heap_end;" >> $@
	$(Q)echo "}" >> $@


elf: $(BINARY).elf
bin: $(BINARY).bin
hex: $(BINARY).hex
list: $(BINARY).list

images: $(BINARY).images

$(LDSCRIPT):
    ifeq (,$(wildcard $(LDSCRIPT)))
    ifneq ($(LDSCRIPT), $(findstring $(LDSCRIPT), $(STUBS)))
        $(error Unable to find or generate specified linker script: $(LDSCRIPT))
    endif
    endif

libf10x_md.a: $(F1OBJS)
	@printf "  AR      $(*).a\n"
	$(Q)$(AR) rcs $(*).a $(F1OBJS)

$(F1OBJS): $(F1SRCS) $(F1HDRS)
	@printf "  CC      $(*).c\n"
	$(Q)if test -f $(*).S ; then \
	$(CC) $(CFLAGS) $(F1INC_DIRS) $(CPPFLAGS) $(ARCH_FLAGS) -o $(*).o -c $(*).S; \
	else \
	$(CC) $(CFLAGS) $(F1INC_DIRS) $(CPPFLAGS) $(ARCH_FLAGS) -o $(*).o -c $(*).c; \
	fi

%.images: %.bin %.hex %.list %.map
	@printf "*** $* images generated ***\n"
	$(Q)$(SIZE) $(*).elf

%.bin: %.elf
	@printf "  OBJCOPY $(*).bin\n"
	$(Q)$(OBJCOPY) -Obinary $(*).elf $(*).bin

%.hex: %.elf
	@printf "  OBJCOPY $(*).hex\n"
	$(Q)$(OBJCOPY) -Oihex $(*).elf $(*).hex

%.list: %.elf
	@printf "  OBJDUMP $(*).list\n"
	$(Q)$(OBJDUMP) -S $(*).elf > $(*).list

%.elf %.map: $(OBJS) $(LDSCRIPT) libf10x_md.a
	@printf "  LD      $(*).elf\n"
	$(Q)$(LD) -o $(*).elf $(LDFLAGS) $(ARCH_FLAGS) $(OBJS) -lf10x_md

%.o: %.c
	@printf "  CC      $(*).c\n"
	$(Q)$(CC) $(CFLAGS) $(INC_DIRS) $(CPPFLAGS) $(ARCH_FLAGS) -o $(*).o -c $(*).c

clean:
	@printf "  CLEAN\n"
	$(Q)$(RM) $(OBJFILES) $(DEPFILES) $(STUBS) *.a *.elf *.bin *.hex *.srec *.list *.map


%.stlink-flash: %.bin
	@printf "  FLASH  $<\n"
	$(Q)$(STFLASH) write $(*).bin 0x8000000


.PHONY: images clean elf bin hex srec list

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

flash: $(BINARY).stlink-flash


