#################################################
# MAKEFILE For STM32F4xxx Devices 				#
# (c) 20111016 Nemui Trinomius					#
# http://nemuisan.blog.bai.ne.jp				#
# Based on Martin Thomas's makefiles thanks!	#
#################################################

# Environment Dependent!!! This environment assure under WINDOWS !!
# Throw path into YOUR environments
#export PATH = %SYSTEMROOT%;$(TOOLDIR)/arm-gcc/bin;$(TOOLDIR)/bin;$(MAKEDIR);$(OCDIR);$(DFUDIR)

# Toolchain prefix (i.e arm-elf -> arm-elf-gcc.exe)
TCHAIN  = arm-none-eabi
#OCD		= openocd
#OCDMODE = SWD
#OCDMODE = JTAG

# Development Tools based on CodeSourceryG++
#DEVTOOL = NETX
DEVTOOL = SOURCERY

#ifeq ($(DEVTOOL),NETX)
#TOOLDIR = C:/Devz/ARM/NetX
#REMOVAL = rm
#else
TOOLDIR = C:/Programme/CodeSourcery/Sourcery G++ Lite
REMOVAL = cs-rm
#endif

MAKEDIR = C:/WinAVR-20100110/utils/bin
#OCDIR	= C:/Devz/ARM/OCD
#ifeq ($(OCDMODE),SWD)
#OCD_CMD = -s $(OCDIR)/tcl					\
#		  -f interface/vsllink_swd.cfg		\
#          -f target/stm32f4x_flash.cfg
#else
#OCD_CMD = -s $(OCDIR)/tcl					\
#		  -f interface/jtagkey2.cfg 		\
#          -f target/stm32f4x_flash.cfg
#endif

#DFUDIR	= C:/Devz/ARM/ST/DFUse/BIN
		  
WSHELL  = cmd
MSGECHO = echo.exe
#GDBDIR  = C:/Devz/ARM/insight/bin
#INSIGHT = $(GDBDIR)/arm-none-eabi-insight
# Environment Dependent!!!


# OPTIMIZE Definition
#OPTIMIZE		= 2
#OPTIMIZE		= 0
OPTIMIZE		= s

# FPU Definition
USING_FPU		= -mfloat-abi=softfp  -mfpu=fpv4-sp-d16
#USING_FPU		= -mfloat-abi=soft

# GCC4.5.x Specific Option
#USE_LTO			= -flto -fipa-sra
#ALIGNED_ACCESS	= -mno-unaligned-access

# Apprication Version
APP_VER = LwIP140_V000


# Basic definition
#EVAL_BOARD    	= USE_REDBULL
EVAL_BOARD    	= USE_STM32F4DISCOVERY

ifeq ($(EVAL_BOARD),USE_STM32F4DISCOVERY)
SUBMODEL		= STM32F407VGT6
else
SUBMODEL		= STM32F407ZGT6
endif
MPU_DENSITY		= STM32F4XX
HSE_CLOCK 		= 8000000
PERIF_DRIVER    = USE_STDPERIPH_DRIVER

#LwIP definition
IPVx			= IPV4
#IPVx			= IPV6

# Synthesis makefile Defines
DEFZ = $(EVAL_BOARD)  $(MPU_DENSITY)  $(PERIF_DRIVER) $(VECTOR_START) $(ROM_START)		\
	   $(SUBMODEL) 

SYNTHESIS_DEFS	= $(addprefix -D,$(DEFZ)) 							\
				 -DMPU_SUBMODEL=\"$(SUBMODEL)\"						\
				 -DAPP_VERSION=\"$(APP_VER)\"						\
				 -DHSE_VALUE=$(HSE_CLOCK)UL 						
#DELforLwIP				 -DALIGN_STRUCT_END=__attribute\(\(aligned\(4\)\)\) \
#DELforLwIP				 -DPACK_STRUCT_END=__attribute\(\(packed\)\) 		\

# TARGET definition
TARGET 		= main
TARGET_ELF  = $(TARGET).elf
TARGET_SREC = $(TARGET).s19
TARGET_HEX  = $(TARGET).hex
TARGET_BIN  = $(TARGET).bin
TARGET_LSS  = $(TARGET).lss
TARGET_SYM  = $(TARGET).sym

# define Cortex-M4 LIBRARY PATH
FWLIB  		= ./lib/STM32F4xx_StdPeriph_Driver
USBLIB 		= 
CM4LIB 		= ./lib/CMSIS
CM4_DEVICE 	= $(CM4LIB)/ST/STM32F4xx
CM4_CORE	= $(CM4LIB)/Include
FWUTL  		= ./lib/Utilities/STM32F4-Discovery
LWIP_DIR		= ./lib/lwip-1.4.0
LWIP_PORT_DIR	= ./lib/lwip-1.4.0-port

# include PATH
INCPATHS	 = 	./						\
				./inc					\
				$(FWLIB)/inc  			\
				$(USBLIB)/inc			\
				$(CM4_DEVICE)/Include	\
				$(CM4_CORE)				\
				$(FWUTL)				\
				$(LWIP_PORT_DIR)		\
				$(LWIP_DIR)/src/include		
ifeq ($(IPVx),IPV4)
 INCPATHS	+= 	$(LWIP_DIR)/src/include/ipv4			
else
 INCPATHS	+= 	$(LWIP_DIR)/src/include/ipv6			
endif
INCPATHS	+= 	$(LWIP_PORT_DIR)/app				
INCPATHS	+= 	$(LWIP_PORT_DIR)/arch				
INCPATHS	+= 	$(LWIP_PORT_DIR)/ENC28J60			
INCPATHS	+= 	$(LWIP_PORT_DIR)/netif			

INCLUDES     = $(addprefix -I ,$(INCPATHS))

# Set library PATH
LIBPATHS     = $(FWLIB) $(USBLIB) $(CM4LIB) 
LIBRARY_DIRS = $(addprefix -L,$(LIBPATHS))
# if you use math-library, put "-lm" 
MATH_LIB	 =	-lm

# LinkerScript PATH
LINKER_PATH =  ./lib/linker
LINKER_DIRS = $(addprefix -L,$(LINKER_PATH)) 

# Object definition
OBJS 	 = $(CFILES:%.c=%.o) 
LIBOBJS  = $(LIBCFILES:%.c=%.o) $(SFILES:%.s=%.o)

# C code PATH
SOURCE  = ./src
CFILES = \
 $(SOURCE)/$(TARGET).c 					\
 $(SOURCE)/EvalBord.c                   \
 $(SOURCE)/hw_config.c					\
 $(SOURCE)/monitor.c					\
 $(SOURCE)/stm32f4xx_it.c				\
 $(SOURCE)/syscalls.c					\
 $(SOURCE)/system_stm32f4xx.c			\
 $(SOURCE)/systick.c					\
 $(SOURCE)/term_io.c					\
 $(SOURCE)/uart_support.c				\
 $(SOURCE)/netconf.c					

 #/*----- STARTUP code PATH -----*/
STARTUP_DIR = $(CM4_DEVICE)/Source/Templates/gcc_ride7
SFILES += \
	$(STARTUP_DIR)/startup_stm32f4xx.s

#/*----- STM32 library PATH -----*/
LIBCFILES = \
 $(FWLIB)/src/misc.c \
 $(FWLIB)/src/stm32f4xx_flash.c 	\
 $(FWLIB)/src/stm32f4xx_gpio.c 		\
 $(FWLIB)/src/stm32f4xx_fsmc.c 		\
 $(FWLIB)/src/stm32f4xx_rcc.c 		\
 $(FWLIB)/src/stm32f4xx_adc.c 		\
 $(FWLIB)/src/stm32f4xx_dma.c 		\
 $(FWLIB)/src/stm32f4xx_tim.c 		\
 $(FWLIB)/src/stm32f4xx_rtc.c 		\
 $(FWLIB)/src/stm32f4xx_sdio.c 		\
 $(FWLIB)/src/stm32f4xx_spi.c 		\
 $(FWLIB)/src/stm32f4xx_usart.c 	\
 $(FWLIB)/src/stm32f4xx_pwr.c 		\
 ./src/system_stm32f4xx.c
 
LIBCFILES += \
 $(FWUTL)/stm32f4_discovery.c			\
 $(FWUTL)/stm32f4_discovery_audio_codec.c	
LIBCFILES += \
 $(LWIP_PORT_DIR)/netif/ethernetif_enc28j60.c		\
 $(LWIP_PORT_DIR)/app/helloworld.c				\
 $(LWIP_PORT_DIR)/app/httpd1.c						

LIBCFILES += $(wildcard $(LWIP_DIR)/src/core/*.c)
LIBCFILES += $(wildcard $(LWIP_DIR)/src/core/snmp/*.c)
LIBCFILES += $(wildcard $(LWIP_DIR)/src/api/*.c)

ifeq ($(IPVx),IPV4)
 LIBCFILES += $(wildcard $(LWIP_DIR)/src/core/ipv4/*.c)
else
 LIBCFILES += $(wildcard $(LWIP_DIR)/src/core/ipv6/*.c)
endif

LIBCFILES += \
 $(LWIP_DIR)/src/netif/etharp.c			\
 $(LWIP_DIR)/src/netif/slipif.c			

LIBCFILES += \
 $(LWIP_PORT_DIR)/ENC28J60/enc28j60.c				\
 $(LWIP_PORT_DIR)/ENC28J60/spi_enc28j60.c			
 


# TOOLCHAIN SETTING
CC 			= $(TCHAIN)-gcc
CPP 		= $(TCHAIN)-g++
OBJCOPY 	= $(TCHAIN)-objcopy
OBJDUMP 	= $(TCHAIN)-objdump
SIZE 		= $(TCHAIN)-size
AR 			= $(TCHAIN)-ar
LD 			= $(TCHAIN)-gcc
NM 			= $(TCHAIN)-nm
REMOVE		= $(REMOVAL) -f
REMOVEDIR 	= $(REMOVAL) -rf

# C and ASM FLAGS
CFLAGS  = -MD -mcpu=cortex-m4 -march=armv7e-m -mtune=cortex-m4
CFLAGS += -mthumb -mlittle-endian $(ALIGNED_ACCESS)
CFLAGS += -mapcs-frame -mno-sched-prolog $(USING_FPU)
CFLAGS += -std=gnu99
CFLAGS += -gdwarf-2 -O$(OPTIMIZE) $(USE_LTO)
CFLAGS += -fno-strict-aliasing -fsigned-char
CFLAGS += -ffunction-sections -fdata-sections
CFLAGS += -fno-schedule-insns2
CFLAGS += --param max-inline-insns-single=1000
CFLAGS += -fno-common -fno-hosted
CFLAGS += -Wall
#CFLAGS += -Wdouble-promotion
#CFLAGS += -Wredundant-decls -Wreturn-type -Wshadow -Wunused
CFLAGS += -Wa,-adhlns=$(subst $(suffix $<),.lst,$<) 
CFLAGS += $(SYNTHESIS_DEFS)  

# Linker FLAGS -mfloat-abi=softfp -msoft-float
LDFLAGS  = -mcpu=cortex-m4 -march=armv7e-m -mthumb
LDFLAGS += -u g_pfnVectors -Wl,-static -Wl,--gc-sections -nostartfiles
LDFLAGS += -Wl,-Map=$(TARGET).map
LDFLAGS += $(LIBRARY_DIRS) $(LINKER_DIRS) $(MATH_LIB)

ifeq ($(USE_EXT_SRAM),DATA_IN_ExtSRAM)
LDFLAGS +=-T$(LINKER_PATH)/$(MPU_DENSITY)_EXTRAM.ld
else
LDFLAGS +=-T$(LINKER_PATH)/$(MPU_DENSITY).ld
endif

# Object Copy and dfu generation FLAGS
OBJCPFLAGS = -O
OBJDUMPFLAGS = -h -S -C
DFU	  = hex2dfu
DFLAGS = -w
 

# Object Size Infomations
ELFSIZE = $(SIZE) -A -x $(TARGET).elf
sizeafter:
	@$(MSGECHO) 
	@$(MSGECHO) Size After:
	$(SIZE) $(TARGET).elf
	@$(SIZE) -A -x $(TARGET).elf
	
# Display compiler version information.
gccversion : 
	@$(CC) --version
	@$(MSGECHO) "BUILD_TYPE = "$(OS_SUPPORT)
	@$(MSGECHO) "USING_DISPLAY = "$(USE_DISPLAY)
	@$(MSGECHO) 

# Build Object
all: gccversion clean build sizeafter
build: $(TARGET_ELF) $(TARGET_LSS) $(TARGET_SYM) $(TARGET_HEX) $(TARGET_SREC) $(TARGET_BIN)

.SUFFIXES: .o .c .s   

$(TARGET_LSS): $(TARGET_ELF)
	@$(MSGECHO)
	@$(MSGECHO) Disassemble: $@
	$(OBJDUMP) $(OBJDUMPFLAGS) $< > $@ 
$(TARGET_SYM): $(TARGET_ELF)
	@$(MSGECHO)
	@$(MSGECHO) Symbol: $@
	$(NM) -n $< > $@
$(TARGET).hex: $(TARGET).elf
	@$(MSGECHO)
	@$(MSGECHO) Objcopy: $@
	$(OBJCOPY) $(OBJCPFLAGS) ihex $^ $@    
$(TARGET).s19: $(TARGET).elf
	@$(MSGECHO)
	@$(MSGECHO) Objcopy: $@
	$(OBJCOPY) $(OBJCPFLAGS) srec $^ $@ 
$(TARGET).bin: $(TARGET).elf
	@$(MSGECHO)
	@$(MSGECHO) Objcopy: $@
	$(OBJCOPY) $(OBJCPFLAGS) binary $< $@ 
#$(TARGET).dfu: $(TARGET).hex
#	@$(MSGECHO)
#	@$(MSGECHO) Make STM32 dfu: $@
#	$(DFU) $(DFLAGS) $< $@
#	@$(MSGECHO)

#$(TARGET).elf: $(OBJS) stm32.a 
$(TARGET).elf: $(OBJS) stm32.a $(AFILES)
	@$(MSGECHO) Link: $@
	$(LD) $(CFLAGS) $(LDFLAGS) $^ -o $@
	@$(MSGECHO)

stm32.a: $(LIBOBJS)
	@$(MSGECHO) Archive: $@
	$(AR) cr $@ $(LIBOBJS)    
	@$(MSGECHO)
.c.o:
	@$(MSGECHO) Compile: $<
	$(CC) -c $(CFLAGS) $(INCLUDES) $< -o $@
	@$(MSGECHO)
.s.o:
	@$(MSGECHO) Assemble: $<
	$(CC) -c $(CFLAGS) $(INCLUDES) $< -o $@
	@$(MSGECHO)

# Flash and Debug Program
#debug :
#	$(WSHELL) /c start /B $(INSIGHT) $(TARGET).elf
#	$(OCD) $(OCD_CMD) -c "soft_reset_halt"
#program :
#	$(OCD) $(OCD_CMD) -c "mt_flash $(TARGET).elf"
##	$(OCD) $(OCD_CMD) -c "eraser"
##	$(OCD) $(OCD_CMD) -c "mt_flash_bin $(TARGET).bin 0x08000000"


# Drop files into dust-shoot
.PHONY clean:
	$(REMOVE) $(TARGET).hex
	$(REMOVE) $(TARGET).bin
	$(REMOVE) $(TARGET).obj
	$(REMOVE) stm32.a
	$(REMOVE) $(TARGET).elf
	$(REMOVE) $(TARGET).map
	$(REMOVE) $(TARGET).s19
	$(REMOVE) $(TARGET).obj
	$(REMOVE) $(TARGET).a90
	$(REMOVE) $(TARGET).sym
	$(REMOVE) $(TARGET).lnk
	$(REMOVE) $(TARGET).lss
	$(REMOVE) $(TARGET).dfu
	$(REMOVE) $(wildcard *.stackdump)
	$(REMOVE) $(OBJS)
	$(REMOVE) $(AOBJ)
	$(REMOVE) $(LIBOBJS)
	$(REMOVE) $(LST)
	$(REMOVE) $(CFILES:.c=.lst)
	$(REMOVE) $(CFILES:.c=.d)
	$(REMOVE) $(LIBCFILES:.c=.lst)
	$(REMOVE) $(LIBCFILES:.c=.d)
	$(REMOVE) $(SFILES:.s=.lst)
	$(REMOVE) $(wildcard ./lib/IOView/*.d)
	$(REMOVE) $(wildcard ./lib/IOView/*.lst)
	$(REMOVE) $(wildcard ./lib/IOView/*.o)
	$(REMOVE) $(wildcard $(DISPLAY_DRV_SRC)/*.d)
	$(REMOVE) $(wildcard $(DISPLAY_DRV_SRC)/*.lst)
	$(REMOVE) $(wildcard $(DISPLAY_DRV_SRC)/*.o)
	$(REMOVE) $(wildcard $(CM4_DEVICE)/*.d)
	$(REMOVE) $(wildcard $(CM4_DEVICE)/*.lst)
	$(REMOVEDIR) .dep
	@$(MSGECHO)

# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion \
build elf hex bin lss sym clean clean_list program
