### YTM SDK Build Makefile ###
## Define SOURCEDIR variable ##
BASEDIR:=../../SDK/
## Define CSOURCES and ASMSOURCES variables ##
# Group drivers
CSOURCES+=dma_driver.c
CSOURCES+=dma_hw_access.c
CSOURCES+=dma_irq.c
CSOURCES+=interrupt_manager.c
CSOURCES+=pins_driver.c
CSOURCES+=pins_port_hw_access.c
CSOURCES+=linflexd_uart_driver.c
CSOURCES+=linflexd_uart_irq.c
CSOURCES+=clock_YTM32B1Hx.c
CSOURCES+=sai_driver.c
CSOURCES+=i2c_driver.c
CSOURCES+=i2c_irq.c
CSOURCES+=osif_baremetal.c
CSOURCES+=printf.c
# Define two helper vars, BASEDIR (SDK base) and SOURCEDIRSDK (paths inside SDK to be included/searched)
SOURCEDIRSDK+=platform/devices
SOURCEDIRSDK+=CMSIS/Core/Include
SOURCEDIRSDK+=platform/devices/common
SOURCEDIRSDK+=platform/devices/YTM32B1HA0/startup
SOURCEDIRSDK+=platform/devices/YTM32B1HA0/include
SOURCEDIRSDK+=platform/drivers/inc
SOURCEDIRSDK+=platform/drivers/src/pins
SOURCEDIRSDK+=platform/drivers/src/dma
SOURCEDIRSDK+=platform/drivers/src/linflexd
SOURCEDIRSDK+=platform/drivers/src/clock/YTM32B1Hx
SOURCEDIRSDK+=platform/drivers/src/interrupt
SOURCEDIRSDK+=platform/drivers/src/sai
SOURCEDIRSDK+=platform/drivers/src/i2c
SOURCEDIRSDK+=rtos/osif
SOURCEDIRSDK+=utility/printf
SOURCEDIRSDK+=platform/devices/YTM32B1HA0/startup/gcc
CSOURCES+=startup.c
CSOURCES+=system_YTM32B1HA0.c
ASMSOURCES+=YTM32B1HA0_startup_gcc.S

# Location of objects and final source directories
OUTPUTDIR_NAME:=FLASH
SOURCEDIR_NAME+=.././board
SOURCEDIR_NAME+=.././src
# Group board
CSOURCES+=clock_config.c
CSOURCES+=peripherals_config.c
CSOURCES+=pin_mux.c
# Group app
CSOURCES+=main.c

# Map file names
MAP_FLASH:=$(OUTPUTDIR_NAME)/flash.map
BIN_FLASH:=$(OUTPUTDIR_NAME)/flash.bin
LST_FLASH:=$(OUTPUTDIR_NAME)/flash.lst

## Elf file names ##
EXECUTABLE_FLASH:=$(OUTPUTDIR_NAME)/flash.elf
EXECUTABLE_SREC:=$(OUTPUTDIR_NAME)/flash.srec

DEVICE:=YTM32B1HA01

## Toolchain executables ##
CC:=arm-none-eabi-gcc
AS:=arm-none-eabi-gcc
LD:=arm-none-eabi-gcc
OC:=arm-none-eabi-objcopy
OD:=arm-none-eabi-objdump
RM:=rm -f
CCSIZE:=arm-none-eabi-size
JLINK:=Jlink
JLINK_ARG:=

## Toolchain flags ##
COMFLAGS:=-mcpu=cortex-m33 -mthumb
COMFLAGS+=-mfpu=fpv5-sp-d16 -mfloat-abi=hard
COMFLAGS+=-Wall -Wextra -pedantic -save-temps=obj
COMFLAGS+=-O1
COMFLAGS+=-funsigned-char -funsigned-bitfields  -fshort-enums
COMFLAGS+=-ffunction-sections -fdata-sections -fno-jump-tables
COMFLAGS+=-g
COMFLAGS+=-DCPU_YTM32B1HA0
COMFLAGS+=-DYTM32B1HA0
COMFLAGS+=--specs=nano.specs --specs=nosys.specs
COMFLAGS+=$(MAKE_ARG)
CFLAGS:=$(COMFLAGS) -std=gnu99 -Wstrict-prototypes 
CPPFLAGS:=$(COMFLAGS)

ASFLAGS_FLASH:=-x assembler-with-cpp $(CFLAGS)
ASFLAGS_FLASH+=-DSTART_FROM_FLASH

## Linker flags
LDLIBS=$(addprefix $(BASEDIR),$(LIBRARIES))
LDFLAGS_FLASH:=-Wl,-Map=$(MAP_FLASH) $(CFLAGS) $(LDLIBS)
LDFLAGS_FLASH+=-nostartfiles -nodefaultlibs -nostdlib -T "link/YTM32B1HA01_flash.ld" --entry=Reset_Handler -Wl,-gc-sections
LDFLAGS_FLASH+=-lgcc -lm -lc 

VPATH=$(SOURCEDIR)

## Internal variables ##
OBJECTS=$(addsuffix .o, $(basename $(ASMSOURCES)))
OBJECTS+=$(CSOURCES:%.c=%.o)

SOURCEDIR=$(SOURCEDIR_NAME)/
SOURCEDIR+=$(addprefix $(BASEDIR),$(SOURCEDIRSDK))

OBJECTDIR_FLASH=$(OUTPUTDIR_NAME)/flash/
COBJECTS_FLASH=$(addprefix $(OBJECTDIR_FLASH),$(OBJECTS))
INCLUDES=$(addprefix -I,$(SOURCEDIR))

SEPARATOR=======================================================================

## Testing to check whether it is a Windows environment or an Unix like
## one. This test is based on 'uname' command call. If the shell is a Windows one
## with no GNU binutils or similar tools, the command will raise a CreateProcess
## error but the makefile will detect the correct environment and work as expected.

UNAME_CMD:=uname
OS_DETECTED:=$(shell $(UNAME_CMD))

ifeq ($(OS_DETECTED), )
	#CC_SEARCH:=where $(CC)
	mkdir=mkdir_windows
	clean_target=clean_windows
	env_predetection_msg=Checked for '$(UNAME_CMD)', not found
	env_detected_msg=Assuming Windows environment
else
	#CC_SEARCH:=where $(CC)
	mkdir=mkdir_linux
	clean_target=clean_linux
	env_predetection_msg=Checked for '$(UNAME_CMD)', found: $(OS_DETECTED)
	env_detected_msg=Assuming Unix like environment
endif

## Testing to check if the toolchain is correct
CC_DETECTED:=$(shell $(CC_SEARCH))

## Retrieving sysroot path
CC_LIB_PATH:=$(shell $(CC) --print-sysroot)
CFLAGS+=--sysroot "$(CC_LIB_PATH)/newlib"
LDFLAGS_FLASH+=--sysroot "$(CC_LIB_PATH)/newlib"

mkdir_message:=Creating directory for object files
clean_message:=Removing files and directories

## Targets ##
.DEFAULT_GOAL := all

## Targets ##

mkdir_windows:
	@echo $(SEPARATOR)
	@echo $(mkdir_message)
	@mkdir $(OBJECTDIR_FLASH) || @echo Directory already exists
		
mkdir_linux:
	@echo $(SEPARATOR)
	@echo $(mkdir_message)
	@mkdir -p $(OUTPUTDIR_NAME)
	@mkdir -p $(OBJECTDIR_FLASH)

clean_windows:
	@echo $(SEPARATOR)
	@echo $(clean_message)
	@del /q  $(OBJECTDIR_NAME_FLASH)\*.* $(EXECUTABLE_FLASH) $(MAP_FLASH)
	@rmdir /s /q $(OUTPUTDIR_NAME)
	
clean_linux:
	@echo $(SEPARATOR)
	@echo $(clean_message)
	@rm -rf $(EXECUTABLE_FLASH) $(MAP_FLASH)
	@rm -rf $(OUTPUTDIR_NAME)
	
print_env:
	@echo $(SEPARATOR)
	@echo $(env_predetection_msg)
	@echo $(env_detected_msg)

all: print_env $(mkdir) $(EXECUTABLE_FLASH) build_complete


# Target used to compile C source files - FLASH target
-include $(OBJECTDIR_FLASH)*.d
$(OBJECTDIR_FLASH)%.o: %.c
	@echo $(SEPARATOR)	
	@echo Compiling $@
	@mkdir -p $(dir $@)
	@$(CC) $(CFLAGS) $(INCLUDES) -c -MMD $< -o $@

# Target used to compile assembler files - FLASH target
$(OBJECTDIR_FLASH)%.o: %.s
	@echo $(SEPARATOR)
	@echo Compiling $@
	@mkdir -p $(dir $@)
	@$(AS) $(ASFLAGS_FLASH) $(INCLUDES) -c $< -o $@

# Target used to compile assembler files - FLASH target
$(OBJECTDIR_FLASH)%.o: %.S
	@echo $(SEPARATOR)
	@echo Compiling $@
	@mkdir -p $(dir $@)
	@$(AS) $(ASFLAGS_FLASH) $(INCLUDES) -c $< -o $@

$(EXECUTABLE_FLASH): $(COBJECTS_FLASH)
	@echo $(SEPARATOR)
	@echo Linking to $(EXECUTABLE_FLASH)
	@$(LD) -o $(EXECUTABLE_FLASH) $(COBJECTS_FLASH) $(LDFLAGS_FLASH)
	@$(OC) -O binary $(EXECUTABLE_FLASH) $(BIN_FLASH)
	@$(OD) -h -S $(EXECUTABLE_FLASH) > $(LST_FLASH)
	@$(OC) -O srec $(EXECUTABLE_FLASH) $(OUTPUTDIR_NAME)/flash.srec
	@$(CCSIZE) $(EXECUTABLE_FLASH)

# Target used to create folder used to store temporary objects
mkdir:
	@mkdir $(OBJECTDIR_NAME) || @echo -

# Target used to print executables sizes
size:
	@$(CCSIZE) $(EXECUTABLE_FLASH)

# Target used to print compile informations
print:
	@echo Compile options: $(CFLAGS) $(ASFLAGS) $(INCLUDES)

build_complete:
	@echo $(SEPARATOR)
	@echo Build complete!

download: $(EXECUTABLE_FLASH)
	@echo -e "con\nloadfile $(OUTPUTDIR_NAME)/flash.srec\nr\ng\nqc" > $(OUTPUTDIR_NAME)/download.jlinkscript
	@$(JLINK) -if swd -speed 4000 -device $(DEVICE) $(JLINK_ARG) -commanderscript $(OUTPUTDIR_NAME)/download.jlinkscript
	
# Target used to remove files and folders
clean: print_env $(clean_target)
	

.PHONY: all size print clean