####################################################################
# Makefile                                                         #
####################################################################

.SUFFIXES:				# ignore builtin rules
.PHONY: all debug release clean

####################################################################
# Definitions                                                      #
####################################################################

DEVICE = EFM32GG330F1024
PROJECTNAME = freertos
# Name of interface configuration file used by OpenOCD
OOCD_IFACE ?= stlink-v2-1

OBJ_DIR = build
EXE_DIR = exe
LST_DIR = lst

####################################################################
# Definitions of toolchain.                                        #
# You might need to do changes to match your system setup          #
####################################################################

# Change path to the tools according to your system configuration
# DO NOT add trailing whitespace chars, they do matter !
WINDOWSCS  ?= GNU Tools ARM Embedded\4.7 2012q4
LINUXCS    ?= /opt/gcc-arm-none-eabi-4_8-2014q1

RMDIRS     := rm -rf
RMFILES    := rm -rf
ALLFILES   := /*.*
NULLDEVICE := /dev/null
SHELLNAMES := $(ComSpec)$(COMSPEC)

# Try autodetecting the environment
ifeq ($(SHELLNAMES),)
  # Assume we are making on a Linux platform
  TOOLDIR := $(LINUXCS)
else
  QUOTE :="
  ifneq ($(COMSPEC),)
    # Assume we are making on a mingw/msys/cygwin platform running on Windows
    # This is a convenient place to override TOOLDIR, DO NOT add trailing
    # whitespace chars, they do matter !
    TOOLDIR := $(PROGRAMFILES)/$(WINDOWSCS)
    ifeq ($(findstring cygdrive,$(shell set)),)
      # We were not on a cygwin platform
      NULLDEVICE := NUL
    endif
  else
    # Assume we are making on a Windows platform
    # This is a convenient place to override TOOLDIR, DO NOT add trailing
    # whitespace chars, they do matter !
    SHELL      := $(SHELLNAMES)
    TOOLDIR    := $(ProgramFiles)/$(WINDOWSCS)
    RMDIRS     := rd /s /q
    RMFILES    := del /s /q
    ALLFILES   := \*.*
    NULLDEVICE := NUL
  endif
endif

# Create directories and do a clean which is compatible with parallell make
$(shell mkdir $(OBJ_DIR)>$(NULLDEVICE) 2>&1)
$(shell mkdir $(EXE_DIR)>$(NULLDEVICE) 2>&1)
$(shell mkdir $(LST_DIR)>$(NULLDEVICE) 2>&1)
ifeq (clean,$(findstring clean, $(MAKECMDGOALS)))
  ifneq ($(filter $(MAKECMDGOALS),all debug release),)
    $(shell $(RMFILES) $(OBJ_DIR)$(ALLFILES)>$(NULLDEVICE) 2>&1)
    $(shell $(RMFILES) $(EXE_DIR)$(ALLFILES)>$(NULLDEVICE) 2>&1)
    $(shell $(RMFILES) $(LST_DIR)$(ALLFILES)>$(NULLDEVICE) 2>&1)
  endif
endif

CC      = $(QUOTE)$(TOOLDIR)/bin/arm-none-eabi-gcc$(QUOTE)
LD      = $(QUOTE)$(TOOLDIR)/bin/arm-none-eabi-ld$(QUOTE)
AR      = $(QUOTE)$(TOOLDIR)/bin/arm-none-eabi-ar$(QUOTE)
OBJCOPY = $(QUOTE)$(TOOLDIR)/bin/arm-none-eabi-objcopy$(QUOTE)
DUMP    = $(QUOTE)$(TOOLDIR)/bin/arm-none-eabi-objdump$(QUOTE)
SIZE    = $(QUOTE)$(TOOLDIR)/bin/arm-none-eabi-size$(QUOTE)

####################################################################
# Flags                                                            #
####################################################################

# -MMD : Don't generate dependencies on system header files.
# -MP  : Add phony targets, useful when a h-file is removed from a project.
# -MF  : Specify a file to write the dependencies to.
DEPFLAGS = -MMD -MP -MF $(@:.o=.d)

#
# Add -Wa,-ahld=$(LST_DIR)/$(@F:.o=.lst) to CFLAGS to produce assembly list files
#
override CFLAGS += -D$(DEVICE) -Wall -Wextra -mcpu=cortex-m3 -mthumb \
-mfix-cortex-m3-ldrd -ffunction-sections \
-fdata-sections -fomit-frame-pointer -DGCC_ARMCM3 -DFREERTOS $(DEPFLAGS) \
-Wno-missing-field-initializers -Wno-unused-function -Wno-switch

override ASMFLAGS += -x assembler-with-cpp -D$(DEVICE) -Wall -Wextra -mcpu=cortex-m3 -mthumb

#
# NOTE: The -Wl,--gc-sections flag may interfere with debugging using gdb.
#
override LDFLAGS += -Xlinker -Map=$(LST_DIR)/$(PROJECTNAME).map -mcpu=cortex-m3 \
-mthumb -T../common/Device/EnergyMicro/EFM32GG/Source/GCC/efm32gg_bootld.ld \
 -Wl,--gc-sections

LIBS = -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group

INCLUDEPATHS += \
-Isrc \
-Isrc/apps \
-IFreeRTOS/Source/include \
-I../bitmaps \
-I../common/CMSIS/Include \
-I../common/Device/EnergyMicro/EFM32GG/Include \
-I../common \
-I../common/drivers \
-I../common/usb \
-I../common/usb/inc \
-I../common/emlib/inc \
-I../common/emdrv/sleep/inc \
-I../common/nmealib/include \
-I../common/reptile/fatfs/inc

####################################################################
# Files                                                            #
####################################################################

C_SRC +=  \
../bitmaps/bitmaps.c \
../common/Device/EnergyMicro/EFM32GG/Source/system_efm32gg.c \
../common/emlib/src/em_assert.c \
../common/emlib/src/em_burtc.c \
../common/emlib/src/em_cmu.c \
../common/emlib/src/em_dma.c \
../common/emlib/src/em_emu.c \
../common/emlib/src/em_gpio.c \
../common/emlib/src/em_i2c.c \
../common/emlib/src/em_int.c \
../common/emlib/src/em_rmu.c \
../common/emlib/src/em_rtc.c \
../common/emlib/src/em_system.c \
../common/emlib/src/em_timer.c \
../common/emlib/src/em_usart.c \
../common/emlib/src/em_leuart.c \
../common/emlib/src/em_msc.c \
../common/emdrv/sleep/src/sleep.c \
../common/drivers/dmactrl.c \
../common/drivers/lcd.c \
../common/drivers/lcd_dma.c \
../common/drivers/backlight.c \
../common/drivers/buttons.c \
../common/drivers/buzzer.c \
../common/drivers/i2cdrv.c \
../common/drivers/light_sensor.c \
../common/drivers/max17047.c \
../common/drivers/microsd.c \
../common/drivers/rtc.c \
../common/drivers/vibra.c \
../common/drivers/lsm303c.c \
../common/drivers/gps.c \
../common/gfx/font_helv11.c \
../common/gfx/font_helv17.c \
../common/gfx/font_helv17b.c \
../common/gfx/font_helv22b.c \
../common/gfx/font_helv29.c \
../common/gfx/font_helv38b.c \
../common/gfx/font_luct38.c \
../common/gfx/font_xm16x25b.c \
../common/gfx/font_xm4x5.c \
../common/gfx/font_xm4x6.c \
../common/gfx/font_xm5x8.c \
../common/gfx/gfx.c \
../common/gfx/ui.c \
../common/reptile/fatfs/src/diskio.c \
../common/reptile/fatfs/src/ff.c \
../common/reptile/fatfs/src/option/ccsbcs.c \
../common/sincos.c \
../common/eeprom_emulation.c \
../common/usb/src/em_usbd.c \
../common/usb/src/em_usbdch9.c \
../common/usb/src/em_usbhal.c \
../common/usb/src/em_usbdep.c \
../common/usb/src/em_usbdint.c \
../common/usb/src/em_usbtimer.c \
../common/usb/usbdbg.c \
../common/usb/msddmedia.c \
../common/usb/msdd.c \
../common/nmealib/src/context.c \
../common/nmealib/src/generate.c \
../common/nmealib/src/generator.c \
../common/nmealib/src/gmath.c \
../common/nmealib/src/info.c \
../common/nmealib/src/parse.c \
../common/nmealib/src/parser.c \
../common/nmealib/src/sentence.c \
../common/nmealib/src/time.c \
../common/nmealib/src/tok.c \
FreeRTOS/Source/timers.c \
FreeRTOS/Source/tasks.c \
FreeRTOS/Source/queue.c \
FreeRTOS/Source/list.c \
FreeRTOS/Source/croutine.c \
FreeRTOS/Source/portable/MemMang/heap_1.c \
FreeRTOS/Source/portable/GCC/ARM_CM3/port.c \
src/apps/settings/set_date.c \
src/apps/settings/set_time.c \
src/apps/settings/settings.c \
src/apps/settings/set_gmt_ofs.c \
src/apps/settings/set_time_fr_gps.c \
src/apps/widgets/spinbox.c \
src/apps/widgets/status_bar.c \
src/apps/application.c \
src/apps/clock.c \
src/apps/example_app.c \
src/apps/compass.c \
src/apps/game.c \
src/apps/menu.c \
src/apps/menu_struct.c \
src/apps/gpscoord.c \
src/apps/reset.c \
src/apps/usb_mass_storage.c \
src/main.c \
src/battery_task.c \
src/blight_task.c \
src/gpsbkgnd_task.c \
src/irq_dispatcher.c \
src/low_power_tick_management.c \
src/state.c

s_SRC +=

S_SRC +=  \
../common/Device/EnergyMicro/EFM32GG/Source/GCC/startup_efm32gg.S

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

C_FILES = $(notdir $(C_SRC) )
S_FILES = $(notdir $(S_SRC) $(s_SRC) )
#make list of source paths, sort also removes duplicates
C_PATHS = $(sort $(dir $(C_SRC) ) )
S_PATHS = $(sort $(dir $(S_SRC) $(s_SRC) ) )

C_OBJS = $(addprefix $(OBJ_DIR)/, $(C_FILES:.c=.o))
S_OBJS = $(if $(S_SRC), $(addprefix $(OBJ_DIR)/, $(S_FILES:.S=.o)))
s_OBJS = $(if $(s_SRC), $(addprefix $(OBJ_DIR)/, $(S_FILES:.s=.o)))
C_DEPS = $(addprefix $(OBJ_DIR)/, $(C_FILES:.c=.d))
OBJS = $(C_OBJS) $(S_OBJS) $(s_OBJS)

vpath %.c $(C_PATHS)
vpath %.s $(S_PATHS)
vpath %.S $(S_PATHS)

# Default build is debug build
all:      debug

debug:    CFLAGS += -DDEBUG -O0 -g -DDEBUG_EFM
debug:    $(EXE_DIR)/$(PROJECTNAME).bin

release:  CFLAGS += -DNDEBUG -O0
release:  $(EXE_DIR)/$(PROJECTNAME).bin

# Create objects from C SRC files
$(OBJ_DIR)/%.o: %.c
	@echo "Building file: $<"
	$(CC) $(CFLAGS) $(INCLUDEPATHS) -c -o $@ $<

# Assemble .s/.S files
$(OBJ_DIR)/%.o: %.s
	@echo "Assembling $<"
	$(CC) $(ASMFLAGS) $(INCLUDEPATHS) -c -o $@ $<

$(OBJ_DIR)/%.o: %.S
	@echo "Assembling $<"
	$(CC) $(ASMFLAGS) $(INCLUDEPATHS) -c -o $@ $<

# Link
$(EXE_DIR)/$(PROJECTNAME).out: $(OBJS)
	@echo "Linking target: $@"
	$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $(EXE_DIR)/$(PROJECTNAME).out

# Create binary file
$(EXE_DIR)/$(PROJECTNAME).bin: $(EXE_DIR)/$(PROJECTNAME).out
	@echo "Creating binary file and code footprint"
	$(OBJCOPY) -O binary $(EXE_DIR)/$(PROJECTNAME).out $(EXE_DIR)/$(PROJECTNAME).bin
# Uncomment next line to produce assembly listing of entire program
#	$(DUMP) -h -S -C $(EXE_DIR)/$(PROJECTNAME).out>$(LST_DIR)/$(PROJECTNAME)out.lst
# Uncomment next line to produce code footprint
	$(SIZE) $<

clean:
ifeq ($(filter $(MAKECMDGOALS),all debug release),)
	$(RMDIRS) $(OBJ_DIR) $(LST_DIR) $(EXE_DIR)
endif

flash: $(EXE_DIR)/$(PROJECTNAME).bin
	openocd -s ../common/openocd -f interface/$(OOCD_IFACE).cfg -f init.cfg -c "program $(EXE_DIR)/$(PROJECTNAME).bin 0 verify reset"

# include auto-generated dependency files (explicit rules)
ifneq (clean,$(findstring clean, $(MAKECMDGOALS)))
-include $(C_DEPS)
endif
