PROJECT_NAME := Ble-Module-GCC
export OUTPUT_FILENAME
MAKEFILE_NAME := $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
MAKEFILE_NAME := $(MAKEFILE_LIST)
MAKEFILE_DIR := $(dir $(MAKEFILE_NAME) ) 


SDK_PATH = $(TEMPLATE_PATH)/Ble-Module-GCC/library

PROJECT_DIR := $(TEMPLATE_PATH)/$(PROJECT_NAME)

TOOLCHAIN_PATH := $(SDK_PATH)\nrf51_sdk_v810\components\toolchain\gcc


ifeq ($(OS),Windows_NT)
include $(TOOLCHAIN_PATH)\Makefile.windows
else
include $(TOOLCHAIN_PATH)\Makefile.posix
endif

MK := mkdir
RM := rm -rf

#echo suspend
ifeq ("$(VERBOSE)","1")
NO_ECHO := 
else
NO_ECHO := @
endif

# Toolchain commands
CC       		:= arm-none-eabi-gcc
AS       		:= arm-none-eabi-as
AR       		:= arm-none-eabi-ar -r
LD       		:= arm-none-eabi-ld
NM       		:= arm-none-eabi-nm
OBJDUMP  		:= arm-none-eabi-objdump
OBJCOPY  		:= arm-none-eabi-objcopy
SIZE    		:= arm-none-eabi-size

CFLAGS = -DSOFTDEVICE_PRESENT -DBLE_DFU_APP_SUPPORT -DNRF51 -DSPI_MASTER_0_ENABLE -DSWI_DISABLE0 -DS110 -DBLE_STACK_SUPPORT_REQD
CFLAGS += -mcpu=cortex-m0 #-mfloat-abi=soft
CFLAGS += -mthumb --std=gnu99
CFLAGS += -Wall -Os
CFLAGS += -ffunction-sections -fdata-sections -fno-builtin --short-enums# -DBL_BAUD_RATE=9600 -DSECU3T

# keep every function in separate section. This will allow linker to dump unused functions
LDFLAGS = -Xlinker -Map=$(LISTING_DIRECTORY)/$(OUTPUT_FILENAME).map
LDFLAGS += -mthumb -mabi=aapcs -L $(TOOLCHAIN_PATH) -T$(LINKER_SCRIPT)
LDFLAGS += -mcpu=cortex-m0
# let linker to dump unused sections
LDFLAGS += -Wl,--gc-sections
# use newlib in nano version
LDFLAGS += --specs=nano.specs -lc -lnosys

# Assembler flags
ASMFLAGS = -DNRF51 -DBLE_DFU_APP_SUPPORT
ASMFLAGS += -DBLE_STACK_SUPPORT_REQD
ASMFLAGS += -DSPI_MASTER_0_ENABLE
ASMFLAGS += -DS110
ASMFLAGS += -DSOFTDEVICE_PRESENT
ASMFLAGS += -DSWI_DISABLE0
#function for removing duplicates in a list
remduplicates = $(strip $(if $1,$(firstword $1) $(call remduplicates,$(filter-out $(firstword $1),$1))))

SOURCE_DIR 	   := $(PROJECT_DIR)
COMPONENTS_DIR := $(SDK_PATH)/nrf51_sdk_v810/components

## Application ASM source files
ASM_SOURCE_FILES = \
$(abspath $(SDK_PATH)\nrf51_sdk_v810\components\toolchain\gcc\gcc_startup_nrf51.s)


## Application C source files
C_SOURCE_FILES += \
$(abspath $(SOURCE_DIR)/application/source/main.c) \
$(abspath $(SOURCE_DIR)/application/source/ains.c) \
$(abspath $(SOURCE_DIR)/application/source/events.c) \
$(abspath $(SOURCE_DIR)/application/source/led.c) \
$(abspath $(SOURCE_DIR)/application/source/s25fl.c) \
$(abspath $(SOURCE_DIR)/application/source/pcf85.c) \
$(abspath $(SOURCE_DIR)/application/source/tests.c) \
$(abspath $(SOURCE_DIR)/application/source/twi_hw_master_sd.c) \
$(abspath $(COMPONENTS_DIR)\drivers_nrf\hal\nrf_delay.c) \
$(abspath $(COMPONENTS_DIR)\drivers_nrf\spi_master\spi_master.c) \
$(abspath $(COMPONENTS_DIR)\drivers_nrf\timer\nrf_drv_timer.c) \
$(abspath $(COMPONENTS_DIR)\drivers_nrf\ppi\nrf_drv_ppi.c) \
$(abspath $(COMPONENTS_DIR)\drivers_nrf\hal\nrf_adc.c) \
$(abspath $(COMPONENTS_DIR)\drivers_nrf\common\nrf_drv_common.c) \
$(abspath $(COMPONENTS_DIR)\drivers_nrf\ble_flash\ble_flash.c) \
$(abspath $(COMPONENTS_DIR)\drivers_nrf\pstorage\pstorage.c) \
$(abspath $(COMPONENTS_DIR)\ble\ble_services\ble_dfu\ble_dfu.c) \
$(abspath $(COMPONENTS_DIR)\ble\device_manager\device_manager_peripheral.c) \
$(abspath $(COMPONENTS_DIR)\ble\common\ble_advdata.c) \
$(abspath $(COMPONENTS_DIR)\ble\common\ble_conn_params.c) \
$(abspath $(COMPONENTS_DIR)\ble\ble_services\ble_nus\ble_nus.c) \
$(abspath $(COMPONENTS_DIR)\ble\ble_advertising\ble_advertising.c) \
$(abspath $(COMPONENTS_DIR)\softdevice\common\softdevice_handler\softdevice_handler.c) \
$(abspath $(COMPONENTS_DIR)\softdevice\common\softdevice_handler\softdevice_handler_appsh.c) \
$(abspath $(COMPONENTS_DIR)\toolchain\system_nrf51422.c) \
$(abspath $(COMPONENTS_DIR)\libraries\util\app_util_platform.c) \
$(abspath $(COMPONENTS_DIR)\libraries\util\app_error.c) \
$(abspath $(COMPONENTS_DIR)\libraries\bootloader_dfu\dfu_app_handler.c) \
$(abspath $(COMPONENTS_DIR)\libraries\timer\app_timer.c) \
$(abspath $(COMPONENTS_DIR)\libraries\bootloader_dfu\bootloader_util.c)
## Application include files

INC_PATHS  = -I$(abspath $(SDK_PATH)\bsp)
INC_PATHS += -I$(abspath $(PROJECT_DIR)\application\config)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\device)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\toolchain)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\ble\ble_advertising)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\ble\ble_services)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\ble\common)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\ble\ble_services\ble_nus)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\drivers_nrf\ble_flash)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\drivers_nrf\common)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\drivers_nrf\gpiote)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\drivers_nrf\hal)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\drivers_nrf\ppi)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\drivers_nrf\pstorage)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\drivers_nrf\spi_master)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\drivers_nrf\timer)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\drivers_nrf\twi_master)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\drivers_nrf\uart)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\drivers_nrf\twi_master\incubated)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\libraries\bootloader_dfu)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\libraries\gpiote)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\libraries\scheduler)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\libraries\timer)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\libraries\trace)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\libraries\util)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\softdevice\s110\headers)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\softdevice\common\softdevice_handler)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\softdevice\s110\toolchain)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\toolchain\gcc)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\ble\device_manager)
INC_PATHS += -I$(abspath $(COMPONENTS_DIR)\ble\ble_services\ble_dfu)

## Application build directory
OBJECT_DIRECTORY = objects_application
LISTING_DIRECTORY = $(OBJECT_DIRECTORY)
OUTPUT_BINARY_DIRECTORY = $(OBJECT_DIRECTORY)

# Sorting removes duplicates
BUILD_DIRECTORIES := $(sort $(OBJECT_DIRECTORY) $(OUTPUT_BINARY_DIRECTORY) $(LISTING_DIRECTORY))

######################################################################################################

## Buildding application and bootloader
all: clean
	$(NO_ECHO)$(MAKE) -f $(MAKEFILE_NAME) -C $(MAKEFILE_DIR) -e cleanobj
	$(NO_ECHO)$(MAKE) -f $(MAKEFILE_NAME) -C $(MAKEFILE_DIR) -e application
	
C_SOURCE_FILE_NAMES = $(notdir $(C_SOURCE_FILES))
C_PATHS = $(call remduplicates, $(dir $(C_SOURCE_FILES) ) )
C_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(C_SOURCE_FILE_NAMES:.c=.o) )

ASM_SOURCE_FILE_NAMES = $(notdir $(ASM_SOURCE_FILES))
ASM_PATHS = $(call remduplicates, $(dir $(ASM_SOURCE_FILES) ))
ASM_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(ASM_SOURCE_FILE_NAMES:.s=.o) )

vpath %.c $(C_PATHS)
vpath %.s $(ASM_PATHS)

OBJECTS = $(C_OBJECTS) $(ASM_OBJECTS)

application: OUTPUT_FILENAME := TeepTrakApp
application: LINKER_SCRIPT=$(PROJECT_DIR)/application/config/application.ld
application: $(BUILD_DIRECTORIES) $(OBJECTS)
	@echo Linking target: $(OUTPUT_FILENAME).out
	$(NO_ECHO)$(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
	$(NO_ECHO)$(MAKE) -f $(MAKEFILE_NAME) -C $(MAKEFILE_DIR) -e finalize

## Create build directories
$(BUILD_DIRECTORIES):
	echo $(MAKEFILE_NAME)
	$(MK) $@

# Assemble files
$(OBJECT_DIRECTORY)/%.o: %.s
	@echo Compiling file: $(notdir $<)
	$(NO_ECHO)$(CC) $(ASMFLAGS) $(INC_PATHS) -c -o $@ $<

# Create objects from C SRC files
$(OBJECT_DIRECTORY)/%.o: %.c
	@echo Compiling file: $(notdir $<)
	$(NO_ECHO)$(CC) $(CFLAGS) $(INC_PATHS) -c -o $@ $<


# Link
$(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out: $(BUILD_DIRECTORIES) $(OBJECTS)
	@echo Linking target: $(OUTPUT_FILENAME).out
	$(NO_ECHO)$(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out


## Create binary .bin file from the .out file
$(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
	@echo Preparing: $(OUTPUT_FILENAME).bin
	$(NO_ECHO)$(OBJCOPY) -O binary $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin

## Create binary .hex file from the .out file
$(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
	@echo Preparing: $(OUTPUT_FILENAME).hex
	$(NO_ECHO)$(OBJCOPY) -O ihex $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex

finalize: genbin genhex echosize

genbin:
	@echo Preparing: $(OUTPUT_FILENAME).bin
	$(NO_ECHO)$(OBJCOPY) -O binary $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin

## Create binary .hex file from the .out file
genhex: 
	@echo Preparing: $(OUTPUT_FILENAME).hex
	$(NO_ECHO)$(OBJCOPY) -O ihex $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex


echosize:
	-@echo ""
	$(NO_ECHO)$(SIZE) $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex
	-@echo ""

clean:
	$(RM) $(BUILD_DIRECTORIES) $(BOOTLOADER_BUILD_DIR)

cleanobj:
	$(RM) $(BUILD_DIRECTORIES)/*.o $(BOOTLOADER_BUILD_DIR)/*.o
