#   Zerocat Chipflasher --- Flash free firmware, kick the Management Engine.
#
#   Copyright (C) 2016  kai <kmx@posteo.net>
#   Copyright (C) 2016, 2017, 2018, 2020, 2021, 2022, 2023  Kai Mertens <kmx@posteo.net>
#
#   This file is part of Zerocat Chipflasher.
#
#   Zerocat Chipflasher is free software: you can redistribute it and/or
#   modify it under the terms of the GNU General Public License as
#   published by the Free Software Foundation, either version 3 of the
#   License, or (at your option) any later version.
#
#   Zerocat Chipflasher is distributed in the hope that it will be
#   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
#   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
#   General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with Zerocat Chipflasher.
#   If not, see <http://www.gnu.org/licenses/>.


#   Documentation
#   =============
#
#
#   FIXME: Those steps missing:
#
#   * propeller-load -s cmm/libfdserial.elf
#   * propeller-elf-objdump -h cmm/libfdserial.elf
#
#
#   Usage
#   -----
#
#
#       $ make help


#   Workaround for GNU Make < 4.3
#   =============================
#
#   Finalize commands within a $(shell) function with semicolon, e.g.:
#
#           $(shell echo;)


# Shell
SHELL                         := /bin/sh


# White Space
EMPTY                         :=
SPACE                         := $(EMPTY) $(EMPTY)
COMMA                         := ,
M5                            := ccccc
TAB1                          := \r\t\t\t


# Suffixes
.SUFFIXES :


# Root Paths
ROOT_HOST_START               := ../../host/start/
ROOT_FW1_SRC                  := ../src/
ROOT_FW1_START                := $(EMPTY)


# Standard Utilities
WHEREIS                       := $(shell command -v whereis;)
WHEREIS_FLAGS                 := -b
$(if $(strip $(WHEREIS)),,    $(error Cannot find whereis utility))

CAT                           := $(shell command -v cat;)
CAT_FLAGS                     :=
$(if $(strip $(CAT)),,        $(error Cannot find cat utility))

CUT                           := $(shell command -v cut;)
CUT_FLAGS                     := -d' '
$(if $(strip $(CUT)),,        $(error Cannot find cut utility))

SED                           := $(shell command -v sed;)
SED_FLAGS                     := -r
$(if $(strip $(SED)),,        $(error Cannot find sed utility))

ECHO                          := $(shell $(WHEREIS) $(WHEREIS_FLAGS) echo | $(CUT) $(CUT_FLAGS) -f2;)
ECHO_FLAGS                    := -e
$(if $(strip $(ECHO)),,       $(error Cannot find echo utility))

SLEEP                         := $(shell command -v sleep;)
SLEEP_FLAGS                   :=
$(if $(strip $(SLEEP)),,      $(error Cannot find sleep utility))


# Extra Utilities
PROPLOAD                      := $(shell command -v propeller-load;)
PROPLOAD_FLAGS                :=
$(if $(strip $(PROPLOAD)),,   $(error Cannot find propeller-load utility))


# Start Options (propeller-load)
KICK_LMM_ELF                  := $(ROOT_FW1_SRC)kick.lmm.elf
BOARD_CONFIG                  := $(ROOT_FW1_START)board.cfg
TTY_PORT                      := $(ROOT_HOST_START)tty_port_pointer
TTY_BAUDRATE                  = $(strip\
	$(shell\
		$(SED) $(SED_FLAGS)\
			-e '/^baudrate:/!d; s/^.*\: //;'\
				$(BOARD_CONFIG);\
	)\
)


# Settings
PROJECT_TITLE                 := Zerocat Chipflasher
PROJECT_BRIEF                 := Flash free firmware to BIOS chips, kick the Management Engine.
MAKEFILE_TITLE                := Load ‘kick’ to Chipflasher’s RAM or EEPROM


# Tinned Cans
define HEADER
$(strip\
	$(ECHO) $(ECHO_FLAGS)\
		"\n$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)"\
		"\n$(M5) $(PROJECT_TITLE)"\
		"\n$(M5) – $(PROJECT_BRIEF)"\
		"\n$(M5) $(MAKEFILE_TITLE)"\
		"\n$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)"\
)
endef
define HEADLINE
$(strip\
	$(ECHO) $(ECHO_FLAGS)\
		"$(M5) Process target “$@” $(M5)$(M5)"\
)
endef
define DONE
$(strip\
	$(ECHO) $(ECHO_FLAGS)\
		"... successfully processed: “$@”"\
		"\n"\
)
endef


# Built-in Special Targets
#~ .SECONDARY :                  # Uncomment for debugging
.PHONY:\
	all\
	\
	hello\
	help\
	\
	config-baud115200\
	config-baud57600\
	config-baud38400\
	\
	reset\
	kick-eeprom\
	kick-ram\
	kick-ram-terminal\
	\
	clean-config\
	clean


# Targets
#   all: same as kick-ram-terminal, with greeter
all : hello kick-ram-terminal
	@$(HEADLINE)\
	&& $(DONE);

#   Say hello, provided with all, clean and help
hello :
	@$(HEADER)\
	&& $(DONE);

#   display help information
help : hello
	@$(HEADLINE)\
	&& $(ECHO) $(ECHO_FLAGS)\
		"\nList of Targets"\
		"\n==============="\
		"\n"\
		"\nDefault Goal"\
		"\n------------"\
		"\n"\
		"\nall$(TAB1)same as kick-ram-terminal, with hello greeter"\
		"\n"\
		"\nHelp"\
		"\n----"\
		"\n"\
		"\nhello$(TAB1)greeter, provided with all, clean and help"\
		"\nhelp$(TAB1)display this help information"\
		"\n"\
		"\nConfigure"\
		"\n---------"\
		"\n"\
		"\nThese goals help you to modify ‘$(BOARD_CONFIG)’ and to set an individual baudrate:"\
		"\n"\
		"\nconfig-baud115200$(TAB1)high speed (default)"\
		"\nconfig-baud57600$(TAB1)medium speed"\
		"\nconfig-baud38400$(TAB1)low speed"\
		"\n"\
		"\nThe rate set will be used by the ‘propeller-load’ utility"\
		"\na) to patch the firmware,"\
		"\nb) to upload the firmware at the given speed."\
		"\n"\
		"\nActions"\
		"\n-------"\
		"\n"\
		"\nreset$(TAB1)reset chipflasher device"\
		"\nkick-eeprom$(TAB1)reset, send ‘kick’ to EEPROM, don't run"\
		"\nkick-ram$(TAB1)reset, send ‘kick’ to RAM and run"\
		"\nkick-ram-terminal$(TAB1)reset, send ‘kick’ to RAM, run and start a propeller-terminal"\
		"\n"\
		"\nClean"\
		"\n-----"\
		"\n"\
		"\nclean-config"\
		"\nclean"\
		"\n"\
	&& $(DONE);

config-baud115200 : $(BOARD_CONFIG)
	@$(HEADLINE)\
	&& $(SED) $(SED_FLAGS)\
		-i\
		-e 's/^baudrate/#~ baudrate/;'\
		-e's/(\#~ )(baudrate: 115200)$$/\2/;'\
			$<\
	&& $(DONE);

config-baud57600 : $(BOARD_CONFIG)
	@$(HEADLINE)\
	&& $(SED) $(SED_FLAGS)\
		-i\
		-e 's/^baudrate/#~ baudrate/;'\
		-e's/(\#~ )(baudrate: 57600)$$/\2/;'\
			$<\
	&& $(DONE);

config-baud38400 : $(BOARD_CONFIG)
	@$(HEADLINE)\
	&& $(SED) $(SED_FLAGS)\
		-i\
		-e 's/^baudrate/#~ baudrate/;'\
		-e's/(\#~ )(baudrate: 38400)$$/\2/;'\
			$<\
	&& $(DONE);

#   reset chipflasher device, trigger two times
reset : $(TTY_PORT) $(BOARD_CONFIG)
	@$(HEADLINE)\
	&& $(PROPLOAD) $(PROPLOAD_FLAGS)\
		-p $(TTY_PORT)\
		-b $(basename $(BOARD_CONFIG))\
		-v\
		-r\
		|| (\
			$(SLEEP) $(SLEEP_FLAGS)\
				4s\
			&& $(PROPLOAD) $(PROPLOAD_FLAGS)\
				-p $(TTY_PORT)\
				-b $(basename $(BOARD_CONFIG))\
				-v\
				-r\
		)\
	&& $(DONE);

#   send kick to EEPROM, don't run
kick-eeprom : $(TTY_PORT) $(BOARD_CONFIG) $(KICK_LMM_ELF) reset
	@$(HEADLINE)\
	&& $(PROPLOAD) $(PROPLOAD_FLAGS)\
		-p $(TTY_PORT)\
		-b $(basename $(BOARD_CONFIG)):default\
		$(KICK_LMM_ELF)\
		-e\
	&& $(DONE);

#   send kick to RAM and run
kick-ram : $(TTY_PORT) $(BOARD_CONFIG) $(KICK_LMM_ELF) reset
	@$(HEADLINE)\
	&& $(PROPLOAD) $(PROPLOAD_FLAGS)\
		-p $(TTY_PORT)\
		-b $(basename $(BOARD_CONFIG)):RAMstart\
		$(KICK_LMM_ELF)\
		-r\
	&& $(DONE);

#   send kick to RAM, run and start a propeller-terminal
kick-ram-terminal : $(TTY_PORT) $(BOARD_CONFIG) $(KICK_LMM_ELF) reset
	@$(HEADLINE)\
	&& $(PROPLOAD) $(PROPLOAD_FLAGS)\
		-p $(TTY_PORT)\
		-b $(basename $(BOARD_CONFIG)):terminal\
		$(KICK_LMM_ELF)\
		-r\
		-t\
		-q\
	&& $(DONE);

clean-config : config-baud115200
	@$(HEADLINE)\
	&& $(DONE);

clean : clean-config
	@$(HEADLINE)\
	&& $(DONE);
