######################################
# HP 3478A TFT Retrofit firmware
# STM32F103C8 (Blue Pill, Cortex-M3)
# Portable Makefile for arm-none-eabi-gcc
# (replaces the VisualGDB build on Windows)
######################################

# Final binary name
TARGET = 3478A_VS_Display

# Build directory
BUILD_DIR = build

# Optimisation / debug
DEBUG   = 1
OPT     = -Og

#######################################
# Toolchain
#######################################
# Set GCC_PATH if arm-none-eabi-gcc is not on your PATH, e.g.:
#   make GCC_PATH=/Applications/ArmGNUToolchain/bin
PREFIX = arm-none-eabi-
ifdef GCC_PATH
CC  = $(GCC_PATH)/$(PREFIX)gcc
AS  = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp
CP  = $(GCC_PATH)/$(PREFIX)objcopy
SZ  = $(GCC_PATH)/$(PREFIX)size
else
CC  = $(PREFIX)gcc
AS  = $(PREFIX)gcc -x assembler-with-cpp
CP  = $(PREFIX)objcopy
SZ  = $(PREFIX)size
endif
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S

#######################################
# Sources
#######################################
C_SOURCES =  \
Core/Src/main.c \
Core/Src/gpio.c \
Core/Src/dma.c \
Core/Src/spi.c \
Core/Src/timer.c \
Core/Src/lcd.c \
Core/Src/lt7680.c \
Core/Src/display.c \
Core/Src/stm32f1xx_it.c \
Core/Src/stm32f1xx_hal_msp.c \
Core/Src/system_stm32f1xx.c \
Core/Src/syscalls.c \
Core/Src/sysmem.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c

# Assembly (startup)
ASM_SOURCES = Core/Startup/startup_stm32f103c8tx.S

#######################################
# CPU / FPU / target
#######################################
CPU = -mcpu=cortex-m3
# Cortex-M3 has no FPU
MCU = $(CPU) -mthumb

# C defines
C_DEFS = \
-DUSE_HAL_DRIVER \
-DSTM32F103xB

# Include directories
C_INCLUDES =  \
-ICore/Inc \
-IDrivers/STM32F1xx_HAL_Driver/Inc \
-IDrivers/STM32F1xx_HAL_Driver/Inc/Legacy \
-IDrivers/CMSIS/Device/ST/STM32F1xx/Include \
-IDrivers/CMSIS/Include

#######################################
# Compiler / assembler flags
#######################################
ASFLAGS = $(MCU) $(OPT) -Wall -fdata-sections -ffunction-sections

# Compatibility: the original VisualGDB project was built with an older GCC that
# treated missing function prototypes as warnings. Several headers have their
# prototypes commented out, so GCC 14+ would otherwise error out. Keep these as
# warnings to build the source unmodified.
COMPAT = -Wno-error=implicit-function-declaration -Wno-error=implicit-int -Wno-error=int-conversion

CFLAGS  = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall $(COMPAT) -fdata-sections -ffunction-sections

ifeq ($(DEBUG), 1)
CFLAGS += -g -gdwarf-2
endif

# Generate dependency files
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"

#######################################
# Linker
#######################################
LDSCRIPT = STM32F103C8TX_FLASH.ld
LIBS = -lc -lm -lnosys
LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBS) \
          -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections \
          -Wl,--no-warn-rwx-segments

#######################################
# Build
#######################################
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin

OBJECTS  = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.S=.o)))
vpath %.S $(sort $(dir $(ASM_SOURCES)))

$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
	$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@

$(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR)
	$(AS) -c $(ASFLAGS) $< -o $@

$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
	$(CC) $(OBJECTS) $(LDFLAGS) -o $@
	$(SZ) $@

$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
	$(HEX) $< $@

$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
	$(BIN) $< $@

$(BUILD_DIR):
	mkdir $@

clean:
	-rm -fR $(BUILD_DIR)

# Flash with ST-LINK (requires stlink: brew install stlink)
flash: $(BUILD_DIR)/$(TARGET).bin
	st-flash --reset write $< 0x8000000

-include $(wildcard $(BUILD_DIR)/*.d)

.PHONY: all clean flash
