TARGET := gps_system

# Keep the standalone app build observable on the board.  The board and parent
# software Makefiles already pass these values, but a direct `make` in this
# directory previously compiled every GPS_LOG call out and produced a silent
# UART image.
GPS_DEBUG ?= 1
GPS_DEBUG_LEVEL ?= 1
GPS_BUILD_ID ?= $(shell git describe --always --dirty --abbrev=12 2>/dev/null || printf unknown)

# The current Genesys2 Rocket/fabric domain that clocks the UART is 50 MHz.
# The 50 Hz fused-location stream plus GPS diagnostics does not fit safely in
# the polling UART budget at 115200 baud.
BSP_UART_CLOCK_HZ ?= 50000000
BSP_UART_BAUDRATE ?= 460800
BSP_CLINT_TIMEBASE_HZ ?= 500000

# Select one sensor backend, or keep the default read-only WHO_AM_I probe.
# Accepted values: auto, tdk, st (stm is an alias for st).
IMU_SENSOR ?= auto
ifeq ($(IMU_SENSOR),auto)
IMU_DRIVER_SRCS := src/drivers/imu/tdk_icm42688.c src/drivers/imu/st_lsm6dsox.c
IMU_BACKEND_CFLAG := -DIMU_SENSOR_BUILD_AUTO=1
else ifeq ($(IMU_SENSOR),tdk)
IMU_DRIVER_SRCS := src/drivers/imu/tdk_icm42688.c
IMU_BACKEND_CFLAG := -DIMU_SENSOR_BUILD_TDK=1
else ifeq ($(IMU_SENSOR),st)
IMU_DRIVER_SRCS := src/drivers/imu/st_lsm6dsox.c
IMU_BACKEND_CFLAG := -DIMU_SENSOR_BUILD_ST=1
else ifeq ($(IMU_SENSOR),stm)
IMU_DRIVER_SRCS := src/drivers/imu/st_lsm6dsox.c
IMU_BACKEND_CFLAG := -DIMU_SENSOR_BUILD_ST=1
else
$(error IMU_SENSOR must be auto, tdk, st or stm)
endif

# A non-zero value is a sensor-independent target.  The common layer accepts
# only a hardware ODR within 5%; thus 200 selects 200 Hz on TDK and the real
# 208 Hz setting on LSM6DSOX.  Zero keeps the backend default.
ifdef TDK_IMU_ODR_HZ
IMU_ODR_HZ ?= $(TDK_IMU_ODR_HZ)
else
IMU_ODR_HZ ?= 50
endif
IMU_ACCEL_FS_G ?= 0
IMU_GYRO_FS_DPS ?= 0
GPS_ESKF_ENABLE ?= 1
# UART telemetry cadence only; ESKF prediction still runs for every IMU sample.
# At the default 50 Hz ODR, 5 samples produce one corrected record every 100 ms.
IMU_CORRECTED_PUBLISH_EVERY_N_SAMPLES ?= 5

APP_SRCS := \
	gps_system.c \
	src/gps/gps_receiver.c \
	src/imu/imu_calibration.c \
	src/imu/imu_sensor.c \
	src/adapters/imu_fusion_profile.c \
	src/adapters/gps_system_uart.c \
	$(IMU_DRIVER_SRCS) \
	src/fusion/eskf.c \
	src/fusion/fusion_motion.c \
	src/fusion/fusion_rest_detector.c \
	src/fusion/fusion_engine.c \
	src/fusion/fusion_gps_adapter.c \
	src/fusion/navigation_fusion.c \
	src/adapters/gps_fusion_publisher.c \
	src/gps/gps_ip.c \
	src/gps/gps_interrupt_handlers.c \
	src/gps/gps_acq_manager.c \
	src/gps/gps_ephemeris_cache.c \
	src/gps/gps_ephemeris_validity.c \
	src/gps/gps_ephemeris_store.c \
	src/gps/gps_lnav_parser.c \
	src/gps/gps_almanac.c \
	src/gps/gps_nav_context_store.c \
	src/gps/gps_time_anchor.c \
	src/gps/gps_nav_epoch.c \
	src/gps/gps_pps.c \
	src/gps/gps_pps_quality.c \
	src/gps/gps_pps_time_filter.c \
	src/gps/gps_tracking_measurement.c \
	src/gps/linked_list.c \
	src/gps/NavEquations.c \
	src/gps/matrixLib.c

BSP_SRCS := init.c uart.c plic.c irq.c spi_flash.c pmod_spi.c

GPS_NAV_SOLVE_TIMER_TICKS ?= 10
# Warm/hot reacquisition epoch-phase seeding.  This needs the tracking IP's
# NAV_SOLVE_PHASE_SEED register, added alongside this firmware.  Building the
# feature in and running against an older bitstream would make the write decode
# to PSLVERR, which the APB-to-TileLink bridge reports as `denied` and Rocket
# can take as a store access fault.  Set to 0 to build firmware for a bitstream
# that predates the register.
GPS_WARM_SEED_ENABLE ?= 1
# Persistent ephemeris cache in the top two 64 KiB flash sectors.  Set to 0 to
# build firmware that never writes to flash.
GPS_EPHEMERIS_FLASH_ENABLE ?= 1
# Test hooks.  MAX_SLOTS caps slots per sector so flash compaction is reachable
# on hardware in seconds instead of after a full sector; FORCE_FORMAT erases
# both sectors at boot.  Both must be 0 in a production image.
GPS_EPHEMERIS_STORE_MAX_SLOTS ?= 0
GPS_EPHEMERIS_FLASH_FORCE_FORMAT ?= 0
GPS_EPHEMERIS_FLASH_SEED_INITIAL ?= 1
GPS_EPHEMERIS_FLASH_BASE ?= 0x01fe0000
GPS_NAV_CONTEXT_ENABLE ?= 1
GPS_NAV_CONTEXT_FLASH_BASE ?= 0x01fc0000
GPS_PPS_STATUS_LOG_INTERVAL ?= 10
GPS_PPS_DOPPLER_PREDICTOR_ENABLE ?= 1
GPS_PPS_DOPPLER_PREDICTOR_AB_UPDATES ?= 0

include ../common/app.mk

CFLAGS += -Iheader
CFLAGS += $(IMU_BACKEND_CFLAG) \
	-DGPS_BUILD_ID=\"$(GPS_BUILD_ID)\" \
	-DIMU_ODR_HZ=$(IMU_ODR_HZ) \
	-DIMU_ACCEL_FS_G=$(IMU_ACCEL_FS_G) \
	-DIMU_GYRO_FS_DPS=$(IMU_GYRO_FS_DPS) \
	-DGPS_ESKF_ENABLE=$(GPS_ESKF_ENABLE) \
	-DIMU_CORRECTED_PUBLISH_EVERY_N_SAMPLES=$(IMU_CORRECTED_PUBLISH_EVERY_N_SAMPLES) \
	-DGPS_NAV_SOLVE_TIMER_TICKS=$(GPS_NAV_SOLVE_TIMER_TICKS) \
	-DGPS_WARM_SEED_ENABLE=$(GPS_WARM_SEED_ENABLE) \
	-DGPS_EPHEMERIS_FLASH_ENABLE=$(GPS_EPHEMERIS_FLASH_ENABLE) \
	-DGPS_EPHEMERIS_STORE_MAX_SLOTS=$(GPS_EPHEMERIS_STORE_MAX_SLOTS)u \
	-DGPS_EPHEMERIS_FLASH_FORCE_FORMAT=$(GPS_EPHEMERIS_FLASH_FORCE_FORMAT) \
	-DGPS_EPHEMERIS_FLASH_SEED_INITIAL=$(GPS_EPHEMERIS_FLASH_SEED_INITIAL) \
	-DGPS_EPHEMERIS_FLASH_BASE=$(GPS_EPHEMERIS_FLASH_BASE)UL \
	-DGPS_NAV_CONTEXT_ENABLE=$(GPS_NAV_CONTEXT_ENABLE) \
	-DGPS_NAV_CONTEXT_FLASH_BASE=$(GPS_NAV_CONTEXT_FLASH_BASE)UL \
	-DGPS_PPS_STATUS_LOG_INTERVAL=$(GPS_PPS_STATUS_LOG_INTERVAL) \
	-DGPS_PPS_DOPPLER_PREDICTOR_ENABLE=$(GPS_PPS_DOPPLER_PREDICTOR_ENABLE) \
	-DGPS_PPS_DOPPLER_PREDICTOR_AB_UPDATES=$(GPS_PPS_DOPPLER_PREDICTOR_AB_UPDATES)
LDLIBS += -lm

ifeq ($(GPS_DEBUG),1)
CFLAGS += -DDEBUG -DGPS_DEBUG_LEVEL=$(GPS_DEBUG_LEVEL)
endif

ifeq ($(GPS_NAV_DIAGNOSTICS),1)
CFLAGS += -DGPS_NAV_JUMP_DIAGNOSTICS=1
endif
