# default energia software directory, check software exists
ifndef ENERGIADIR
ENERGIADIR := $(firstword $(wildcard ~/energia /usr/share/energia /opt/energia))
endif
ifeq "$(wildcard $(ENERGIADIR)/hardware/msp430/boards.txt)" ""
$(error ENERGIADIR is not set correctly; energia software not found)
endif

# default versions
ARDUINOCONST ?= 101
ENERGIACONST ?= 17

TOOLDIR := $(ENERGIADIR)/hardware/tools/lm4f/bin
COMPILER := $(TOOLDIR)/arm-none-eabi
UPLOADER := $(TOOLDIR)/cc3200prog
BOARD := cc3200
ENERGIABOARD := lpcc3200
SERIALDEV := /dev/serial/by-id/usb-FTDI_USB__-__JTAG_SWD_cc3101-if01-port0
# Compiled files output
BUILDDIR := $(CURDIR)/build
SRCDIR := $(CURDIR)
# Project name
NAME := tracker


### LOADING BOARD PARAMETERS
BOARDS_FILE := $(ENERGIADIR)/hardware/$(BOARD)/boards.txt
BOARD_BUILD_MCU 	:= $(shell sed -ne "s/$(ENERGIABOARD).build.mcu=\(.*\)/\1/p" $(BOARDS_FILE))
BOARD_BUILD_FCPU 	:= $(shell sed -ne "s/$(ENERGIABOARD).build.f_cpu=\(.*\)/\1/p" $(BOARDS_FILE))
BOARD_BUILD_VARIANT 	:= $(shell sed -ne "s/$(ENERGIABOARD).build.variant=\(.*\)/\1/p" $(BOARDS_FILE))
BOARD_UPLOAD_SPEED 	:= $(shell sed -ne "s/$(ENERGIABOARD).upload.speed=\(.*\)/\1/p" $(BOARDS_FILE))
BOARD_UPLOAD_PROTOCOL 	:= $(shell sed -ne "s/$(ENERGIABOARD).upload.protocol=\(.*\)/\1/p" $(BOARDS_FILE))
BOARD_FLASH_SIZE 	:= $(shell sed -ne "s/$(ENERGIABOARD).upload.maximum_size=\(.*\)/\1/p" $(BOARDS_FILE))
BOARD_LDSCRIPT 		:= $(shell sed -ne "s/$(ENERGIABOARD).ldscript=\(.*\)/\1/p" $(BOARDS_FILE))

### DIRECTORY STRUCTURE
ENERGIALIB := $(ENERGIADIR)/hardware/$(BOARD)/libraries
VARIANTLIB := $(ENERGIADIR)/hardware/$(BOARD)/variants/$(BOARD_BUILD_VARIANT)
COREDIR := $(ENERGIADIR)/hardware/$(BOARD)/cores/$(BOARD)
CORELIB := $(BUILDDIR)/core.a
SOURCES := $(wildcard *.c *.cc *.cpp)

# External libraries
LIBRARIES := $(foreach lib, $(filter $(notdir $(wildcard $(ENERGIALIB)/*)), \
	$(shell sed -ne "s/^ *\# *include *[<\"]\(.*\)\.h[>\"]/\1/p" $(SOURCES))), $(ENERGIALIB)/$(lib))
LIBRARIES += $(foreach lib, $(LIBRARIES), $(lib)/utility)

LIBDIRS := $(COREDIR) $(COREDIR)/driverlib $(CORELIB)/avr # This is corelib

CORELIBSOURCES := $(foreach dir, $(LIBDIRS),  $(wildcard $(addprefix $(dir)/, *.c *.cpp)))
LIBSOURCES := $(foreach dir, $(LIBRARIES),  $(wildcard $(addprefix $(dir)/, *.c *.cpp)))
SRCOBJS = $(addprefix $(BUILDDIR)/, $(notdir $(addsuffix .o, $(SOURCES) $(LIBSOURCES))))
LIBOBJS = $(addprefix $(BUILDDIR)/, $(notdir $(addsuffix .o, $(CORELIBSOURCES))))  # This is corelib
OBJECTS = $(addprefix $(BUILDDIR)/, $(notdir $(addsuffix .o, $(SOURCES) $(LIBSOURCES))))

$(info OBJS $(OBJECTS))
VPATH = $(LIBRARIES) $(LIBDIRS) $(SRCDIR) 
$(info VPATH $(VPATH))

BIN := $(BUILDDIR)/$(NAME).bin
EFI := $(BUILDDIR)/$(NAME).efi

### COMPILER OPTIONS
CC := $(COMPILER)-gcc
CXX := $(COMPILER)-g++
LD := $(COMPILER)-ld
AR := $(COMPILER)-ar
OBJCOPY := $(COMPILER)-objcopy
GDB := $(COMPILER)-gdb
SIZE := $(COMPILER)-size

CFLAGS := -c -Os -Wall -ffunction-sections -fdata-sections -mthumb
CFLAGS += -mcpu=$(BOARD_BUILD_MCU) -DF_CPU=$(BOARD_BUILD_FCPU) -MMD -DARDUINO=$(ARDUINOCONST) -DENERGIA=$(ENERGIACONST)
CXXFLAGS := -c -Os -Wall -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections -mthumb
CXXFLAGS += -mcpu=$(BOARD_BUILD_MCU) -DF_CPU=$(BOARD_BUILD_FCPU) -MMD -DARDUINO=$(ARDUINOCONST) -DENERGIA=$(ENERGIACONST)
LINKFLAGS := -Os -nostartfiles -nostdlib -Wl,--gc-sections -T$(COREDIR)/$(BOARD_LDSCRIPT) -Wl,--entry=ResetISR -mthumb -mcpu=$(BOARD_BUILD_MCU)

### INCLUDES AND LIBRARIES
INCLUDES := -I$(COREDIR) -I$(VARIANTLIB) -I$(ENERGIALIB) $(addprefix -I, $(LIBRARIES))

# default rule
.DEFAULT_GOAL := all
#_______________________________________________________________________________
#                                                                          RULES

.PHONY:	all binary upload clean boards monitor size upload_monitor

all: binary

binary: $(BIN)

upload: binary size
	@echo "Uploading to board..."
	cd $(TOOLDIR) && $(UPLOADER) $(SERIALDEV) $(BIN)

clean:
	rm -irf $(BUILDDIR) 

boards:
	@echo Available values for BOARD:
	@sed -ne '/^#/d; /^[^.]\+\.name=/p' $(BOARDS_FILE) | \
		sed -e 's/\([^.]\+\)\.name=\(.*\)/\1            \2/' \
			-e 's/\(.\{14\}\) *\(.*\)/\1 \2/'

monitor:
	@echo Escape typing ~.
	cu -s 9600 -l $(SERIALDEV)

size: $(EFI)
	$(info Binary sketch size: $(word 7, $(shell $(SIZE) $(EFI))) bytes (of a $(BOARD_FLASH_SIZE) byte maximum))

upload_monitor: upload monitor

# building the target
$(BIN): $(EFI)
	@mkdir -p $(BUILDDIR)
	$(OBJCOPY) -O binary $< $@

$(EFI): $(CORELIB) $(OBJECTS)
	@mkdir -p $(BUILDDIR)
	$(CXX) $(LINKFLAGS) $(SRCOBJS) $< -L$(BUILDDIR) -lm -lc -lgcc -o $@

$(CORELIB): $(LIBOBJS)
	@mkdir -p $(BUILDDIR)
	$(AR) rcs $@ $(LIBOBJS)

$(BUILDDIR)/%.c.o: %.c
	@mkdir -p $(BUILDDIR)
	$(CC) $(CFLAGS) $(INCLUDES) $< -o $@

$(BUILDDIR)/%.cpp.o: %.cpp
	@mkdir -p $(BUILDDIR)
	$(CXX) $(CXXFLAGS) $(INCLUDES) $< -o $@

