###############################################################################
###############################################################################
#
#	Makefile für ARM7-Applikationen auf einem TMS470R1B1M Prozessor.
#
#	mögliche Konfigurationen:
#	-------------------------
#	RAM-Debug
#	RAM-Release
#	Flash-Debug
#	Flash-Release
#
#	Somit könnte ein Aufruf dieses Makefiles folgendermaßen aussehen:
#
#		make all CONFIG=RAM-Debug
#
#	Wird keine Konfiguration im Aufruf des Makefiles explizit angegeben,
#	wird RAM-Debug als Default-Konfiguration genutzt.
#
#	© Maihak AG 2006, Autor: [KB] Karsten Brandt
#
#	Hinweis: Thumb- und C++-Support sind noch in Arbeit
#
###############################################################################
###############################################################################

# Projekt-spezifische Einstellungen
###############################
TARGET	:= FlashLight_Demo
INC_DIR	:= ../include
UPLOAD	:= @../../upload/upload.exe

# initialisiere Parameter anhand der angegebenen Konfiguration
##############################################################
ifeq ($(CONFIG), )
  CONFIG			:= RAM-Debug
endif
ifeq ($(CONFIG), RAM-Debug)
  RUN_MODE			:= RUN_FROM_RAM
  USE_THUMB_MODE	:= NO
  DEBUG				:= -g
  OPTIM				:= -O0
  LDSCRIPT			:= ../system_source/TMS470R1B1M-RAM.ld
endif
ifeq ($(CONFIG), RAM-Release)
  RUN_MODE			:= RUN_FROM_RAM
  USE_THUMB_MODE	:= NO
  DEBUG				:= 
  OPTIM				:= -Os
  LDSCRIPT			:= ../system_source/TMS470R1B1M-RAM.ld
endif
ifeq ($(CONFIG), Flash-Debug)
  RUN_MODE			:= RUN_FROM_ROM
  USE_THUMB_MODE	:= NO
  DEBUG				:= -g
  OPTIM				:= -O0
  LDSCRIPT			:= ../system_source/TMS470R1B1M-ROM.ld
endif
ifeq ($(CONFIG), Flash-Release)
  RUN_MODE			:= RUN_FROM_ROM
  USE_THUMB_MODE	:= NO
  DEBUG				:= 
  OPTIM				:= -Os
  LDSCRIPT			:= ../system_source/TMS470R1B1M-ROM.ld
endif


# definiere die Tools, die für den Build-Prozess benutzt werden
###############################################################
AWK		:= awk
CC		:= @arm-elf-gcc
CPP		:= @arm-elf-c++
OBJCOPY	:= @arm-elf-objcopy
ARCH	:= @arm-elf-ar
RUBY	:= @ruby
SIZE	:= @arm-elf-size
PRINT	:= @echo
TOUCH	:= @touch
REMOVE	:= @rm -rf



# Projekt-globale Einstellungen
###############################
LINKER_MAP		:= $(TARGET).map
ELF_TARGET		:= $(TARGET).elf
HEX_TARGET		:= $(TARGET).hex
MCU				:= arm7tdmi
BINARY_FORMAT	:= ihex
JLINK_LOG		:= JLINK.log

# TMS470-spezifische Einstellungen
##################################
STARTUP_CODE	:= ../system_source/crt0.S
ifeq ($(RUN_MODE), RUN_FROM_ROM)
  LOW_LEVEL_INIT:= ../system_source/tms470r1b1m_low_level_init_flash.c 
else
  LOW_LEVEL_INIT:=
endif
SYSTEM_FILES	:= $(STARTUP_CODE) $(LOW_LEVEL_INIT)
REGMAP			:= ../system_source/reg_map.ld
IAR_HEADER		:= \
				$(INC_DIR)/intrinsic.h \
				$(INC_DIR)/io_macros.h \
				$(INC_DIR)/iotms470r1b1m.h \
				$(INC_DIR)/tms470r1b1m_bit_definitions.h
SYSTEM_SCRIPT	:= ../createMemMap/createMemMap.rb $(REGMAP)

# FLAGS für THUMB und ARM mode builds
#####################################
WARNINGS	:= \
			-Wall \
			-Wextra \
			-Wshadow \
			-Wpointer-arith \
			-Wcast-align \
			-Wsign-compare \
			-Waggregate-return \
			-Wunused

C_WARNINGS	:= \
			-Wbad-function-cast \
			-Wstrict-prototypes \
			-Wmissing-prototypes \
			-Wmissing-declarations

FLAGS		:= \
			-mcpu=$(MCU) \
			-T$(LDSCRIPT) -T$(REGMAP)\
			$(WARNINGS) \
			-D $(RUN_MODE) \
			-D GCC_ARM7 \
			-I. \
			-I.. \
			-I$(INC_DIR) \
			$(DEBUG) \
			$(OPTIM)

C_FLAGS		:=  $(FLAGS) $(C_WARNINGS)

# FLAGS nur für THUMB mode builds
#################################
ifeq ($(USE_THUMB_MODE),YES)
  C_FLAGS += \
		-mthumb-interwork \
		-D THUMB_INTERWORK \
		THUMB_FLAGS=-mthumb
endif


# LINKER-FLAGS für THUMB und ARM mode builds
############################################
LD_LIBRARY_PATH	:= C:\WinARM\arm-elf\lib
LINKER_FLAGS	:= \
				-o$(ELF_TARGET) \
				-Xlinker -M \
				-Xlinker -Map=$(LINKER_MAP) \
				-lstdc++	

# Source files that can be built to THUMB mode.
###############################################
THUMB_SRC = 

# Source files that must be built to ARM mode.
##############################################
ARM_C_SRC 	= $(wildcard *.c)
ARM_CPP_SRC = $(wildcard *.cpp)

# Definiere alle Objekt-Dateien.
################################
ARM_C_OBJ 	= $(ARM_C_SRC:.c=.o)
ARM_CPP_OBJ = $(ARM_CPP_SRC:.cpp=.o)
THUMB_C_OBJ = $(THUMB_SRC:.c=.o)
ALL_OBJECTS	= $(ARM_C_OBJ) $(ARM_CPP_OBJ) $(THUMB_C_OBJ)

# Definiere alle Abhängigkeitsdateien.
######################################
ARM_C_DEP 	= $(ARM_C_SRC:.c=.d)
ARM_CPP_DEP = $(ARM_CPP_SRC:.cpp=.d)
THUMB_C_DEP = $(THUMB_SRC:.c=.d)

# Einbinden der erzeugten Abhängigkeits- und Buildbeschreibungen (.d-Dateien)
#############################################################################
ifneq "$(MAKECMDGOALS)" "clean"
    
  ifneq ($(ARM_C_DEP), )
    -include $(ARM_C_DEP)   
  endif
  
  ifneq ($(ARM_CPP_DEP), )
    -include $(ARM_CPP_DEP)
  endif
  
  ifneq ($(THUMB_C_DEP), )
    -include $(THUMB_C_DEP)
  endif

endif

# Definiere nun die make-Target's
#################################

all : print_Config_Info \
	  map_Register 		\
	  create_hex		\
	  upload_to_target	\
	  get_size_info	

map_Register : $(IAR_HEADER) $(SYSTEM_SCRIPT)

	$(PRINT) Aktualisierung der TMS470-Register-Adressierung wird durchgeführt
	$(RUBY) $(SYSTEM_SCRIPT)
	
upload_to_target:

	$(PRINT) Upload läuft...
		
    ifeq ($(RUN_MODE), RUN_FROM_RAM)
		$(UPLOAD) -ram -elf $(ELF_TARGET) > $(JLINK_LOG)
    else # RUN_FROM_ROM
		$(UPLOAD) -flash -elf $(ELF_TARGET) > $(JLINK_LOG)
    endif

	$(PRINT) Build erfolgreich abgeschlossen!

get_size_info:

	$(PRINT) -------------------------------------------------------------------------------
	$(SIZE) --target=$(BINARY_FORMAT) $(ELF_TARGET)| \
	$(AWK) 'NR == 2 {print "Größe des .text-Segmentes   : " $$1}\
			NR == 2 {print "Größe des .data-Segmentes   : " $$2}'
	$(SIZE) --target=$(BINARY_FORMAT) -A $(ELF_TARGET)| \
	$(AWK) 'NR == 7 {print "Größe des .bss-Segmentes    : " $$2}\
			NR == 8 {print "Größe des .stack-Segmentes  : " $$2}'
	$(PRINT) -------------------------------------------------------------------------------
	$(SIZE) --target=$(BINARY_FORMAT) $(HEX_TARGET)| \
	$(AWK) 'NR == 2 {print "Gesamtgröße des Binär-Codes : " $$4}'
	$(PRINT)

create_hex : create_elf

	$(PRINT) Binär-Datei $(HEX_TARGET) wird erstellt
	$(OBJCOPY) $(ELF_TARGET) -O $(BINARY_FORMAT) $(HEX_TARGET)

create_elf : info_msg  $(LDSCRIPT) $(SYSTEM_FILES) $(ALL_OBJECTS)

	$(PRINT) Linker-Vorgang läuft...
	$(CC)  -nostartfiles $(LINKER_FLAGS) $(FLAGS) $(SYSTEM_FILES) $(ALL_OBJECTS)

$(ALL_OBJECTS) : $(ARM_C_DEP) $(ARM_CPP_DEP) $(THUMB_C_DEP)

$(THUMB_C_DEP) : %.d : %.c

	$(CC) -M $(C_FLAGS) $< > $@
	$(PRINT) "	$(PRINT)" $< >> $@
	$(PRINT) "	"$(CC)" -c $(THUMB_FLAGS) $(C_FLAGS) $< -o $(subst .d,.o,$@)" >> $@
		
$(ARM_C_DEP) : %.d : %.c

	$(CC) -M $(C_FLAGS) $< > $@
	$(PRINT) "	$(PRINT)" $< >> $@
	$(PRINT) "	"$(CC)" -c $(C_FLAGS) $< -o $(subst .d,.o,$@)" >> $@
	
$(ARM_CPP_DEP) : %.d : %.cpp

	$(CPP) -M $(FLAGS) $< > $@
	$(PRINT) "	$(PRINT)" $< >> $@
	$(PRINT) "	"$(CPP)" -c $(FLAGS) $< -o $(subst .d,.o,$@)" >> $@	
	
print_Config_Info:

	$(PRINT) -------------------------------------------------------------------------------
	$(PRINT) Konfiguration: $(TARGET) - $(RUN_MODE) - $(CONFIG)
	$(PRINT) -------------------------------------------------------------------------------
	
info_msg :

	$(PRINT) Kompilierung läuft...
	
###############################################################################
clean :

	$(PRINT)
	$(PRINT) Temporäre Dateien und Ausgabedateien für $(TARGET) werden gelöscht.
	$(TOUCH) Makefile 
	$(REMOVE) $(ARM_CPP_DEP)
	$(REMOVE) $(ARM_C_DEP)
	$(REMOVE) $(THUMB_C_DEP)
	$(REMOVE) $(ARM_CPP_OBJ)
	$(REMOVE) $(ARM_C_OBJ)
	$(REMOVE) $(THUMB_C_OBJ)
	$(REMOVE) $(LINKER_MAP)
	$(REMOVE) $(ELF_TARGET)
	$(REMOVE) $(HEX_TARGET)
	$(REMOVE) $(JLINK_LOG)

