#   Zerocat Chipflasher --- Flash free firmware, kick the Management Engine.
#
#   Copyright (C) 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
#   =============
#
#
#   Brief
#   -----
#
#
#   Build the chipflasher’s new firmware: `kick2`


#   Workaround for buggy 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                            := xxxxx
TAB1                          := \r\t\t
TAB2                          := \r\t\t\t
TAB3                          := \r\t\t\t\t
TOKEN_DISABLE                 := $(EMPTY)"'~ \# "$(EMPTY)
TOKEN_ENABLE                  := $(EMPTY)"\# \t "$(EMPTY)


# Suffixes
.SUFFIXES :
.SUFFIXES : .spin .txt .html


# Root Paths
ROOT_FW2_DOC                  := ../../firmware2/doc/
ROOT_FW2_SRC                  := ../../firmware2/src/


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

CP                            := $(shell command -v cp;)
CP_FLAGS                      :=
$(if $(strip $(CP)),,         $(error Cannot find cp utility))

MV                            := $(shell command -v mv;)
MV_FLAGS                      :=
$(if $(strip $(MV)),,         $(error Cannot find mv utility))

RM                            := $(shell command -v rm;)
RM_FLAGS                      := -f
$(if $(strip $(RM)),,         $(error Cannot find rm 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))

GIT                           := $(shell command -v git;)
GIT_FLAGS                     :=
$(if $(strip $(GIT)),,        $(error Cannot find git utility))

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

SET                           := $(shell command -v set;)
SET_FLAGS                     := -f
$(if $(strip $(SET)),,        $(error Cannot find set utility))

DATE                          := $(shell command -v date;)
DATE_FLAGS                    := -R
$(if $(strip $(DATE)),,       $(error Cannot find date utility))

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

LESS                          := $(shell command -v less;)
LESS_FLAGS                    := -e -N
$(if $(strip $(LESS)),,       $(error Cannot find less utility))

MKTEMP                        := $(shell command -v mktemp;)
MKTEMP_FLAGS                  :=
$(if $(strip $(MKTEMP)),,     $(error Cannot find mktemp utility))


# Extra Utilities
OPENSPIN                      := $(shell command -v openspin;)
OPENSPIN_FLAGS                :=
$(if $(strip $(OPENSPIN)),,   $(error Cannot find openspin utility))


# Files
FAVICON                       := $(ROOT_FW2_DOC)favicon
SPIN_KICK2                    := kick2.spin
SOURCES_SPIN                  := $(strip\
	$(addprefix $(ROOT_FW2_SRC),$(notdir $(shell\
		$(OPENSPIN) $(OPENSPIN_FLAGS)\
			-f\
				$(SPIN_KICK2);\
	)))\
)
SPIN_PINS                     := pins.spin
SPIN_PCCOM                    := pccom.spin
SPIN_MENU                     := menu.spin
OUT                           := $(subst .spin,,$(SPIN_KICK2))
BOARD_CONFIG                  := $(ROOT_FW2_START)board.cfg


# Settings
PROJECT_TITLE                 := Zerocat Chipflasher
PROJECT_BRIEF                 := Flash free firmware to BIOS chips, kick the Management Engine.
MAKEFILE_TITLE                := Build ‘kick2’, the second firmware, and provide compiled documentation output.
PROJECT_REPO                  := git://zerocat.org/zerocat/projects/chipflasher
PROJECT_NUMBER                := $(strip\
	$(shell\
		$(SET) $(SET_FLAGS);\
		$(GIT) $(GIT_FLAGS)\
			describe\
				--match v* |\
		$(SED) $(SED_FLAGS)\
			-e 's/(.*)(-g)([0-9a-f]*)/\1-\3/;'\
				-;\
	)\
)
PROJECT_BRANCH                := $(strip\
	$(shell\
		$(GIT) $(GIT_FLAGS)\
			branch |\
		$(SED) $(SED_FLAGS)\
			-e '/^\*/!d; s/^\* //;'\
				-;\
	)\
)
TTY_BAUDRATE                  = $(strip\
	$(shell\
		$(SED) $(SED_FLAGS)\
			-e '/^baudrate:/!d; s/^.*\: //;'\
				$(BOARD_CONFIG);\
	)\
)
KICK2_INTERFACE               := $(strip\
	$(shell\
		ifc=$$(\
			$(SED) $(SED_FLAGS)\
				-e '/^\#[ \t]*define[ \t]*_CFG/!d; s/^.*_CFG_//; y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;'\
					$(SPIN_KICK2)\
		)\
		&& if [ -z "$$ifc" ];\
			then\
				$(ECHO) $(ECHO_FLAGS) nointerface;\
			else\
				$(ECHO) $(ECHO_FLAGS) $$ifc;\
			fi;\
	)\
)
IFC_CONFIG                    := 0
ifeq ($(KICK2_INTERFACE),connect)
	IFC_CONFIG                    := 1
endif
ifeq ($(KICK2_INTERFACE),terminal)
	IFC_CONFIG                    := 1
endif
ifeq ($(KICK2_INTERFACE),flashrom)
	IFC_CONFIG                    := 2
endif
ifeq ($(KICK2_INTERFACE),nointerface)
	IFC_CONFIG                    := 3
endif


# 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) – $(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
define NAVBAR
$(strip\
	$(ECHO) $(ECHO_FLAGS)\
		"    <div class=\"navbar-container\">"\
		"\n      <a id=\"$${id}\"></a>"\
		"\n      <div class=\"navbar\">"\
		"\n        <div>"\
		"\n          <a href=\"$(ROOT_FW2_DOC)index.html\"><button type=\"button\">Back</button></a>"\
		"\n          <div>"\
		"\n          </div>"\
		"\n        </div>"\
		"\n      </div>"\
		"\n    </div>"\
			>> $@\
)
endef


# Built-in Special Targets
#~ .SECONDARY :                  # Uncomment for debugging
.PHONY :\
	all\
	\
	hello\
	help\
	symbols\
	review\
	files\
	tree\
	docs\
	\
	html\
	\
	config-connect\
	config-flashrom\
	config-propterm\
	config-nointerface\
	\
	config-baud115200\
	config-baud57600\
	config-baud38400\
	\
	config-SPI_CLOCK100\
	config-SPI_CLOCK75\
	config-SPI_CLOCK50\
	config-SPI_CLOCK25\
	config-SPI_CLOCK_DIPSW
	config-SPI_MODE0\
	config-SPI_MODE3\
	config-SPI_MODE_DIPSW\
	config-RS232_BAUD115200\
	config-RS232_BAUD57600\
	config-RS232_BAUD38400\
	config-SUSPEND_ALLOW\
	config-SUSPEND_INHIBIT\
	config-SUSPEND_DIPSW\
	config-PWRUP_ONCE\
	config-PWRUP_REPETITIVE\
	config-PWRUP_DIPSW\
	\
	clean-config
	clean-docs\
	clean


# Targets
#   all: greet and build the firmware
all : hello $(OUT)
	@$(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$(TAB2)same as $(OUT), with greeter"\
		"\n"\
		"\nHelp Options"\
		"\n------------"\
		"\n"\
		"\nhello$(TAB2)greeter, provided with all, clean and help"\
		"\nhelp$(TAB2)display this help information"\
		"\ndoc$(TAB2)dump doc output mode"\
		"\ntree$(TAB2)list project’s object tree"\
		"\nfiles$(TAB2)list spin files in use"\
		"\nsymbol$(TAB2)dump PUB & CON symbol information"\
		"\nreview$(TAB2)review dumped doc output"\
		"\n"\
		"\nConfigure"\
		"\n---------"\
		"\n"\
		"\n### Interface Options"\
		"\n"\
		"\nconfig-connect$(TAB2)enable interface to ‘connect’ utility (default)"\
		"\nconfig-flashrom$(TAB2)enable interface to ‘flashrom’"\
		"\nconfig-propterm$(TAB2)enable interface to propeller-terminal"\
		"\nconfig-nointerface$(TAB2)disable any interface"\
		"\n"\
		"\n### Options for Interfaces to ‘connect’ or ‘terminal’"\
		"\n"\
		"\nconfig-baud115200$(TAB2)high speed (default)"\
		"\nconfig-baud57600$(TAB2)medium speed"\
		"\nconfig-baud38400$(TAB2)low speed"\
		"\n"\
		"\n### Options for Interface to ‘flashrom’"\
		"\n"\
		"\nconfig-RS232_BAUD115200$(TAB3)configure interface to ‘flashrom’ to use a fast baudrate (default)"\
		"\nconfig-RS232_BAUD57600$(TAB3)configure interface to ‘flashrom’ to use a medium baudrate"\
		"\nconfig-RS232_BAUD38400$(TAB3)configure interface to ‘flashrom’ to use a slow baudrate"\
		"\nconfig-SPI_MODE3$(TAB3)configure interface to ‘flashrom’ to use SPI Mode 3"\
		"\nconfig-SPI_MODE0$(TAB3)configure interface to ‘flashrom’ to use SPI Mode 0"\
		"\nconfig-SPI_MODE_DIPSW$(TAB3)configure interface to ‘flashrom’ to use SPI Mode according to DIP Switch (default)"\
		"\nconfig-SUSPEND_ALLOW$(TAB3)configure interface to ‘flashrom’ to suspend Vcc_SPI if required"\
		"\nconfig-SUSPEND_INHIBIT$(TAB3)configure interface to ‘flashrom’ to power Vcc_SPI without interruption"\
		"\nconfig-SUSPEND_DIPSW$(TAB3)configure interface to ‘flashrom’ to power Vcc_SPI according to DIP Switch (default)"\
		"\nconfig-PWRUP_ONCE$(TAB3)configure interface to ‘flashrom’ to use one SPI Power-up Pulse"\
		"\nconfig-PWRUP_REPETITIVE$(TAB3)configure interface to ‘flashrom’ to repeat a SPI Power-up Pulse"\
		"\nconfig-PWRUP_DIPSW$(TAB3)configure interface to ‘flashrom’ to use SPI Power-up Pulses according to DIP Switch (default)"\
		"\nconfig-SPI_CLOCK100$(TAB3)configure interface to ‘flashrom’ to use 100% SPI clock driver strength"\
		"\nconfig-SPI_CLOCK75$(TAB3)configure interface to ‘flashrom’ to use 75% SPI clock driver strength"\
		"\nconfig-SPI_CLOCK50$(TAB3)configure interface to ‘flashrom’ to use 50% SPI clock driver strength"\
		"\nconfig-SPI_CLOCK25$(TAB3)configure interface to ‘flashrom’ to use 25% SPI clock driver strength"\
		"\nconfig-SPI_CLOCK_DIPSW$(TAB3)configure interface to ‘flashrom’ to use SPI clock driver strength according to DIP Switch (default)"\
		"\n"\
		"\nCompile"\
		"\n-------"\
		"\n"\
		"\nhtml$(TAB2)generate html documentation"\
		"\n$(OUT)$(TAB2)build the firmware, provide ‘$(OUT)’ and ‘$(OUT).eeprom’"\
		"\n"\
		"\nClean Options"\
		"\n-------------"\
		"\n"\
		"\nclean-config$(TAB2)reset configuration"\
		"\nclean-doc$(TAB2)remove generated documentation files"\
		"\nclean$(TAB2)make folders clean"\
		"\n"\
	&& $(DONE);

config-baud115200 : $(filter %$(SPIN_PINS) %$(SPIN_PCCOM),$(SOURCES_SPIN))
	@$(HEADLINE)\
	&& if [ "$(KICK2_INTERFACE)" = "connect" -o "$(KICK2_INTERFACE)" = "terminal" ];\
		then\
			for i in $^;\
				do\
					$(SED) $(SED_FLAGS)\
						--in-place\
						-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_BAUDRATE.*)/"$(TOKEN_DISABLE)"\2/;"\
						-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_BAUDRATE_$(subst config-baud,,$@))/"$(TOKEN_ENABLE)"\2/;"\
							$$i;\
				done;\
		fi\
	&& $(DONE);

config-baud57600 : $(filter %$(SPIN_PINS) %$(SPIN_PCCOM),$(SOURCES_SPIN))
	@$(HEADLINE)\
	&& if [ "$(KICK2_INTERFACE)" = "connect" -o "$(KICK2_INTERFACE)" = "terminal" ];\
		then\
			for i in $^;\
				do\
					$(SED) $(SED_FLAGS)\
						--in-place\
						-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_BAUDRATE.*)/"$(TOKEN_DISABLE)"\2/;"\
						-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_BAUDRATE_$(subst config-baud,,$@))/"$(TOKEN_ENABLE)"\2/;"\
							$$i;\
				done;\
		fi\
	&& $(DONE);

config-baud38400 : $(filter %$(SPIN_PINS) %$(SPIN_PCCOM),$(SOURCES_SPIN))
	@$(HEADLINE)\
	&& if [ "$(KICK2_INTERFACE)" = "connect" -o "$(KICK2_INTERFACE)" = "terminal" ];\
		then\
			for i in $^;\
				do\
					$(SED) $(SED_FLAGS)\
						--in-place\
						-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_BAUDRATE.*)/"$(TOKEN_DISABLE)"\2/;"\
						-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_BAUDRATE_$(subst config-baud,,$@))/"$(TOKEN_ENABLE)"\2/;"\
							$$i;\
				done;\
		fi\
	&& $(DONE);

config-RS232_BAUD115200 : $(filter %$(SPIN_PINS) %$(SPIN_PCCOM),$(SOURCES_SPIN))
	@$(HEADLINE)\
	&& if [ "$(KICK2_INTERFACE)" = "flashrom" ];\
		then\
			for i in $^;\
				do\
					$(SED) $(SED_FLAGS)\
						--in-place\
						-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_BAUDRATE.*)/"$(TOKEN_DISABLE)"\2/;"\
						-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_BAUDRATE_$(subst config-RS232_BAUD,,$@))/"$(TOKEN_ENABLE)"\2/;"\
							$$i;\
				done;\
		fi\
	&& $(DONE);

config-RS232_BAUD57600 : $(filter %$(SPIN_PINS) %$(SPIN_PCCOM),$(SOURCES_SPIN))
	@$(HEADLINE)\
	&& if [ "$(KICK2_INTERFACE)" = "flashrom" ];\
		then\
			for i in $^;\
				do\
					$(SED) $(SED_FLAGS)\
						--in-place\
						-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_BAUDRATE.*)/"$(TOKEN_DISABLE)"\2/;"\
						-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_BAUDRATE_$(subst config-RS232_BAUD,,$@))/"$(TOKEN_ENABLE)"\2/;"\
							$$i;\
				done;\
		fi\
	&& $(DONE);

config-RS232_BAUD38400 : $(filter %$(SPIN_PINS) %$(SPIN_PCCOM),$(SOURCES_SPIN))
	@$(HEADLINE)\
	&& if [ "$(KICK2_INTERFACE)" = "flashrom" ];\
		then\
			for i in $^;\
				do\
					$(SED) $(SED_FLAGS)\
						--in-place\
						-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_BAUDRATE.*)/"$(TOKEN_DISABLE)"\2/;"\
						-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_BAUDRATE_$(subst config-RS232_BAUD,,$@))/"$(TOKEN_ENABLE)"\2/;"\
							$$i;\
				done;\
		fi\
	&& $(DONE);

config-SPI_CLOCK100 : $(SPIN_PINS)
	@$(HEADLINE)\
	&& if [ "$(KICK2_INTERFACE)" = "flashrom" ];\
		then\
			$(SED) $(SED_FLAGS)\
				--in-place\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_DRV75)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_DRV50)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_DRV25)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_DRV_DIPSW)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_DRV100)/"$(TOKEN_ENABLE)"\2/;"\
					$<;\
		fi\
	&& $(DONE);

config-SPI_CLOCK75 : $(SPIN_PINS)
	@$(HEADLINE)\
	&& if [ "$(KICK2_INTERFACE)" = "flashrom" ];\
		then\
			$(SED) $(SED_FLAGS)\
				--in-place\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_DRV100)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_DRV50)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_DRV25)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_DRV_DIPSW)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_DRV75)/"$(TOKEN_ENABLE)"\2/;"\
					$<;\
		fi\
	&& $(DONE);

config-SPI_CLOCK50 : $(SPIN_PINS)
	@$(HEADLINE)\
	&& if [ "$(KICK2_INTERFACE)" = "flashrom" ];\
		then\
			$(SED) $(SED_FLAGS)\
				--in-place\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_DRV100)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_DRV75)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_DRV25)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_DRV_DIPSW)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_DRV50)/"$(TOKEN_ENABLE)"\2/;"\
					$<;\
		fi\
	&& $(DONE);

config-SPI_CLOCK25 : $(SPIN_PINS)
	@$(HEADLINE)\
	&& if [ "$(KICK2_INTERFACE)" = "flashrom" ];\
		then\
			$(SED) $(SED_FLAGS)\
				--in-place\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_DRV100)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_DRV75)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_DRV50)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_DRV_DIPSW)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_DRV25)/"$(TOKEN_ENABLE)"\2/;"\
					$<;\
		fi\
	&& $(DONE);

config-SPI_CLOCK_DIPSW : $(SPIN_PINS)
	@$(HEADLINE)\
	&& if [ "$(KICK2_INTERFACE)" = "flashrom" ];\
		then\
			$(SED) $(SED_FLAGS)\
				--in-place\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_DRV100)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_DRV75)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_DRV50)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_DRV25)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_DRV_DIPSW)/"$(TOKEN_ENABLE)"\2/;"\
					$<;\
		fi\
	&& $(DONE);

#   config-PWRUP_ONCE
config-PWRUP_ONCE : $(SPIN_PINS)
	@$(HEADLINE)\
	&& if [ "$(KICK2_INTERFACE)" = "flashrom" ];\
		then\
			$(SED) $(SED_FLAGS)\
				--in-place\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_PWRUP_.*)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_PWRUP_ONCE)/"$(TOKEN_ENABLE)"\2/;"\
					$<;\
		fi\
	&& $(DONE);

#   config-PWRUP_REPETITIVE
config-PWRUP_REPETITIVE : $(SPIN_PINS)
	@$(HEADLINE)\
	&& if [ "$(KICK2_INTERFACE)" = "flashrom" ];\
		then\
			$(SED) $(SED_FLAGS)\
				--in-place\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_PWRUP_.*)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_PWRUP_REPETITIVE)/"$(TOKEN_ENABLE)"\2/;"\
					$<;\
		fi\
	&& $(DONE);

#   config-PWRUP_DIPSW
config-PWRUP_DIPSW : $(SPIN_PINS)
	@$(HEADLINE)\
	&& if [ "$(KICK2_INTERFACE)" = "flashrom" ];\
		then\
			$(SED) $(SED_FLAGS)\
				--in-place\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_PWRUP_.*)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_PWRUP_DIPSW)/"$(TOKEN_ENABLE)"\2/;"\
					$<;\
		fi\
	&& $(DONE);

#   config-SUSPEND_ALLOW
config-SUSPEND_ALLOW : $(SPIN_PINS)
	@$(HEADLINE)\
	&& if [ "$(KICK2_INTERFACE)" = "flashrom" ];\
		then\
			$(SED) $(SED_FLAGS)\
				--in-place\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_SUSPEND_.*)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_SUSPEND_ALLOW)/"$(TOKEN_ENABLE)"\2/;"\
					$<;\
		fi\
	&& $(DONE);

#   config-SUSPEND_INHIBIT
config-SUSPEND_INHIBIT : $(SPIN_PINS)
	@$(HEADLINE)\
	&& if [ "$(KICK2_INTERFACE)" = "flashrom" ];\
		then\
			$(SED) $(SED_FLAGS)\
				--in-place\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_SUSPEND_.*)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_SUSPEND_INHIBIT)/"$(TOKEN_ENABLE)"\2/;"\
					$<;\
		fi\
	&& $(DONE);

#   config-SUSPEND_DIPSW
config-SUSPEND_DIPSW : $(SPIN_PINS)
	@$(HEADLINE)\
	&& if [ "$(KICK2_INTERFACE)" = "flashrom" ];\
		then\
			$(SED) $(SED_FLAGS)\
				--in-place\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_SUSPEND_.*)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_SUSPEND_DIPSW)/"$(TOKEN_ENABLE)"\2/;"\
					$<;\
		fi\
	&& $(DONE);

#   config-SPI_MODE0 – Enable interface to `flashrom` to use SPI Mode 0
config-SPI_MODE0 : $(SPIN_PINS)
	@$(HEADLINE)\
	&& if [ "$(KICK2_INTERFACE)" = "flashrom" ];\
		then\
			$(SED) $(SED_FLAGS)\
				--in-place\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_SPIMODE3)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_SPIMODE_DIPSW)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_SPIMODE0)/"$(TOKEN_ENABLE)"\2/;"\
					$<;\
		fi\
	&& $(DONE);

#   config-SPI_MODE3 – Enable interface to `flashrom` to use SPI Mode 3
config-SPI_MODE3 : $(SPIN_PINS)
	@$(HEADLINE)\
	&& if [ "$(KICK2_INTERFACE)" = "flashrom" ];\
		then\
			$(SED) $(SED_FLAGS)\
				--in-place\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_SPIMODE0)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_SPIMODE_DIPSW)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_SPIMODE3)/"$(TOKEN_ENABLE)"\2/;"\
					$<;\
		fi\
	&& $(DONE);

#   config-SPI_MODE_DIPSW – Enable interface to `flashrom` to use SPI Modes according to DIP Switch
config-SPI_MODE_DIPSW : $(SPIN_PINS)
	@$(HEADLINE)\
	&& if [ "$(KICK2_INTERFACE)" = "flashrom" ];\
		then\
			$(SED) $(SED_FLAGS)\
				--in-place\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_SPIMODE0)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_ENABLE)")(.*define.*_CFG_SPIMODE3)/"$(TOKEN_DISABLE)"\2/;"\
				-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_SPIMODE_DIPSW)/"$(TOKEN_ENABLE)"\2/;"\
					$<;\
		fi\
	&& $(DONE);

ifeq ($(IFC_CONFIG),1)
#   clean configuration
clean-config : config-baud115200 config-connect
	@$(HEADLINE)\
	&& $(DONE);
endif

ifeq ($(IFC_CONFIG),2)
#   clean configuration
clean-config :\
	config-RS232_BAUD115200\
		config-SPI_CLOCK_DIPSW\
			config-SPI_MODE_DIPSW\
				config-SUSPEND_DIPSW\
					config-PWRUP_DIPSW\
						config-connect
	@$(HEADLINE)\
	&& $(DONE);
endif

ifeq ($(IFC_CONFIG),3)
#   clean configuration
clean-config : config-connect
	@$(HEADLINE)\
	&& $(DONE);
endif


#   build ‘kick2’, the firmware
$(OUT) : $(SOURCES_SPIN)
	@$(HEADLINE)\
	&& tmpfile=`$(MKTEMP) $(MKTEMP_FLAGS)`\
	&& $(CP) $(CP_FLAGS)\
		$(SPIN_MENU) $$tmpfile\
	&& $(SED) $(SED_FLAGS)\
		--in-place\
		-e 's/<VERSION2>/$(PROJECT_NUMBER)/g;'\
			$(SPIN_MENU)\
	&& $(OPENSPIN) $(OPENSPIN_FLAGS)\
		-u\
		-e $<\
		-o $@.eeprom\
	&& $(OPENSPIN) $(OPENSPIN_FLAGS)\
		-u\
		-b $<\
		-o $@\
	&& $(MV) $(MV_FLAGS)\
		$$tmpfile $(SPIN_MENU)\
	&& $(DONE);

#   favicon for html output
$(FAVICON) : $(ROOT_FW2_DOC)Makefile
	@$(HEADLINE)\
	&& $(MAKE)\
		-C $(<D)\
			$(@F)\
	&& $(DONE);

%.spin.$(KICK2_INTERFACE).txt : %.spin
	@$(HEADLINE)\
	&& $(OPENSPIN) $(OPENSPIN_FLAGS)\
		-v\
		-d\
			$<\
				> $@\
	&& $(DONE);

#   *.spin.txt.html
#     * remove copyright footers
#     * remove email addresses
%.spin.$(KICK2_INTERFACE).html : %.spin.$(KICK2_INTERFACE).txt $(FAVICON)
	@$(ECHO) $(ECHO_FLAGS)\
		"<!DOCTYPE html>"\
		"\n<html>"\
		"\n  <head>"\
		"\n    <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">"\
		"\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=3.0, user-scalable=1\">"\
		"\n    <link rel=\"icon\" type=\"image/png\" href=\"$(FAVICON)\">"\
		"\n    <title>$@</title>"\
		"\n    <style type=\"text/css\">"\
		"\n      @import url(../doc/stylesheet.css) all;"\
		"\n    </style>"\
		"\n  </head>"\
		"\n  <body>"\
		"\n    <div><br></div>"\
			> $@\
	&& $(ECHO) $(ECHO_FLAGS)\
		"    <p id=\"doc-reference\">"\
		"\n      Documentation for “$(PROJECT_TITLE)” as of $(shell $(DATE) $(DATE_FLAGS);)<br>"\
		"\n      Repository: $(PROJECT_REPO)<br>"\
		"\n      Version: $(PROJECT_NUMBER)<br>"\
		"\n      Branch: $(PROJECT_BRANCH)<br>"\
		"\n    </p>"\
			>> $@\
	&& $(NAVBAR)\
	&& $(ECHO) $(ECHO_FLAGS)\
		"\n    <h1>$@</h1>"\
		"\n    <pre>"\
			>> $@\
	&& $(CAT) $(CAT_FLAGS)\
		-v\
			$<\
	| $(SED) $(SED_FLAGS)\
		-e 's/<.*@.*\..*>//g; s/\&/\&amp;/g; s/\"/\&quot;/g; s/</\&lt;/g; s/>/\&gt;/g;'\
			-\
				>> $@\
	&& $(ECHO) $(ECHO_FLAGS)\
		"    </pre>"\
			>> $@\
	&& $(ECHO) $(ECHO_FLAGS)\
		"\n  </body>"\
		"\n</html>"\
			>> $@\
	&& $(DONE);

#   config-connect – Enable interface to `connect`
config-connect : $(SPIN_KICK2) config-nointerface
	@$(HEADLINE)\
	&& $(SED) $(SED_FLAGS)\
		--in-place\
		-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_CONNECT)/"$(TOKEN_ENABLE)"\2/;"\
			$<\
	&& $(DONE);

#   config-flashrom – Enable interface to `flashrom`
config-flashrom : $(SPIN_KICK2) config-nointerface
	@$(HEADLINE)\
	&& $(SED) $(SED_FLAGS)\
		--in-place\
		-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_FLASHROM)/"$(TOKEN_ENABLE)"\2/;"\
			$<\
	&& $(DONE);

#   config-propterm – Enable interface to `propeller terminal`
config-propterm : $(SPIN_KICK2) config-nointerface
	@$(HEADLINE)\
	&& $(SED) $(SED_FLAGS)\
		--in-place\
		-e "s/^("$(TOKEN_DISABLE)")(.*define.*_CFG_TERMINAL)/"$(TOKEN_ENABLE)"\2/;"\
			$<\
	&& $(DONE);

#   config-nointerface – Disable interface configurations in top object
config-nointerface : $(SPIN_KICK2)
	@$(HEADLINE)\
	&& $(SED) $(SED_FLAGS)\
		--in-place\
		-e "s/^("$(TOKEN_ENABLE)")(.*define)/"$(TOKEN_DISABLE)"\2/;"\
			$<\
	&& $(DONE);

#   docs – dump out doc mode
docs : $(patsubst %.spin,%.spin.$(KICK2_INTERFACE).txt,$(SOURCES_SPIN))

#   html – generate html documentation
html : $(patsubst %.spin,%.spin.$(KICK2_INTERFACE).html,$(SOURCES_SPIN))
	@$(HEADLINE)\
	&& $(DONE);

#   tree – list project’s object tree
tree : $(SPIN_KICK2)
	@$(HEADLINE)\
	&& @$(OPENSPIN) $(OPENSPIN_FLAGS)\
		-t\
			$<\
	&& $(DONE);

#   files – list spin files in use
files : $(SPIN_KICK2)
	@$(HEADLINE)\
	&& $(OPENSPIN) $(OPENSPIN_FLAGS)\
		-f\
			$<\
	&& $(DONE);

#   review – review dumped documentation
review : docs
	@$(HEADLINE)\
	&& for i in $(wildcard ./*.spin.txt);\
		do\
			$(LESS) $(LESS_FLAGS)\
				$$i;\
		done\
	&& $(DONE);

#   symbols – Dump PUB & CON symbol information
symbols : $(SPIN_KICK2)
	@$(HEADLINE)\
	&& $(OPENSPIN) $(OPENSPIN_FLAGS)\
		-s\
			$<\
	&& $(DONE);

#   clean documentation
clean-docs :
	@$(HEADLINE)\
	&& $(RM) $(RM_FLAGS)\
		-f\
			$(wildcard ./*.binary)\
			$(wildcard ./*.spin.*.txt)\
			$(wildcard ./*.spin.*.html)\
			index.html\
	&& $(DONE);

#   clean
clean : hello clean-docs clean-config
	@$(HEADLINE)\
	&& $(RM) $(RM_FLAGS)\
		-f\
			$(OUT)\
			$(OUT).eeprom\
	&& $(DONE);
