#   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, 2024, 2025  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
#   -----
#
#
#   Upload, start ‘kick2’, the Chipflasher’s new firmware
#
#
#   Usage
#   -----
#
#
#   To get an overview of targets, type:
#
#           make help
#
#   To start ‘connect’, type:
#
#           make connect
#
#   To load ‘kick2’ into RAM and start ‘connect’, type:
#
#           make kick2-ram-connect
#


# Shell
SHELL                         := /bin/sh


# White Space
EMPTY                         :=
SPACE                         := $(EMPTY) $(EMPTY)
COMMA                         := ,
M5                            := xxxxx
TAB1                          := $(SPACE)$(SPACE)$(SPACE)$(SPACE)
FG_DARKGRAY                   := "\e[90m"
FG_DEFAULT                    := "\e[39m\n"


# Root Paths
ROOT_DOC                      := ../../doc/
ROOT_HOST_START               := ../../host/start/
ROOT_HOST_SRC                 := ../../host/src/
ROOT_FW2_START                := $(EMPTY)
ROOT_FW2_SRC                  := ../src/
ROOT_FW2_IO                   := $(ROOT_FW2_START)


# Utilities
LS                            := $(shell command -v ls;)
LS_FLAGS                      := -l
$(if $(strip $(LS)),,         $(error Cannot find ls utility))

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

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

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

ECHO                          := $(shell command -v echo;)
ECHO_FLAGS                    :=
$(if $(strip $(ECHO)),,       $(error Cannot find echo utility))

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

PRINTF                        := $(shell command -v printf;)
PRINTF_FLAGS                  :=
$(if $(strip $(PRINTF)),,     $(error Cannot find printf utility))

CONNECT                       := $(ROOT_HOST_SRC)connect
CONNECT_FLAGS                 :=
#   No check for `connect`, it will be compiled.

FLASHROM                      := $(shell command -v flashrom;)
FLASHROM_FLAGS                :=
$(if $(strip $(FLASHROM)),,   $(error Cannot find flashrom utility))

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


# Files
SPIN_PCB                      := $(ROOT_FW2_SRC)PCB.spin
FLASHROM_LOG                  := $(ROOT_FW2_START)flashrom.log
KICK2                         := $(ROOT_FW2_SRC)kick2
BOARD_CONFIG                  := $(ROOT_FW2_START)board.cfg
PTR_TTY_PORT                  := $(ROOT_HOST_START)tty_port_pointer
CHIP2FILE                     := $(ROOT_FW2_IO)chip2file.txt
FILE2CHIP                     := $(ROOT_FW2_IO)file2chip.txt


# Project Numbers
include $(ROOT_DOC)project-numbers.mk


# Settings
MAKEFILE_TITLE                := Load ‘kick2’ to chipflasher’s RAM or EEPROM.
PROJECT_TITLE                 := Zerocat Chipflasher
PROJECT_BRIEF                 := Flash free firmware to BIOS chips, kick the Management Engine.
TTY_PORT                      = $(strip\
	$(shell\
		$(LS) $(LS_FLAGS) $(PTR_TTY_PORT)\
		| $(SED) $(SED_FLAGS) -e's/(.*-> )(.*)/\2/' -\
	)\
)
TTY_BAUDRATE                  = $(strip\
	$(shell\
		$(SED) $(SED_FLAGS)\
			-e '/^baudrate:/!d; s/^.*\: //;'\
				$(BOARD_CONFIG);\
	)\
)
TTY_BAUDRATE_SERPROG          = $(strip\
	$(shell\
		$(SED) $(SED_FLAGS)\
			-e '/^#.*define.*_CFG_BAUDRATE_/!d; s/^.*_CFG_BAUDRATE_//;'\
				$(SPIN_PCB);\
	)\
)
FLASHROM_FLAGS                += $(strip\
	-p serprog:dev=$(TTY_PORT):$(TTY_BAUDRATE_SERPROG)\
)
RESET_DELAY                   := 5s


# Tinned Cans: HEADER, HEADLINE, DONE
include $(ROOT_DOC)tinned-headers.mk


# Tinned Cans: TRIGGER_RESET
define TRIGGER_RESET
	$(strip\
		$(PROPLOAD) $(PROPLOAD_FLAGS)\
			-p $(TTY_PORT)\
			-b $(basename $(BOARD_CONFIG))\
			-o -r\
	)
endef


# Remove corrupted files
.DELETE_ON_ERROR :


# Suffixes, to be checked for old fashioned suffix rules
.SUFFIXES :


# Intermediate Targets
#~ .INTERMEDIATE :


# Secondary Targets, enable empty list for debugging
#~ .SECONDARY :


# Phony Targets
.PHONY :\
	all\
	\
	hello\
	help\
	\
	config-baud230400\
	config-baud115200\
	config-baud57600\
	config-baud38400\
	\
	reset\
	kick2-ram\
	kick2-eeprom\
	kick2-ram-terminal\
	kick2-ram-connect\
	connect\
	terminal\
	flashrom\
	\
	clean-config\
	clean


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

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

#   display help information
help : hello
	@$(HEADLINE)\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "List of Targets"\
	&& $(ECHO) $(ECHO_FLAGS) "==============="\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "Default Goal"\
	&& $(ECHO) $(ECHO_FLAGS) "------------"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "all"\
	&& $(ECHO) $(ECHO_FLAGS) "$(TAB1)same as kick2-ram, with greeter"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "Help"\
	&& $(ECHO) $(ECHO_FLAGS) "----"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "hello"\
	&& $(ECHO) $(ECHO_FLAGS) "$(TAB1)greeter"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "help"\
	&& $(ECHO) $(ECHO_FLAGS) "$(TAB1)this short overview"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "Configure"\
	&& $(ECHO) $(ECHO_FLAGS) "---------"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "These goals help you to modify ‘$(BOARD_CONFIG)’ and to set an individual baudrate:"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "config-baud230400"\
	&& $(ECHO) $(ECHO_FLAGS) "$(TAB1)high speed"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "config-baud115200"\
	&& $(ECHO) $(ECHO_FLAGS) "$(TAB1)standard speed (default)"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "config-baud57600"\
	&& $(ECHO) $(ECHO_FLAGS) "$(TAB1)medium speed"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "config-baud38400"\
	&& $(ECHO) $(ECHO_FLAGS) "$(TAB1)low speed"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "The rate set will be used by the ‘propeller-load’ utility"\
	&& $(ECHO) $(ECHO_FLAGS) "a) to upload the firmware at the given speed,"\
	&& $(ECHO) $(ECHO_FLAGS) "b) to pass the baudrate as an argument to ‘connect’ or ‘flashrom’."\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "The firmware itself will not be patched, it should have been compiled with the same rate."\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "Ready-Mades"\
	&& $(ECHO) $(ECHO_FLAGS) "-----------"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "kick2-ram"\
	&& $(ECHO) $(ECHO_FLAGS) "$(TAB1)reset device, send ‘kick2’ to free-design RAM, and run"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "kick2-ram-connect"\
	&& $(ECHO) $(ECHO_FLAGS) "$(TAB1)send ‘kick2’ to free-design RAM, run, and start ‘connect’"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "kick2-ram-terminal"\
	&& $(ECHO) $(ECHO_FLAGS) "$(TAB1)reset device, send ‘kick2’ to free-design RAM, run, and start in terminal mode"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "reset"\
	&& $(ECHO) $(ECHO_FLAGS) "$(TAB1)reset chip flasher device"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "kick2-eeprom"\
	&& $(ECHO) $(ECHO_FLAGS) "$(TAB1)reset device, send ‘kick2’ to EEPROM, don't run"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "### Start Utilities"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "connect"\
	&& $(ECHO) $(ECHO_FLAGS) "$(TAB1)start ‘connect’, the host utility, which will talk to ‘kick2’ stored in EEPROM or free-design RAM"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "terminal"\
	&& $(ECHO) $(ECHO_FLAGS) "$(TAB1)reset device, start in terminal mode"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "flashrom"\
	&& $(ECHO) $(ECHO_FLAGS) "$(TAB1)invoke ‘flashrom’ without options, just probe chip."\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "Clean"\
	&& $(ECHO) $(ECHO_FLAGS) "-----"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "clean-config"\
	&& $(ECHO) $(ECHO_FLAGS) "$(TAB1)reset default baudrate"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(ECHO) $(ECHO_FLAGS) "clean"\
	&& $(ECHO) $(ECHO_FLAGS) "$(TAB1)make files and folders clean"\
	&& $(ECHO) $(ECHO_FLAGS) ""\
	&& $(DONE);

config-baud230400 : $(BOARD_CONFIG)
	@$(HEADLINE)\
	&& $(SED) $(SED_FLAGS)\
		-i\
		-e 's/^baudrate/#~ baudrate/;'\
		-e's/(\#~ )(baudrate: 230400)$$/\2/;'\
			$<\
	&& $(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);

#   send kick2 to RAM and run
kick2-ram : $(KICK2) $(BOARD_CONFIG) | $(TTY_PORT)
	@$(HEADLINE)\
	&& $(PROPLOAD) $(PROPLOAD_FLAGS)\
		-p $(TTY_PORT)\
		-b $(basename $(BOARD_CONFIG))\
		$<\
		-r\
	&& $(DONE);

#   send kick2 to EEPROM, don't run
kick2-eeprom : $(KICK2).eeprom $(BOARD_CONFIG) | $(TTY_PORT)
	-@$(HEADLINE)\
	&& $(PRINTF) $(PRINTF_FLAGS) $(FG_DARKGRAY)\
	&& $(PROPLOAD) $(PROPLOAD_FLAGS)\
		-p $(TTY_PORT)\
		-b $(basename $(BOARD_CONFIG))\
		$<\
		-e;
	@$(PRINTF) $(PRINTF_FLAGS) $(FG_DEFAULT)\
	&& $(DONE);

#   send kick2 to RAM, run, and start a propeller-terminal
kick2-ram-terminal : $(KICK2) $(BOARD_CONFIG) | $(TTY_PORT)
	-@$(HEADLINE)\
	&& $(PRINTF) $(PRINTF_FLAGS) $(FG_DARKGRAY)\
	&& $(PROPLOAD) $(PROPLOAD_FLAGS)\
		-p $(TTY_PORT)\
		-b $(basename $(BOARD_CONFIG))\
		$<\
		-r\
		-t\
		-q;
	@$(PRINTF) $(PRINTF_FLAGS) $(FG_DEFAULT)\
	&& $(DONE);

#   connect utility
$(CONNECT) :
	@$(HEADLINE)\
	&& $(MAKE)\
		-C $(@D)\
			$(@F)\
	&& $(DONE);

#   start connect
connect : $(BOARD_CONFIG) $(CONNECT) | $(TTY_PORT)
	@$(HEADLINE)\
	&& $(CONNECT) $(CONNECT_FLAGS)\
		$(ROOT_FW2_IO)$(CHIP2FILE)\
		$(ROOT_FW2_IO)$(FILE2CHIP)\
		$(TTY_PORT)\
		B$(TTY_BAUDRATE)\
	&& $(DONE);

#   send kick2 to RAM and start connect
kick2-ram-connect :
	@$(HEADLINE)\
	&& $(MAKE)\
		kick2-ram\
	&& $(SLEEP) $(SLEEP_FLAGS)\
		10\
	&& $(MAKE)\
		connect\
	&& $(DONE);

#   start propeller-load terminal
terminal : | $(TTY_PORT)
	-@$(HEADLINE)\
	&& $(PRINTF) $(PRINTF_FLAGS) $(FG_DARKGRAY)\
	&& $(PROPLOAD) $(PROPLOAD_FLAGS)\
		-p $(TTY_PORT)\
		-b $(basename $(BOARD_CONFIG))\
		-o255,5000\
		-r\
		-t\
		-q;
	@$(PRINTF) $(PRINTF_FLAGS) $(FG_DEFAULT)\
	&& $(DONE);

#   start flashrom with no operation, just probe chip
flashrom : | $(TTY_PORT)
	@$(HEADLINE)\
	&& $(FLASHROM) $(FLASHROM_FLAGS)\
		-V\
		-o $(FLASHROM_LOG)\
	&& $(DONE);

#   reset chip flasher device
reset : $(BOARD_CONFIG) | $(TTY_PORT)
	@$(HEADLINE)\
	&& $(TRIGGER_RESET)\
	&& $(DONE);

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

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