SHELL := /bin/bash
.SHELLFLAGS := -euo pipefail -c

REPO_DIR := $(abspath ../..)
SOC_DIR := $(REPO_DIR)/soc
OUT_DIR ?= $(SOC_DIR)/out/software
FLASH_DIR ?= $(SOC_DIR)/out/flash
include $(REPO_DIR)/tools/project.mk

APP_FLASH_OFFSET ?= 0x06000000
APP ?= hello_uart
GPS_DEBUG ?= 1
GPS_DEBUG_LEVEL ?= 1
GPS_ESKF_ENABLE ?= 1
GPS_EPHEMERIS_FLASH_ENABLE ?= 1
GPS_EPHEMERIS_FLASH_SEED_INITIAL ?= 1
GPS_EPHEMERIS_FLASH_BASE ?= 0x01fe0000
GPS_NAV_CONTEXT_ENABLE ?= 1
GPS_NAV_CONTEXT_FLASH_BASE ?= 0x01fc0000
IMU_SENSOR ?= auto
BSP_UART_CLOCK_HZ ?= 100000000
BSP_UART_BAUDRATE ?= 460800
GPS_SYSTEM_UART_BAUDRATE ?= 460800
BSP_CLINT_TIMEBASE_HZ ?= 1000000
BSP_SPI_FLASH_PROFILE ?= 1
GPS_SYSTEM_CLINT_TIMEBASE_HZ ?= 500000
GPS_SYSTEM_IMU_PUBLISH_EVERY_N_SAMPLES ?= 5
# BSP_DTIM_* mirrors the FPGA DTIM_* knobs and is used by C code plus linker scripts.
BSP_DTIM_BASE ?= 0x80000000
BSP_DTIM_SIZE ?= 0x00100000
OBJCOPY := $(CROSS)objcopy
READELF := $(CROSS)readelf
MAKE_FLASH_IMAGE := $(SOC_DIR)/software/tools/make_flash_image.py

.PHONY: help all app bootloader hello pmod-spi-test max2771-spi-test steval-mki217v1-test gps-system flash-image clean

help:
	@echo "Common Rocket bare-metal software targets:"
	@echo "  make all         # build bootloader and default hello app"
	@echo "  make app APP=name # build one app under soc/software/name"
	@echo "  make bootloader  # build only BootROM flash bootloader"
	@echo "  make hello       # build only hello UART app"
	@echo "  make pmod-spi-test # build PMOD SPI smoke test app"
	@echo "  make max2771-spi-test # build dedicated MAX2771 SPI test app"
	@echo "  make steval-mki217v1-test # build STEVAL-MKI217V1 LSM6DSOX polling app"
	@echo "  make gps-system  # build imported GPS bare-metal app"
	@echo "  make flash-image APP=name # build bootloader-readable app flash image"
	@echo "  make clean       # remove software build products"
	@echo "Config:"
	@echo "  APP_FLASH_OFFSET=$(APP_FLASH_OFFSET)"
	@echo "  BSP_UART_CLOCK_HZ=$(BSP_UART_CLOCK_HZ)"
	@echo "  BSP_UART_BAUDRATE=$(BSP_UART_BAUDRATE)"
	@echo "  GPS_SYSTEM_UART_BAUDRATE=$(GPS_SYSTEM_UART_BAUDRATE)"
	@echo "  GPS_ESKF_ENABLE=$(GPS_ESKF_ENABLE)"
	@echo "  GPS_EPHEMERIS_FLASH_ENABLE=$(GPS_EPHEMERIS_FLASH_ENABLE)"
	@echo "  GPS_EPHEMERIS_FLASH_SEED_INITIAL=$(GPS_EPHEMERIS_FLASH_SEED_INITIAL)"
	@echo "  GPS_EPHEMERIS_FLASH_BASE=$(GPS_EPHEMERIS_FLASH_BASE)"
	@echo "  GPS_NAV_CONTEXT_ENABLE=$(GPS_NAV_CONTEXT_ENABLE)"
	@echo "  GPS_NAV_CONTEXT_FLASH_BASE=$(GPS_NAV_CONTEXT_FLASH_BASE)"
	@echo "  IMU_SENSOR=$(IMU_SENSOR)"
	@echo "  BSP_CLINT_TIMEBASE_HZ=$(BSP_CLINT_TIMEBASE_HZ)"
	@echo "  BSP_SPI_FLASH_PROFILE=$(BSP_SPI_FLASH_PROFILE)"
	@echo "  GPS_SYSTEM_CLINT_TIMEBASE_HZ=$(GPS_SYSTEM_CLINT_TIMEBASE_HZ)"
	@echo "  GPS_SYSTEM_IMU_PUBLISH_EVERY_N_SAMPLES=$(GPS_SYSTEM_IMU_PUBLISH_EVERY_N_SAMPLES)"
	@echo "  BSP_DTIM_BASE=$(BSP_DTIM_BASE)"
	@echo "  BSP_DTIM_SIZE=$(BSP_DTIM_SIZE)"

all: bootloader hello

bootloader:
	@make -C bootloader TOOLCHAIN="$(TOOLCHAIN)" BUILD_DIR="$(OUT_DIR)/bootloader" APP_FLASH_OFFSET="$(APP_FLASH_OFFSET)" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_SPI_FLASH_PROFILE="$(BSP_SPI_FLASH_PROFILE)" BSP_DTIM_BASE="$(BSP_DTIM_BASE)" BSP_DTIM_SIZE="$(BSP_DTIM_SIZE)" all

hello:
	@make -C hello_uart TOOLCHAIN="$(TOOLCHAIN)" BUILD_DIR="$(OUT_DIR)/hello_uart" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_DTIM_BASE="$(BSP_DTIM_BASE)" BSP_DTIM_SIZE="$(BSP_DTIM_SIZE)" all

pmod-spi-test:
	@make -C pmod_spi_test TOOLCHAIN="$(TOOLCHAIN)" BUILD_DIR="$(OUT_DIR)/pmod_spi_test" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_DTIM_BASE="$(BSP_DTIM_BASE)" BSP_DTIM_SIZE="$(BSP_DTIM_SIZE)" all

max2771-spi-test:
	@make -C max2771_spi_test TOOLCHAIN="$(TOOLCHAIN)" BUILD_DIR="$(OUT_DIR)/max2771_spi_test" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_DTIM_BASE="$(BSP_DTIM_BASE)" BSP_DTIM_SIZE="$(BSP_DTIM_SIZE)" all

steval-mki217v1-test:
	@make -C steval_mki217v1_test TOOLCHAIN="$(TOOLCHAIN)" BUILD_DIR="$(OUT_DIR)/steval_mki217v1_test" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_DTIM_BASE="$(BSP_DTIM_BASE)" BSP_DTIM_SIZE="$(BSP_DTIM_SIZE)" all

gps-system:
	@make -C gps_system TOOLCHAIN="$(TOOLCHAIN)" BUILD_DIR="$(OUT_DIR)/gps_system" GPS_DEBUG="$(GPS_DEBUG)" GPS_DEBUG_LEVEL="$(GPS_DEBUG_LEVEL)" GPS_ESKF_ENABLE="$(GPS_ESKF_ENABLE)" GPS_EPHEMERIS_FLASH_ENABLE="$(GPS_EPHEMERIS_FLASH_ENABLE)" GPS_EPHEMERIS_FLASH_SEED_INITIAL="$(GPS_EPHEMERIS_FLASH_SEED_INITIAL)" GPS_EPHEMERIS_FLASH_BASE="$(GPS_EPHEMERIS_FLASH_BASE)" GPS_NAV_CONTEXT_ENABLE="$(GPS_NAV_CONTEXT_ENABLE)" GPS_NAV_CONTEXT_FLASH_BASE="$(GPS_NAV_CONTEXT_FLASH_BASE)" IMU_SENSOR="$(IMU_SENSOR)" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(GPS_SYSTEM_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(GPS_SYSTEM_CLINT_TIMEBASE_HZ)" BSP_SPI_FLASH_PROFILE="$(BSP_SPI_FLASH_PROFILE)" IMU_CORRECTED_PUBLISH_EVERY_N_SAMPLES="$(GPS_SYSTEM_IMU_PUBLISH_EVERY_N_SAMPLES)" BSP_DTIM_BASE="$(BSP_DTIM_BASE)" BSP_DTIM_SIZE="$(BSP_DTIM_SIZE)" all

app:
	@test -d "$(APP)"
	@make -C "$(APP)" TOOLCHAIN="$(TOOLCHAIN)" BUILD_DIR="$(OUT_DIR)/$(APP)" GPS_DEBUG="$(GPS_DEBUG)" GPS_DEBUG_LEVEL="$(GPS_DEBUG_LEVEL)" GPS_ESKF_ENABLE="$(GPS_ESKF_ENABLE)" GPS_EPHEMERIS_FLASH_ENABLE="$(GPS_EPHEMERIS_FLASH_ENABLE)" GPS_EPHEMERIS_FLASH_SEED_INITIAL="$(GPS_EPHEMERIS_FLASH_SEED_INITIAL)" GPS_EPHEMERIS_FLASH_BASE="$(GPS_EPHEMERIS_FLASH_BASE)" GPS_NAV_CONTEXT_ENABLE="$(GPS_NAV_CONTEXT_ENABLE)" GPS_NAV_CONTEXT_FLASH_BASE="$(GPS_NAV_CONTEXT_FLASH_BASE)" IMU_SENSOR="$(IMU_SENSOR)" BSP_UART_CLOCK_HZ="$(BSP_UART_CLOCK_HZ)" BSP_UART_BAUDRATE="$(BSP_UART_BAUDRATE)" BSP_CLINT_TIMEBASE_HZ="$(BSP_CLINT_TIMEBASE_HZ)" BSP_SPI_FLASH_PROFILE="$(BSP_SPI_FLASH_PROFILE)" BSP_DTIM_BASE="$(BSP_DTIM_BASE)" BSP_DTIM_SIZE="$(BSP_DTIM_SIZE)" all

flash-image: app
	@mkdir -p "$(FLASH_DIR)"
	python3 "$(MAKE_FLASH_IMAGE)" \
	  --elf "$(OUT_DIR)/$(APP)/$(APP).elf" \
	  --out "$(FLASH_DIR)/$(APP).flash.bin" \
	  --flash-offset "$(APP_FLASH_OFFSET)" \
	  --objcopy "$(OBJCOPY)" \
	  --readelf "$(READELF)"

clean:
	rm -rf "$(SOC_DIR)/out"
